目录
1、this 的原理
- 了解内存的数据结构:
1、数据结构是对象,对象是一个值
var obj = { foo: 5 };
obj 是一个变量的地址,如果要读取 obj,foo ,就要从obj 读取地址,然后再从该地址拿到原始的对象,最后获取该对象的属性
2、数据结构是对象,对象是一个函数
var obj = { foo: function () {} };
引擎会将函数单独保存在内存中,然后再将函数的地址赋值给foo
属性的value
属性。
由于函数是一个单独的值,所以它可以在不同的环境(上下文)执行。
var f = function () {};
var obj = { f: f };
// 单独执行
f()
// obj 环境执行
obj.f()
JavaScript 允许在函数体内部,引用当前环境的其他变量。
2、this 的总结
(1)this指向的几种情况
function foo () {
console.log(this)
}
foo() // => 全局对象 / globalThis
foo.call(1) // => 1
结论:this的指向不确定
const obj1 = {
foo: function () {
console.log(this)
}
}
obj1.foo() // => obj1
const fn = obj1.foo
fn() // => window
结论:this的指向不确定
const obj2 = {
foo: function () {
function bar () {
console.log(this)
}
bar()
}
}
obj2.foo()
结论:this指向全局对象
(2)总结
- 沿着作用于向上找最近的一个 function(不是箭头函数), 看这个 function 最终是怎样执行的;
- this 的指向取决于所属 function 的调用方式,而不是定义;
- function 调用一般分为以下几种情况:
- 作为函数调用,即: foo()
- 指向全局对象(globalThis),注意严格模式,严格模式下是 undefined
- 作为方法调用,即 :foo.bar() / foo.bar.baz() / foo['bar'] / foo[0]()
- 指向最终调用这个方法的对象
- 作为构造函数调用,即:new Foo()
- 指向一个新对象 Foo{}
- 特殊调用,即:foo.call() / foo.apply() / foo.bind()
- 指向参数指定成员
- 作为函数调用,即: foo()
- 找不到所属的 function, 就是全局对象