为什么 this 绑定在其中一个箭头调用中,而不是另一个?
Why is this bound in one of these arrow invocations, but not the other?
我无法准确理解为什么 this
在某些情况下有价值,而在其他情况下却没有。我维护着一个图书馆,它精简到最低限度以解释我的困惑,如下所示:
const arrayify = f => {
console.log('init', f.name, !!this);
return function (thingOrThings, ...args) {
console.log('arrayify for ', f.name, !!this);
return [thingOrThings].map(t => f.call(this, t, ...args));
};
};
class Utils {}
Object.assign(Utils.prototype, {
setProperty: arrayify(function setPropertyFunc(layer, prop, value) {
console.log('setPropertyFunc called', !!this); // outputs true
}),
hoverPopup(layers, cb, popupOptions = {}) {
console.log('hoverPopup init', !!this);
arrayify(function hoverPopupFunc(layer, cb) {
console.log('hoverPopupFunc called', !!this); // outputs false
})(layers, cb);
},
});
(它看起来过于复杂,因为我删除了所有实际有用的东西。但基本上 arrayify
允许函数接受单个事物或事物数组,并隐式运行在每个项目上后一种情况下的数组。)
我这样称呼它:
const U = new Utils();
U.setProperty('mylayer', 'lineColor', 'red');
U.hoverPopup('mylayer', () => 1);
输出:
init setPropertyFunc false
arrayify for setPropertyFunc true
setPropertyFunc called true
hoverPopup init true
init hoverPopupFunc false
arrayify for hoverPopupFunc false
hoverPopupFunc called false
所以在第一种情况下,调用U.setProperty
调用arrayify
,this
(在arrayify
内)有一个值。返回给 setProperty
的函数内的 this
也有一个值。
第二个,U.hoverPopup
调用 arrayify
没有 this
值,返回的函数中也没有 this
值。
我无法理解第二种情况有何不同。特别令人困惑的是 this
是 not 在 setPropertyFunc
的 init 中定义,但 是 在嵌入式函数中定义,而hoverPopupFunc
正好相反
我真的很想在这两种情况下都定义 this
- 在第二种情况下如何实现? (在 hoverPopup
的情况下,必须进行一些初始化,所以它不像“对数组中的每个项目都这样做”那么简单)
查看调用返回函数的位置和方式以了解调用上下文 - this
。
在第一种情况下,原型上的 setProperty
方法是返回函数,它被调用 作为实例 属性 的 :
U.setProperty('mylayer', 'lineColor', 'red'); // outputs true
// ^ calling context: this
但是在第二种情况下,没有调用上下文:
arrayify(function (layer, cb) {
console.log('hoverpopup', !!this); // outputs false
})(layers, cb);
这只是一个立即调用的普通函数。为了简化一点:
arrayify(someFn)(layers, cb)
被调用的函数 - 整个 arrayify(someFn)
部分 - 不是对象的一部分,而是一个独立的变量,因此没有调用上下文。
I'd really like this to be defined in both cases - how can I achieve that in the second case?
使用 .call
调用具有特定 this
的函数。
hoverPopup(layers, cb, popupOptions = {}) {
// do some other initialisation here
const fn = function (layer, cb) {
console.log('hoverpopup', !!this); // outputs false
};
arrayify(fn).call(this, layers, cb);
},
这是可行的,因为当在 hoverPopup
的主体内时,this
是实例:
U.hoverPopup('mylayer', () => 1);
// ^ calling context: this
这样做 arrayify(fn).call(this, layers, cb);
将按照您的意愿传递它。
添加我自己的解释以帮助更好地理解这一点。
对象实例化后,U
基本上是这样的:
{
setProperty: function (thingOrThings, ...args) {
console.log('arrayify for ', f.name, !!this);
return [thingOrThings].map(t => /* ... */);
},
hoverPopup: function(layers, cb, popupOptions = {}) {
console.log('hoverPopup init', !!this);
arrayify(function hoverPopupFunc(layer, cb) {
console.log('hoverPopupFunc called', !!this);
})(layers, cb);
}
}
所以,在这一点上,setProperty
只是对象上的一个函数,因此当它被调用时,它当然具有 this
的值。此函数是由另一个函数(无论是否为箭头)创建的事实无关紧要。
hoverPopup
也是对象上的一个函数,也有一个this
值。但是当它调用 arrayify
时,那个调用 没有 有一个 this
值,因为它不满足任何 the four rules
尝试将 this
的值绑定到 arrayify
是行不通的,因为它是一个箭头函数。但是您可以将值绑定到 arrayify 返回的函数:
hoverPopup(layers, cb, popupOptions = {}) {
console.log(`hoverPopup init ${this === U}`);
arrayify(function hoverPopupFunc(layer, cb) {
console.log(`hoverPopupFunc called ${this === U}`); // outputs true
}).call(this, layers, cb);
},
我无法准确理解为什么 this
在某些情况下有价值,而在其他情况下却没有。我维护着一个图书馆,它精简到最低限度以解释我的困惑,如下所示:
const arrayify = f => {
console.log('init', f.name, !!this);
return function (thingOrThings, ...args) {
console.log('arrayify for ', f.name, !!this);
return [thingOrThings].map(t => f.call(this, t, ...args));
};
};
class Utils {}
Object.assign(Utils.prototype, {
setProperty: arrayify(function setPropertyFunc(layer, prop, value) {
console.log('setPropertyFunc called', !!this); // outputs true
}),
hoverPopup(layers, cb, popupOptions = {}) {
console.log('hoverPopup init', !!this);
arrayify(function hoverPopupFunc(layer, cb) {
console.log('hoverPopupFunc called', !!this); // outputs false
})(layers, cb);
},
});
(它看起来过于复杂,因为我删除了所有实际有用的东西。但基本上 arrayify
允许函数接受单个事物或事物数组,并隐式运行在每个项目上后一种情况下的数组。)
我这样称呼它:
const U = new Utils();
U.setProperty('mylayer', 'lineColor', 'red');
U.hoverPopup('mylayer', () => 1);
输出:
init setPropertyFunc false
arrayify for setPropertyFunc true
setPropertyFunc called true
hoverPopup init true
init hoverPopupFunc false
arrayify for hoverPopupFunc false
hoverPopupFunc called false
所以在第一种情况下,调用U.setProperty
调用arrayify
,this
(在arrayify
内)有一个值。返回给 setProperty
的函数内的 this
也有一个值。
第二个,U.hoverPopup
调用 arrayify
没有 this
值,返回的函数中也没有 this
值。
我无法理解第二种情况有何不同。特别令人困惑的是 this
是 not 在 setPropertyFunc
的 init 中定义,但 是 在嵌入式函数中定义,而hoverPopupFunc
我真的很想在这两种情况下都定义 this
- 在第二种情况下如何实现? (在 hoverPopup
的情况下,必须进行一些初始化,所以它不像“对数组中的每个项目都这样做”那么简单)
查看调用返回函数的位置和方式以了解调用上下文 - this
。
在第一种情况下,原型上的 setProperty
方法是返回函数,它被调用 作为实例 属性 的 :
U.setProperty('mylayer', 'lineColor', 'red'); // outputs true
// ^ calling context: this
但是在第二种情况下,没有调用上下文:
arrayify(function (layer, cb) {
console.log('hoverpopup', !!this); // outputs false
})(layers, cb);
这只是一个立即调用的普通函数。为了简化一点:
arrayify(someFn)(layers, cb)
被调用的函数 - 整个 arrayify(someFn)
部分 - 不是对象的一部分,而是一个独立的变量,因此没有调用上下文。
I'd really like this to be defined in both cases - how can I achieve that in the second case?
使用 .call
调用具有特定 this
的函数。
hoverPopup(layers, cb, popupOptions = {}) {
// do some other initialisation here
const fn = function (layer, cb) {
console.log('hoverpopup', !!this); // outputs false
};
arrayify(fn).call(this, layers, cb);
},
这是可行的,因为当在 hoverPopup
的主体内时,this
是实例:
U.hoverPopup('mylayer', () => 1);
// ^ calling context: this
这样做 arrayify(fn).call(this, layers, cb);
将按照您的意愿传递它。
添加我自己的解释以帮助更好地理解这一点。
对象实例化后,U
基本上是这样的:
{
setProperty: function (thingOrThings, ...args) {
console.log('arrayify for ', f.name, !!this);
return [thingOrThings].map(t => /* ... */);
},
hoverPopup: function(layers, cb, popupOptions = {}) {
console.log('hoverPopup init', !!this);
arrayify(function hoverPopupFunc(layer, cb) {
console.log('hoverPopupFunc called', !!this);
})(layers, cb);
}
}
所以,在这一点上,setProperty
只是对象上的一个函数,因此当它被调用时,它当然具有 this
的值。此函数是由另一个函数(无论是否为箭头)创建的事实无关紧要。
hoverPopup
也是对象上的一个函数,也有一个this
值。但是当它调用 arrayify
时,那个调用 没有 有一个 this
值,因为它不满足任何 the four rules
尝试将 this
的值绑定到 arrayify
是行不通的,因为它是一个箭头函数。但是您可以将值绑定到 arrayify 返回的函数:
hoverPopup(layers, cb, popupOptions = {}) {
console.log(`hoverPopup init ${this === U}`);
arrayify(function hoverPopupFunc(layer, cb) {
console.log(`hoverPopupFunc called ${this === U}`); // outputs true
}).call(this, layers, cb);
},