CanNNN可以在命名函数表达式中用作标识符吗?

时间:2017-05-15 15:28:34

标签: javascript polyfills function-expression

上下文

我正在阅读这本书You Don't Know JS: Up & Going, Chapter 2: Into JavaScript。在 Polyfilling 部分中,作者提供了以下示例:

if (!Number.isNaN) {
    Number.isNaN = function isNaN(x) {
        return x !== x;
    };
}

因此,这里要做的是创建一个polyfill,以便ES6方法Number.isNaN可以在较旧的浏览器中运行(即,ES6之前的版本)。正如我所料,他使用了较旧的isNaN方法。前一种方法实际上是指通过设计弃用后者。

问题

为什么将isNaN用作指定function expression标识符?我原以为它会以某种方式用于 body 。为什么?因为在Web上的示例中通常可以看到所有标识符,所以在比较函数表达式与函数声明时,采用以下形式:

功能声明:

function foo() {
    // ..
}

功能表达:

var foo = function bar() {
    // ..
};

因此,在此示例中, bar 正在'bar()'字符串后的括号内定义。那么为什么当 isNaN 是JavaScript中已定义的函数时,使用上面的'isNaN'?我们是否真的为了polyfill而覆盖它?我在这里错过/误解了什么?

1 个答案:

答案 0 :(得分:1)

如果在表达式中有命名函数,则该值不会被提升,而是保存在表达式范围中。所以原始值不会改变。

<强>示例

&#13;
&#13;
function bar(){
  console.log("In Bar")
}

var foo = function bar(){
  console.log("In Foo")
}

bar();
foo();
&#13;
&#13;
&#13;

你为什么要使用它?

如果出现异常,这将有助于您进行调试。匿名函数不会在堆栈跟踪中显示任何名称,如果你在1函数中说4-5个匿名函数,那么哪个失败就很难了。拥有一个命名函数使它变得简单。

&#13;
&#13;
var bar = function Test() {
  (function() {
    (function() {
      (function() {
        throw new Error("I have no Name2")
      })()
    })()
  })()
}

var foo = function Test() {
  (function inFoo1() {
    (function inFoo2() {
      (function inFoo3() {
        throw new Error("I have no Name2")
      })()
    })()
  })();
}


function init() {
  try {
    foo();
  } catch (ex) {
    console.log(ex.stack)
  }
  try {
    bar();
  } catch (ex) {
    console.log(ex.stack)
  }
}

function start() {
  init();
}

start();
&#13;
&#13;
&#13;

您还可以参考Why using named function expressions?了解更多信息。

相关问题