首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么类方法中的fat箭头没有绑定到父作用域呢?

为什么类方法中的fat箭头没有绑定到父作用域呢?
EN

Stack Overflow用户
提问于 2017-04-03 16:25:37
回答 1查看 158关注 0票数 0

我有一个ES2015代码片段,根据this.data.pageCategoryL1~3的状态,我尝试用不同的数据动态地填充对象originalData键。我将类方法作为回调传递给_categoryMapper,它并不是将回调绑定到类的this --它只是传递指向函数的指针,而不绑定它,即使它是一个方法。仅这一点似乎就奇怪了,因为它没有自动绑定到实例中。

但真正令人费解的是:在_categoryMapper的缩减功能中,胖箭头函数的thisundefined。我认为胖箭头应该绑定到它们的父this的作用域?

代码语言:javascript
复制
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: ''
      };*/

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-03 16:35:18

你在这里滥用bind

代码语言:javascript
复制
let category = callback(mapping[key]).bind(this);

bind创建一个函数的副本,该函数的this设置为传递它的任何内容,并且预加载了零个或多个参数。

代码语言:javascript
复制
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设置为其第一个参数的函数。

代码语言:javascript
复制
function log(argument1) {
  console.log(this);
  console.log(argument1);
}

log.call({ a: 1 }, 'a');
log.call({ b: 2 }, 'b');

this === undefined的原因是,callback不是用箭头函数定义的,也没有任何其他方法来定义this。这基本上就是你在做的事。

代码语言:javascript
复制
'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);

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43189698

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档