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找,若是仍是沒有,就真的沒有了!!!