JavaScript 里的奇葩知识

1Function.prototype 竟然是个函数类型 。而自定义函数的原型却是对象类型 。
typeof Function.prototype === 'function';  // truefunction People() {}typeof People.prototype === 'object';      // true所以我们设置空函数可以这么做:
// Good const noop = Function.prototype;// Badconst noop = () => {};2一个变量真的会不等于自身吗?
const x = NaN;x !== x  // true这是目前为止 js 语言中唯一的一个不等于自己的数据 。为什么?因为 NaN 代表的是一个范围,而不是一个具体的数值 。在早期的 isNaN() 函数中,即使传入字符串,也会返回 true ,这个问题已经在 es6 中修复 。
isNaN('abc');       // trueNumber.isNaN('abc') // false所以如果您想兼容旧浏览器,用 x !== x 来判断是不是NaN,是一个不错的方案 。
3构造函数如果 return了新的数据
// 不返回function People() {}const people = new People();   // People {}// 返回数字function People() {  return 1;}const people = new People();   // People {}// 返回新对象function Animal() {  return {    hello: 'world',  };}const animal = new Animal();  // { hello: 'world' }在实例化构造函数时,返回非对象类型将不生效
4.call.call 到底在为谁疯狂打call?
function fn1() {  console.log(1);}function fn2() {  console.log(2);}fn1.call.call(fn2); // 2所以 fn1.call.call(fn2) 等效于 fn2.call(undefined) 。而且无论您加多少个 .call,效果也是一样的 。
5实例后的对象也能再次实例吗?
function People() {}const lili = new People();            // People {}const lucy = new tom.constructor();   // People {}因为 lili 的原型链指向了 People 的原型,所以通过向上寻找特性,最终在 Peopel.prototype 上找到了构造器即 People 自身
6setTimeout 嵌套会发生什么奇怪的事情?
console.log(0, Date.now());setTimeout(() => {  console.log(1, Date.now());  setTimeout(() => {    console.log(2, Date.now());    setTimeout(() => {      console.log(3, Date.now());      setTimeout(() => {        console.log(4, Date.now());        setTimeout(() => {          console.log(5, Date.now());          setTimeout(() => {            console.log(6, Date.now());          });        });      });    });  });});在0-4层,setTimeout 的间隔是 1ms ,而到第 5 层时,间隔至少是 4ms  。
7es6函数带默认参数时将生成声明作用域
var x = 10;function fn(x = 2, y = function () { return x + 1 }) {  var x = 5;  return y();}fn();   // 38函数表达式(非函数声明)中的函数名不可覆盖
const c = function CC() {  CC = 123;  return CC;};c(); // Function当然,如果设置 var CC = 123 ,加声明关键词是可以覆盖的 。
9严格模式下,函数的 this 是 undefined 而不是 Window
// 非严格function fn1() {  return this;}fn1(); // Window// 严格function fn2() {  'use strict';  return this;}fn2(); // undefined对于模块化的经过webpack打包的代码,基本都是严格模式的代码 。


推荐阅读