为必需的箭头函数

时间:2016-10-19 15:17:48

标签: javascript node.js arrow-functions

我试图在各种情况下设置this

在node.js v6.8.1中执行的以下代码将打印每行末尾注释的内容:

function requireFromString(src) {
  var Module = module.constructor;
  var m = new Module();
  m._compile(src, __filename);
  return m.exports;
}

(function(){
  var f1 = (() => {console.log(this.a === 1)});
  var f2 = function(){ console.log(this.a === 1) };
  var f3 = requireFromString('module.exports = (() => {console.log(this.a === 1)});');
  var f4 = requireFromString('module.exports = function(){ console.log(this.a === 1) };');

  console.log('Body:');
  console.log(this.a === 1);                          // true
  (()=>console.log(this.a === 1))();                  // true
  (()=>console.log(this.a === 1)).call(this);         // true
  (function(){console.log(this.a === 1)})();          // false
  (function(){console.log(this.a === 1)}).call(this); // true


  console.log('\nFunctions:');
  f1();                                               // true
  f1.call(this);                                      // true
  f2();                                               // false
  f2.call(this);                                      // true
  f3();                                               // false [1]
  f3.call(this);                                      // false [2]
  f4();                                               // false 
  f4.call(this);                                      // true

}).apply({a:1});

使用thisarrow functions的文档,除了标有[1][2]的案例外,我可以解释所有案例。

有人可以对观察到的行为有所了解吗?并且可能会提示我如何调用f3以便函数打印为true。

备注

1 个答案:

答案 0 :(得分:1)

原因是"胖箭头功能"总是从周围的代码中学习this词法。他们 无法 this更改为callbind等。运行此代码作为示例:

var object = {
  stuff: 'face',

  append: function() {
    return (suffix) => {
      console.log(this.stuff + ' '+suffix);
    }
  }
}
var object2 = {
  stuff: 'foot'
};

object.append()(' and such');
object.append().call(object2, ' and such');

您只会看到face and such

因此,就f3的情况而言,这并不起作用,因为它是一个需要自包含的模块。因此,它的基本级箭头函数将仅使用模块中的this,它们不能与bindcall等绑定,如上所述。 为了对它们使用call,它们必须是常规功能,而不是箭头功能。

" lexical this"意思? 它基本上与闭包相同。以此代码为例:

fileA.js:

(function () {
    var info = 'im here!';

    var infoPrintingFunctionA = function() {
        console.log(info);
    };

    var infoPrintingFunctionB = require('./fileB');

    infoPrintingFunctionA();
    infoPrintingFunctionB();
})();

fileB.js:

module.exports = function() {
    console.log(info);
};

结果会是什么?错误info is not defined。为什么?因为函数的可访问变量(范围)仅包括可用的变量,其中定义了函数。因此,infoPrintingFunctionA可以访问info,因为info存在于定义infoPrintingFunctionA的范围内。

但是,即使infoPrintingFunctionB在同一作用域中被调用,它也不是在同一作用域中定义。因此,它无法从调用范围访问变量。

但这一切都与变量和闭包有关;那么this和箭头函数呢?

箭头函数的this与函数中其他变量的闭包相同。基本上,箭头函数只是说在创建的闭包中包含this。并且以同样的方式你不能期望fileB的函数可以访问fileA的变量,你不能期望调用模块(fileA)的this能够成为从被调用模块(fileB)的主体引用。

TLDR:我们如何定义"周围的代码",在表达式" lexical this中取自周围的代码?"周围的代码是定义函数的范围,不一定是调用它的位置。