var Person = function (name) { this.name = name; } Person.prototype.say = function () { console.log(this.name); } var p = new Person('hello'); p.say(); // 'hello'
这是一个最简单的面向对象的写法,那为何经过 new 方法后赋值给 p 后 ,p能够调用say()方法!this
咱们来看看 new 为咱们作了些什么spa
1.var p = {}; 2.p.__proto__ = Person.prototype; 3.Person.call(p);
步骤1:初始化一个空对象
步骤2:将这个对象的 __proto__ 指向 Person.prototype
步骤3:初始化p
__proto__是什么鬼?prototype
每个对象的内部都会有一个__proto__属性,当咱们想要查找某个对象的某个属性时,若是没有,他就会去__proto__属性里面去找,若是仍是没找到,而__proto__属性里面又包含一个__proto__,就又去__proto__的__proto__里面去找.........,一直找到Object里面,若是尚未,就真的没有了!!code
你可能有点晕,可是这就是js中的原型链机制,而这个__proto__就是这个链子。对象
这是 console.log(p) 产生的结果!blog
位置1: p.__proto__ 指向了一个对象,而这个对象就是 Person.prototype继承
位置2:这个__proto__是属于Person.prototype的,他指向Object.prototype原型链
console.log(p.__proto__ == Person.prototype); // true
console.log(Person.prototype.__proto__ == Object.prototype); //true
如今咱们能够解释为啥p能够调用say()方法,p本身没有say()方法,可是由于它的__proto__属性指向了Person.prototype原型
恰巧 Person.prototype有say()方法,那要是Person.prototype里面仍是没有呢?,那就去Person.prototype.__proto__io
指向的Object.prototype里面去找,要是仍是没有,那就真的没有了
这是一张脑图!很是形象的描述了js原型继承的机制
咱们能够把上面的Cat mycat 换成咱们的 Person p
console.log(p.__proto__ == Person.prototype);//true console.log(Person.prototype.__proto__ == Object.prototype); //true console.log(Person.__proto__ == Function.prototype); //true console.log(Function.prototype.__proto__ == Object.prototype); //true console.log({}.__proto__ == Object.prototype); //true
__proto__ __proto__ __proto__
A——————————》B——————————》C——————————》Object.prototype
全部对象最终都指向Object.prototype
A里面有就用A里面的,不会再去找了,若是没有就经过原型链去链接的B里面找,若是有就用B里面的,若是没有就去B链接的C里面去找,
若是C有,就用C的,若是没有就去Object.prototype找,若是仍是没有,就真的没有了!!!