[英]Why is the fat arrow in a class method not binding to the parent scope's this?
I've got an ES2015 code snippet where I'm trying to dynamically populate the objects this.data.pageCategoryL1~3
keys with different data depending on the state of the originalData
. 我有一个ES2015代码片段,其中试图根据
originalData
数据的状态动态填充具有不同数据的对象this.data.pageCategoryL1~3
键。 I'm passing class methods as a callback to _categoryMapper
, which isn't binding the callback to class's this
- it's only passing a pointer to the function without binding it even though it's a method. 我传递类方法作为回调
_categoryMapper
,这是不具约束力的回调类的this
-它只是一个指针传递给函数,而不结合它,即使它是一个方法。 That alone seems weird odd that it isn't automatically bound to the instance. 仅凭它没有自动绑定到实例就显得很奇怪。
The truly puzzling part though: inside of _categoryMapper
's reduce function, the fat arrow function's this
is undefined
. 不过,真正令人困惑的部分是:
_categoryMapper
的reduce函数中, _categoryMapper
箭头函数的this
是undefined
。 I thought fat arrows were supposed to bind to their parent this
's scope? 我还以为胖箭头被认为结合其父母
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: '' };*/
You're misusing bind
here. 您在此处滥用
bind
。
let category = callback(mapping[key]).bind(this);
bind
creates a copy of a function with this
set to whatever you passed it and zero or more arguments preloaded. 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();
What you probably want to use is call
which calls a function with this
set to it's first argument. 你可能想使用什么是
call
它调用一个函数this
给它的第一个参数集。
function log(argument1) { console.log(this); console.log(argument1); } log.call({ a: 1 }, 'a'); log.call({ b: 2 }, 'b');
The reason this === undefined
is that callback
is not defined with an arrow function nor does it have any other way of defining what this
should be. 之所以
this === undefined
是callback
不带箭头的功能定义也不会有什么定义任何其他方式this
应该是。 This is essentially what you're doing. 这实质上就是您正在执行的操作。
'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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.