我有一个ES2015代码片段,根据this.data.pageCategoryL1~3的状态,我尝试用不同的数据动态地填充对象originalData键。我将类方法作为回调传递给_categoryMapper,它并不是将回调绑定到类的this --它只是传递指向函数的指针,而不绑定它,即使它是一个方法。仅这一点似乎就奇怪了,因为它没有自动绑定到实例中。
但真正令人费解的是:在_categoryMapper的缩减功能中,胖箭头函数的this是undefined。我认为胖箭头应该绑定到它们的父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: ''
};*/
发布于 2017-04-03 16:35:18
你在这里滥用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);
https://stackoverflow.com/questions/43189698
复制相似问题