构造函数、原型、实例
构造函数:用来在创建对象时初始化对象。特点:构造函数名一般为大写字母开头;与new运算符一起使用来实例化对象。
原型:构造函数在创建的过程中,系统自动创建出来与构造函数相关联的一个空的对象。可以由构造函数.prototype来访问到。
实例:通过构造函数创建出来的对象。
构造函数、原型对象、实例化对象三者的关系:

示例:
function Person() {
}
// prototype是函数才会有的属性
Person.prototype.name = 'Kevin';
var p = new Person();
console.log(p.__proto__ === Person.prototype); // true
console.log(Person === Person.prototype.constructor); // true
//当获取 p.constructor 时,其实 p 中并没有 constructor 属性,当不能读取到constructor 属性时,
//会从 p 的原型也就是 Person.prototype 中读取,正好原型中有该属性,所以:
console.log(p.constructor === Person); // true
console.log(p.constructor === Person.prototype.constructor); // true
- 在实例化对象p的过程中,系统就自动创建出了构造函数的原型,即 Person.prototype;
- 每个原型都有一个 constructor 属性指向关联的构造函数;
- 每个实例对象(除了 null )都具有的一个属性,叫__proto__ ,这个属性会指向该对象的原型;
- prototype是构造函数的属性,__proto__是实例对象的属性,constructor是原型的属性。
原型链
原型链:每一个对象都有自己的原型对象,原型对象本身也是对象,原型对象也有自己的原型对象,这样就形成了一个链式结构,叫做原型链。 在上面这个例子中的p对象的原型链结构图如下:
p对象----->Person.prototype------->Object.prototype--------->null
对这个实例化对象而言,访问对象的属性,是首先在对象本身去找,如果没有,就会去他的原型对象中找,一直找到原型链的终点; 如果是修改对象的属性,如果这个实例化对象中有这个属性,就修改,没有这个属性就添加这个属性。

new与instanceOf
new A()
使用new命令时,它后面的函数依次执行下面的步骤:
- 创建一个空对象,作为将要返回的对象实例。
- 将这个空对象的原型,指向构造函数的prototype属性。
- 将这个空对象赋值给函数内部的this关键字。
- 开始执行构造函数内部的代码。
可表示如下:
var obj = {}; // 创建一个空对象
obj.__proto__ = 构造函数.prototype;
构造函数.call(this); // 绑定this
...
return obj;
A instanceOf B
主要的实现原理: 就是只要右边变量的 prototype 在左边变量的原型链上即可。 因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例.
类型判断
简单来说,我们使用 typeof 来判断基本数据类型是 ok 的,不过需要注意当用 typeof 来判断 null 类型时的问题, 如果想要判断一个对象的具体类型可以考虑用 instanceof,但是 instanceof 也可能判断不准确,比如一个数组,他可以被 instanceof 判断为 Object。 所以我们要想比较准确的判断对象实例的类型时,可以采取 Object.prototype.toString.call 方法