为什么类方法中的胖箭头没有绑定到父范围呢?

时间:2017-04-03 16:25:38

标签: javascript class lambda ecmascript-6

我有一个ES2015代码段,我尝试使用不同的数据动态填充对象this.data.pageCategoryL1~3密钥,具体取决于originalData的状态。我将类方法作为回调传递给_categoryMapper,它不会将回调绑定到类this - 它只传递一个指向该类的_categoryMapper指针。函数没有绑定它,即使它是一个方法。仅此一点似乎很奇怪它不会自动绑定到实例。

真正令人费解的部分是:在this的reduce函数内,胖箭头函数的undefinedthis。我认为胖箭应该绑定到他们的父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: '' };*/的范围?



List<string> words = new List<string>(new string[] { "this", "be able", "it" });
var paragraph = "This is my text and this is why I want to match it! As this is just a text, I would like to be able to solve it. This is the final phrase of this paragraph.";
//List<string> 
foreach (string word in words)
{
    var foundItems = Regex.Matches(paragraph, @"\b" + word + @"\b", RegexOptions.IgnoreCase);
    if (foundItems.Count != 0)
    {
        var count = 0;
        var toReplace = 3;
        foreach (Match foudItem in foundItems)
        {
            count++;
            if(count != toReplace)
                continue;

            var regex = $"(^.{{{foudItem.Index}}}){foudItem.Value}(.*)";
            paragraph = Regex.Replace(paragraph, regex, $"$1<strong>{foudItem.Value}</strong>$2");
        }
        Console.WriteLine(paragraph);
    }
    Console.WriteLine(foundItems[0] + " " + foundItems[1]);
}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

你在这里误导了bind

let category = callback(mapping[key]).bind(this);

bind创建一个函数的副本,其中this设置为您传递的任何内容以及预加载的零个或多个参数。

&#13;
&#13;
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();
&#13;
&#13;
&#13;

你可能想要使用的是call 调用一个函数,this设置为它的第一个参数。

&#13;
&#13;
function log(argument1) {
  console.log(this);
  console.log(argument1);
}

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

原因this === undefinedcallback未使用箭头函数定义,也没有任何其他方式来定义this应该是什么。这基本上就是你正在做的事情。

&#13;
&#13;
'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);
&#13;
&#13;
&#13;