我有一个 ES2015 代码片段,我试图根据 originalData< 的状态,用不同的数据动态填充对象
。我将类方法作为回调传递给 this.data.pageCategoryL1~3
键_categoryMapper
,它不会将回调绑定(bind)到类的 this
- 它只是将指针传递给函数而不绑定(bind)它,即使这是一种方法。仅此一点就显得很奇怪,因为它不会自动绑定(bind)到实例。
真正令人费解的部分是:在_categoryMapper
的reduce 函数内部,粗箭头函数的this
是未定义
。我认为粗箭头应该绑定(bind)到其父 this
的范围?
class AnalyticsData {
constructor(originalData) {
this.data = {};
this.originalData = originalData;
}
mapCategories() {
debugger;
let mappedCategories = {
pageCategoryL1: '',
pageCategoryL2: '',
pageCategoryL3: ''
};
if (this.originalData.search && this.originalData.search.refinements) {
mappedCategories = this._categoryMapper({
pageCategoryL1: 'categoryl1',
pageCategoryL2: 'categoryl2',
pageCategoryL3: 'categoryl3'
},
this._getSomeCategory); // if i bind only here it will work, because it doesn't use fat arrow's this
} else if (this.originalData.items) {
mappedCategories = this._categoryMapper({
pageCategoryL1: 'a',
pageCategoryL2: 'b',
pageCategoryL3: 'c'
},
this._getSomeOtherCategory);
}
return mappedCategories;
}
_categoryMapper(mapping, callback) {
return Object.keys(mapping).reduce((acc, key) => {
// fat arrow in reduce should be implicitly bound to this
console.log(this);
let category = callback(mapping[key]).bind(this);
acc[key] = category ? category : '';
return acc;
}, {});
}
_getSomeCategory(categoryKey) {
// No access to this as currently written
console.log(this)
let refinements = this.originalData.search.refinements;
let matchedObj = refinements.find(({
refinement
}) => categoryKey === refinement.name);
return matchedObj && matchedObj.refinement.value;
}
_getSomeOtherCategory(categoryKey) {
let id = Object.keys(this.originalData.items)[0];
return this.originalData.items[id][categoryKey];
}
}
window.x = new AnalyticsData({
search: {
refinements: [{
refinement: {
name: 'categoryl1',
value: 'yup'
}
}]
}
}).mapCategories()
console.log(x)
/* this.data should be: {
pageCategoryL1: 'yup',
pageCategoryL2: '',
pageCategoryL3: ''
};*/
最佳答案
您滥用了 bind
在这里。
let category = callback(mapping[key]).bind(this);
bind
使用 this
创建函数的副本设置为您传递的任何内容并预加载零个或多个参数。
function log(argument1) {
console.log(this);
console.log(argument1);
}
let f = log.bind({ a: 1 }, 'a');
let g = log.bind({ b: 2 }, 'b');
f();
g();
您可能想要使用的是 call
其中调用一个带有 this
的函数设置为它的第一个参数。
function log(argument1) {
console.log(this);
console.log(argument1);
}
log.call({ a: 1 }, 'a');
log.call({ b: 2 }, 'b');
原因this === undefined
是callback
没有用箭头函数定义,也没有任何其他方式定义 this
应该。这本质上就是您正在做的事情。
'use strict';
let obj = {
a: 1,
log() {
console.log(this);
}
};
function callCallback(callback) {
callback();
}
// This is what you want to happen
callCallback(obj.log.bind(obj));
// This is what you're doing
callCallback(obj.log);
关于javascript - 为什么类方法中的粗箭头没有绑定(bind)到父作用域的 this ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43189698/