以下代码片段中“this”值变化的解释?
An explanation for the change in the value of `this` in the following snippet of code?
function wrap(func) {
console.log('0', this)
return function x() {
console.log('1', this)
func()
return function z() {
console.log('3', this)
}
}
}
var obj = {
x: 5,
test: wrap(function y() {
console.log('2', this)
})
}
obj.test()()
上面的代码记录
// 0 Window
// 1 Object
// 2 Window
// 3 Window
我无法理解什么决定了 this
的值应该是什么。
// 0 Window
是有道理的,因为这是第一次调用 wrap 的时候,此时它的值 this
不应该设置为 obj
// 1 Object
有意义 obj.test
现在等于 function x()
,它正确地将 this
记录为 obj
// 2 Window
我不确定为什么会这样。为什么 this
的值不会传播到 func()
?我认为 this
应该指的是函数的所有者。这是否意味着即使 function y()
是在 obj 内部创建的,它也会以某种方式被提升到 window?
// 3 Window
同样 function z()
为什么 this
的值没有从 function x()
传下来。 this
的值不应该在那里传播吗?
'this' 绑定非常混乱。但是,如果您记住以下这些规则,就会更容易理解。根据 Javascript 文档,'this' 绑定的顺序有四个规则:
- 新运营商
- 通过调用或应用方法进行显式或硬绑定
- 与包含对象的隐式绑定,如对象的方法
- 默认(全球)
在您的脚本中,只有规则 #3 和 #4 适用,因为没有新的运算符和 call 或 apply 方法。
所以解释是:
// 0 Window - 规则 #4 默认(全局)
// 1 对象 - 规则 #3 与包含对象的隐式绑定,就像一个对象的方法,obj.test 在你的例子中
// 2 Window - 规则 #4 默认(全局)
// 3 Window - 规则 #4 默认(全局)
以下,this文章的大部分准确指导,按顺序,函数调用desugar到
wrap.call(window, function() {})
obj.test.call(obj)
y.call(window)
z.call(window)
要记住的是 this
不会 通过函数声明传播。 this
的值完全取决于函数的调用方式。
我之所以感到困惑,是因为我对箭头函数有点太习惯了,箭头函数为您保留了 this
的值。
function wrap(func) {
return () => {
console.log(this)
return () => {
console.log(this)
func()
return () => console.log(this)
}
}
}
这个脱糖到
function wrap(func) {
var _this = this;
return function () {
console.log(_this);
return function () {
console.log(_this);
func()
return function () {
return console.log(_this);
};
};
};
}
并显示您必须显式传递 this
的值。即使使用箭头函数,重要的是要注意对 func
的调用不会保留 this
的值。我需要做 func.call(this)
才能做到这一点。
function wrap(func) {
console.log('0', this)
return function x() {
console.log('1', this)
func()
return function z() {
console.log('3', this)
}
}
}
var obj = {
x: 5,
test: wrap(function y() {
console.log('2', this)
})
}
obj.test()()
上面的代码记录
// 0 Window
// 1 Object
// 2 Window
// 3 Window
我无法理解什么决定了 this
的值应该是什么。
// 0 Window
是有道理的,因为这是第一次调用 wrap 的时候,此时它的值 this
不应该设置为 obj
// 1 Object
有意义 obj.test
现在等于 function x()
,它正确地将 this
记录为 obj
// 2 Window
我不确定为什么会这样。为什么 this
的值不会传播到 func()
?我认为 this
应该指的是函数的所有者。这是否意味着即使 function y()
是在 obj 内部创建的,它也会以某种方式被提升到 window?
// 3 Window
同样 function z()
为什么 this
的值没有从 function x()
传下来。 this
的值不应该在那里传播吗?
'this' 绑定非常混乱。但是,如果您记住以下这些规则,就会更容易理解。根据 Javascript 文档,'this' 绑定的顺序有四个规则:
- 新运营商
- 通过调用或应用方法进行显式或硬绑定
- 与包含对象的隐式绑定,如对象的方法
- 默认(全球)
在您的脚本中,只有规则 #3 和 #4 适用,因为没有新的运算符和 call 或 apply 方法。
所以解释是:
// 0 Window - 规则 #4 默认(全局)
// 1 对象 - 规则 #3 与包含对象的隐式绑定,就像一个对象的方法,obj.test 在你的例子中
// 2 Window - 规则 #4 默认(全局)
// 3 Window - 规则 #4 默认(全局)
以下,this文章的大部分准确指导,按顺序,函数调用desugar到
wrap.call(window, function() {})
obj.test.call(obj)
y.call(window)
z.call(window)
要记住的是 this
不会 通过函数声明传播。 this
的值完全取决于函数的调用方式。
我之所以感到困惑,是因为我对箭头函数有点太习惯了,箭头函数为您保留了 this
的值。
function wrap(func) {
return () => {
console.log(this)
return () => {
console.log(this)
func()
return () => console.log(this)
}
}
}
这个脱糖到
function wrap(func) {
var _this = this;
return function () {
console.log(_this);
return function () {
console.log(_this);
func()
return function () {
return console.log(_this);
};
};
};
}
并显示您必须显式传递 this
的值。即使使用箭头函数,重要的是要注意对 func
的调用不会保留 this
的值。我需要做 func.call(this)
才能做到这一点。