Can isNaN be used as identifier in a named function expression?

78 Views Asked by At

The context:

I am reading the book You Don't Know JS: Up & Going, Chapter 2: Into JavaScript. In the Polyfilling section, the author gives the following example:

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

So, what is being done here is creating a polyfill so that the ES6 method Number.isNaN can run in older browsers (ie, pre-ES6 versions). As I expected, he makes use of the older isNaN method. The former method is actually meant to deprecate the latter by design.

The question:

Why is isNaN being used as the identifier of the named function expression? I would have expected it to be used in the body somehow. Why? Because all of the identifiers usually seen in examples around the web, when comparing function expressions vs function declarations take the following form:

Function declaration:

function foo() {
    // ..
}

Function expression:

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

So in this example bar is being defined within the brackets after the 'bar()' string. So why use 'isNaN' above when isNaN is an already defined function within JavaScript? Are we actually overwriting it for the purpose of the polyfill? What am I missing/misunderstanding here?

1

There are 1 best solutions below

0
On

When you have a named function in an expression, that value is not hoisted but is saved in expression scope. So original value is not changed.

Sample

function bar(){
  console.log("In Bar")
}

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

bar();
foo();

Why should you use it?

In case of exception, that will help you in debug. An anonymous function will not show any name in stack trace and if you have say 4-5 anonymous functions in 1 function, it becomes difficult as to which one failed. Having a named functions makes it little simple.

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();

You can also refer to Why using named function expressions? for more information.