Open hzzzzzzzq opened 2 years ago
在[《JavaScript 深入之执行上下文栈》]()中提到,当 JavaScript 代码执行代码时,就会创建一个执行上下文。
对于执行上下文,都有三个重要属性:
我们来介绍一下 this。
什么是 this 呢?我们可以把 this 的指向当作执行时所指向的执行上下文。在不同的上下文中,this 的确定经常会发生问题。
this 是执行上下文中的一个属性。
globalContext = { VO: {...}, this: globalContext.VO, }
VO 就是上一节讲到的变量对象了。
this 与上下文中可执行代码的类型有直接关系,this 值在进入上下文时确定,并且在上下文运行期间永久不变
全局代码中的 this 始终是全局对象本身。
this.a = 1; console.log(a); // 1 b = 2; console.log(this.b); // 2 var c = 3; console.log(this.c); // 3
那么全局对象本身是什么呢?在浏览器中就是我们经常使用的 window。
window
console.log(this); // window 对象 console.log(window); // window 对象 console.log(this === window); // true
函数中的 this 是很奇特的,也是很有趣的。它的指向并不是固定的,而且可以通过手动进行修改。
我们在上面介绍到,this 是进入上下文时确定,所以在一个函数代码中,这个值在每一次完全不同。
注意:任何时候不能改变 this 的值。
let objBind = { value: 2 }; let obj = { value: 1, test: function () { console.log(this === obj); console.log(this.value); // this = objBind; // 报错,任何时候不能改变 this 的值 // console.log(this.value); }, }; // 我们来执行一下 obj.test(); // true, 1 objBind.test = obj.test; objBind.test(); // false, 2
我们看到结果的结果是不同的。 发现,指向的结果是不是跟调用它的对象有关呢?事实就是这样,谁调用就指向谁。
我们使用 obj 来调用 test 方法时,指向了 obj,打印 true,而我们将方法赋给 objBind 之后,objBind 来调用时,指向了 objBind。
obj
test
true
objBind
我们来看一下执行 test 方法时,test 上下文:
// obj 调用执行 testContext = { AO: {...}, this: obj, }; // objBind 调用执行 testContext = { AO: {...}, this: objBind, }
通过上下文,我们可以清楚的了解到 this 在运行中的指向。
this
我们来看一下还有一种方式,指向了全局对象。
let test = obj.test; test(); // false, undefined
这时候执行 test 时的上下文:
testContext = { AO: {...}, this: window }
function Constructor() { console.log(this); // "a"对象下创建一个新属性 this.value = 1; } let x = new Constructor(); console.log(x.value); // 1 // { // "value": 1 // }
在这里就要使用到 Function.prototype.apply 或 Function.prototype.call 了。
Function.prototype.apply
Function.prototype.call
在这里也介绍了 apply 和 call 以及 bind,可以看我的这两篇文章 - [《JavaScript 深入之 call 和 apply 函数》]() 与 [《JavaScript 深入之 bind 函数》]()
apply
call
bind
let obj = { value: 1, }; function fn(a) { console.log(this.value); console.log(a); } fn(2); // undefined, 2 fn.call(obj, 20); // 1, 20 fn.apply(obj, [20]); // 1, 20
箭头函数的 this 指向,不能按照上面的任何一种来。
箭头函数的 this 指向,是在定义时决定的,而不是在调用时决定。
var value = 1; let obj = { value: 2, test: () => { console.log(this); // window 对象 console.log(this.value); // 1 }, }; // 按照上面的想法,打印出来的应该是 2,而实际打印的是 1 obj.test();
JavaScript 深入之 this
在[《JavaScript 深入之执行上下文栈》]()中提到,当 JavaScript 代码执行代码时,就会创建一个执行上下文。
对于执行上下文,都有三个重要属性:
我们来介绍一下 this。
this
什么是 this 呢?我们可以把 this 的指向当作执行时所指向的执行上下文。在不同的上下文中,this 的确定经常会发生问题。
this 是执行上下文中的一个属性。
VO 就是上一节讲到的变量对象了。
this 与上下文中可执行代码的类型有直接关系,this 值在进入上下文时确定,并且在上下文运行期间永久不变
全局代码中的 this
全局代码中的 this 始终是全局对象本身。
那么全局对象本身是什么呢?在浏览器中就是我们经常使用的
window
。函数中的 this
函数中的 this 是很奇特的,也是很有趣的。它的指向并不是固定的,而且可以通过手动进行修改。
我们在上面介绍到,this 是进入上下文时确定,所以在一个函数代码中,这个值在每一次完全不同。
注意:任何时候不能改变 this 的值。
我们看到结果的结果是不同的。 发现,指向的结果是不是跟调用它的对象有关呢?事实就是这样,谁调用就指向谁。
我们使用
obj
来调用test
方法时,指向了obj
,打印true
,而我们将方法赋给objBind
之后,objBind
来调用时,指向了objBind
。我们来看一下执行
test
方法时,test
上下文:通过上下文,我们可以清楚的了解到
this
在运行中的指向。我们来看一下还有一种方式,指向了全局对象。
这时候执行 test 时的上下文:
作为构造函数下的 this
函数调用时,手动设置 this
在这里就要使用到
Function.prototype.apply
或Function.prototype.call
了。在这里也介绍了
apply
和call
以及bind
,可以看我的这两篇文章 - [《JavaScript 深入之 call 和 apply 函数》]() 与 [《JavaScript 深入之 bind 函数》]()多言一句 - 箭头函数指向
箭头函数的
this
指向,不能按照上面的任何一种来。箭头函数的
this
指向,是在定义时决定的,而不是在调用时决定。