Skip to content

Latest commit

 

History

History
133 lines (98 loc) · 4.3 KB

File metadata and controls

133 lines (98 loc) · 4.3 KB

类型检测

JS中的数据类型分为两类:基本数据类型和用户自定的数据类型。对数据类型的判断遵循以下两个基本原则即可:

  • 如果判断的是基本数据类型或javascript内置对象,用toString

  • 如果判断的是自定义类型,用instanceof

为什么不用typeof呢?看看下面的例子:

typeof null; // object
typeof ''; // string
typeof new String('123') // object

typeof null已经是一个众所周知的bug,按下不表。对String类型的判断才是我们的心头大患: 我们希望无论是'123' 还是new String('123')都是同样的string类型,而toString方法正好可以满足这个要求。

由于很多对象都重载了toString方法,因此我们用Object.prototype.toString来判断对象的类型:

toString = Object.prototype.toString;
toString.call('') // [object String]
toString.call(new String('')) // [object String]

如果要更加深入的理解这种用法,推荐大家阅读lodashisXXX 部分的源码。

相比静态语言,动态语言的类型判断更加灵活。有的时候只要实例满足某些条件,我们也认为它是可接受的 数据类型,这就是所谓的鸭子类型

关于类型检测的更多细节,还可以读一下这篇文章

变量提升

在ES6中,新增了块级作用域,使用let和const声明的变量不存在变量提升的问题,但这并不意味这ES6中就不存在 变量提升了,如:

function test() {
  hehe(); // hehe

  function hehe() { console.log('hehe'); }
}

要消除变量提升带来的不确定性,建议坚持使用let/const的方式定义函数。

变量提升的问题更多的是来自于ES5。由于在ES5中只有函数作用域和全局作用域,因此存在大量变量提升的场景,同时 也导致了自执行函数的广泛使用:

(function() {
  // ...
}());

you dont know javascript的scope && closure部分 对变量提升也有很好的解释,对这部分还有疑问的同学一定要抽时间读一读。

闭包

大成总结的闭包的文章基本涵盖了闭包问题所需要了解的方方面面,这里就不赘述了。

继承

this的问题

js中的this也是个磨人的话题。对于this,除了了解和掌握它的基本原理,一定要能结合代码熟练应用。

就this来说,一般遵循这几个基本的原则:

  • this指向函数运行时所在的对象,而非函数定义时所在的对象;

  • 匿名函数或不处于任何对象中的函数this指向全局变量window/global;

  • 对于调用了call、apply、bind的函数,指定的this是谁就是谁;

  • 箭头函数默认不绑定this,它的this指向定义时其作用域对应的this;

下面结合几个面试中的问题来说明上面几点:

  • 全局变量的this指向window对象
var a = 10;
(function() {
  a = 11;
}());

console.log(global === this); // true
console.log(global.a); // 11
console.log(this.a); 11
  • 匿名函数的this指向window/global对象
var a = 100;
var b = {
  a: 10
};
function test() {
  return function() {
    console.log(this.a);
  };
}

test.call(b)(); // 100
  • 箭头函数this指向其所在函数作用域的this;
var value = 10;
var b = { value: 100 };

function test() {
  return () => {
    console.log(arguments, this.value);
  }
}

let a = test(1);
a.call(b, 2); // [1] 10

关于this更进一步的解读参考神奇的this

对象的深/浅拷贝

推荐阅读

浮点数的运算

事件的捕获和冒泡

事件捕获和冒泡基本模型相信大家都很清楚了。此处主要是想补充一点:

当元素同时绑定了事件捕获和冒泡时间时,事件的执行顺序是什么?

答案是浏览器更偏爱事件捕获。它会优先处理捕获事件,再处理冒泡事件。

更多关于事件的细节,推荐这篇文章:细说addEventListener与事件捕获、冒泡

ES6