简体   繁体   English

为什么类方法中的粗箭头不能绑定到父作用域的this?

[英]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箭头函数的thisundefined 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 === undefinedcallback不带箭头的功能定义也不会有什么定义任何其他方式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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM