导航
function Test() {
//var this = {
// __proto__: Test.prototype
//}
this.name = '123';
}
var test = new Test();
AO = {
this: window -> {
__proto__: Test.prototype,
name: '123'
}
}
GO = {
Test: f() {},
test: {}
}
function Person() {
this.name = 'Lance';
this.age = 10;
}
function Programmer() {
Person.apply(this);
this.work = 'Programming';
}
var p = new Programmer();
console.log(p);

var x = {
name: 'bw2',
getName1: function() {
console.log(this)
},
getName2: function() {
setTimeout(() => {
console.log(this)
},0)
},
getName31: () => {
console.log(this)
},
getName32: function() {
return function() {
console.log(this)
}
}
}
x.getName1();
// {name: "bw2", getName1: ƒ}
// x为调用者
x.getName2()
// {name: "bw2", getName1: ƒ}
// 箭头函数没有this,this继承外层作用域,
// x为getName2调用者,this指向x
x.getName31()
// Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
// js中作用域只有全局作用域和函数作用域
// 箭头函数this指向外层作用域window,而不是调用者x
x.getName32()()
// Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
// this的值取决于调用上下文,
// 如果一个函数不是作为某个对象的方法被调用,
// 那么this就是global object.否则就是该对象
function test(a, b, c) {
console.log(arguments.callee.length); // === test.length = 3
console.log(arguments.callee); // function test
}
test(1, 2, 3);

var sum = (function (n) {
if (n <= 1) return 1;
return n + arguments.callee(n - 1);
})(100);
console.log(sum); // 5050
function test1() {
test2();
}
function test2() {
console.log(test2.caller);
}
test1();

var a = 5;
function test() {
a = 0;
console.log(a);
console.log(this.a);
var a;
console.log(a);
}
test();
new test();
GO: {
a: 5,
test: function test() {}
}
AO: {
this: window => {}
a: undefined => 0,
}
// 执行 test 时打印: 0, 5, 0
// 执行 new Test 时打印: 0, undefined, 0
// 最终打印顺序: 0, 5, 0, 0, undefined, 0
// 解析:
// 实例化 test 时,有内部 this ,但是并没有给 this 上添加 a 属性,所以 this.a 打印 undefined

this 的本质
this不是在函数定义时决定的,而是在函数被「调用」时动态绑定的。它永远指向 当前函数执行上下文中的「调用者对象」(或全局对象/undefined,取决于模式)。
function foo() {
console.log(this); // 非严格模式:window;严格模式:undefined
}
foo(); // 直接调用
this 指向 全局对象(非严格模式) 或 undefined(严格模式)。const obj = {
name: 'Alice',
greet() {
console.log(this.name); // 'Alice'
}
};
obj.greet(); // 调用时前面有 obj.
规则:函数通过 obj.fn() 形式调用 → this 指向 . 前面的对象(obj)。
❗ 陷阱:如果把方法赋值给变量再调用,会丢失绑定:
const fn = obj.greet;
fn(); // this → 全局/undefined(不再是 obj!)
function greet() { console.log(this.name); }
const person = { name: 'Bob' };
greet.call(person); // 'Bob'
greet.apply(person); // 'Bob'
const bound = greet.bind(person);
bound(); // 'Bob'
call/apply/bind 第一个参数就是 this 的值。bind 返回新函数,永久绑定 this(即使再用 call 也无法改变)。function Person(name) {
this.name = name; // this 指向新创建的实例
}
const p = new Person('Charlie');
console.log(p.name); // 'Charlie'
new 调用函数 → this 指向 新创建的空对象(即实例)。const obj = {
name: 'David',
greet: () => {
console.log(this.name); // undefined(this 来自外层作用域)
},
normal() {
const arrow = () => console.log(this.name);
arrow(); // 'David'(继承 normal 的 this)
}
};
obj.greet(); // this 是全局(因为箭头函数定义在全局)
obj.normal(); // 'David'
this,它词法继承外层非箭头函数的 this。this 在定义时就确定了,无法被 call/apply/bind 改变!thisbutton.addEventListener('click', function() {
console.log(this); // button 元素(隐式绑定:浏览器自动 call(this=element))
});
// 箭头函数则不同:
button.addEventListener('click', () => {
console.log(this); // 全局对象(因为箭头函数继承外层 this)
});
this = 触发事件的 DOM 元素(相当于 handler.call(element))。this = 定义时的外层作用域。遇到任何函数调用,按顺序问自己这 4 个问题:
new 调用?this = 新创建的实例对象。call / apply / bind 调用?this = 显式传入的第一个参数。obj.fn() 形式)this = . 前面的对象(obj)。this = 外层最近的非箭头函数的 this(词法作用域)。