javascript - 为什么类方法中的粗箭头没有绑定(bind)到父作用域的 this ?

标签 javascript class lambda ecmascript-6

我有一个 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 === undefinedcallback没有用箭头函数定义,也没有任何其他方式定义 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/

相关文章:

python 如何在类上使用 getattr

class - Vue中一个条件绑定(bind)多个类

c++ - 为函数内的数组元素赋值

c#-3.0 - 创建一个将 lambda 表达式传递给构造函数的对象

javascript - 访问 Knockout 中的子元素

javascript - 获取元素鼠标在 JavaScript 之上

javascript - 访问 eventListener 函数 Javascript 中的类方法

c# - 在 C# 的嵌套函数中分配的捕获变量在哪里

javascript - Casperjs 单击无法打开 'download csv' 操作系统窗口

JavaScript - 在函数内部保存变量而不调用函数