js中的繼承關(guān)鍵是靠__proto__屬性實(shí)現(xiàn)的
prototype屬性的職責(zé)是將原型鏈中的數(shù)據(jù)放入__proto__中的中介坟桅,即我們在new 一個對象的時候
js中有兩種對象璃氢,即函數(shù)對象和普通對象
-
函數(shù)對象: 凡是通過new Function()創(chuàng)建的都是函數(shù)對象
函數(shù)對象屬性包含__proto__和prototype兩個屬性哟玷;而普通對象有__proto__沒有prototype屬性,
像 Number;Object;Array都是函數(shù)對象
//例如
var a = function(){}; function a(){}; var a = new Function(); var a = Function();
- 普通對象: 不是通過new Function()創(chuàng)建的對象
//例如
var a = 1 即(a = new Number(1)); var a = 'hello'即(a = new String(1));var a = []即(a = new Array());
-
__proto__
主要用來回溯對象,即用來繼承的巢寡,即當(dāng)執(zhí)行a.b的時候喉脖,如果當(dāng)前對象沒有定義b屬性,則會通過a.__proto__到父對象中查找抑月,以此類推 -
prototype
*其值是函數(shù)創(chuàng)建的時候創(chuàng)建了一個它的實(shí)例對象树叽,并賦值給prototype,其作用是將值傳遞給實(shí)例對象的__proto__谦絮,以實(shí)現(xiàn)繼承 -
實(shí)例代碼 Function
主要演示函數(shù)對象Function的__proto__屬性以及prototype屬性的值
console.log('--------------------------------函數(shù)對象Function--------------------------------------');
//函數(shù)對象Function Function.prototype === Function.__proto__ (true)
//此例比如 var temp = new Function();Function.prototype = temp;
//所以Function.prototype 為function
console.log('Function.prototype:',Function.prototype);
console.log('Function.__proto__:',Function.__proto__);
//原始對象Object
console.log('Function.prototype.__proto__:',Function.prototype.__proto__);
console.log('Function.__proto__.__proto__:',Function.__proto__.__proto__);
//一切的起點(diǎn)null 所有對象通過__proto__回溯都會找到null
console.log('Function.prototype.__proto__.__proto__:',Function.prototype.__proto__.__proto__);
console.log('Function.__proto__.__proto__.__proto__:',Function.__proto__.__proto__.__proto__);
//會抱錯题诵,null是起點(diǎn) null沒有__proto__屬性 不能在回溯
console.log('Function.prototype.__proto__.__proto__.__proto__:',Function.__proto__.__proto__.__proto__.__proto__);
console.log('Function.__proto__.__proto__.__proto__.__proto__:',Function.__proto__.__proto__.__proto__.__proto__);
-
chrome下輸出
-
實(shí)例代碼 Number
主要演示函數(shù)對象Number的__proto__屬性以及prototype屬性的值
console.log('--------------------------------函數(shù)對象Number--------------------------------------');
//函數(shù)對象Number 其實(shí)可以理解為var Number = new Function();
//原型對象prototype的值實(shí)際是函數(shù)創(chuàng)建的時候創(chuàng)建了一個它的實(shí)例對象,并賦值給prototype
//此例比如 var temp = new Number();Number.prototype = temp;Number.prototype 為Number的實(shí)例對象层皱,是普通對象,繼承自O(shè)bject
//所以typeof Number.prototype 為 Object
//Number為Function的實(shí)例對象性锭,而Function.__proto__為function ,
//所以typeof Number.__proto__ 為 function
console.log('Number.prototype:',Number.prototype);
console.log('Number.__proto__:',Number.__proto__);
console.log('typeof Number.prototype:',typeof Number.prototype);
console.log('typeof Number.__proto__:',typeof Number.__proto__);
//原始對象Object
console.log('Number.prototype.__proto__:',Number.prototype.__proto__);
console.log('Number.__proto__.__proto__:',Number.__proto__.__proto__);
//原始對象 無中生有的無 即null,
console.log('Number.prototype.__proto__.__proto__:',Number.prototype.__proto__.__proto__);
console.log('Number.__proto__.__proto__.__proto__:',Number.__proto__.__proto__.__proto__);
//會抱錯叫胖,因?yàn)閚ull沒有__proto__屬性console.log('Number.prototype.__proto__.__proto__.__proto__:',Number.__proto__.__proto__.__proto__.__proto__);
console.log('Number.__proto__.__proto__.__proto__.__proto__:',Number.__proto__.__proto__.__proto__.__proto__);
-
chrome下輸出
-
實(shí)例代碼 Object
主要演示函數(shù)對象Object的__proto__屬性以及prototype屬性的值
console.log('--------------------------------函數(shù)對象Object--------------------------------------');
console.log('Object.prototype:',Object.prototype);
console.log('Object.__proto__:',Object.__proto__);
console.log('typeof Object.prototype:',typeof Object.prototype);
console.log('typeof Object.__proto__:',typeof Object.__proto__);
//原始對象 無中生有的無 即null草冈,
console.log('Object.prototype.__proto__:',Object.prototype.__proto__);
//Object
console.log('Object.__proto__.__proto__:',Object.__proto__.__proto__);
//null
console.log('Object.__proto__.__proto__.__proto__:',Object.__proto__.__proto__.__proto__);
//抱錯
//console.log('Object.prototype.__proto__.__proto__:',Object.prototype.__proto__.__proto__);
-
chrome下輸出
-
實(shí)例代碼
主要演示普通對象的__proto__屬性以及prototype屬性的值
console.log('--------------------------------普通對象--------------------------------------');
//例如 var a = 1 即(a = new Number(1)); var a = 'hello'即(a = new String(1));var a = []即(a = new Array());
function obj(){
this.a = 1;this.b = 2; }
obj.prototype.pMethod=function(){
console.log('ddd');
}
var c = new obj();
//普通對象c 沒有prototype屬性,所以typeof c.prototype 為 Object
//c為Function的實(shí)例對象瓮增,而Function.__proto__為function
//所以typeof c.__proto__ 為 function
console.log('c.prototype:',c.prototype); //undefined
//我們再來看看__proto__的定義:他的值是創(chuàng)建實(shí)例對象的時候?qū)?yīng)的函數(shù)對象的原型對象
//即obj.prototype = new obj();
//obj.prototype.pMethod=function(){console.log('ddd');}
//c.__proto__ = obj.prototype;
//此時__proto__中有obj實(shí)例對象以及pMethod函數(shù)怎棱、__prototype__ 屬性
console.log('c.__proto__:',c.__proto__);
//如果我們這樣定義原型鏈函數(shù)
obj.prototype = {
pMethod:function(){
console.log('ddd');
}
}
var c = new obj();
//__proto__的定義:他的值是創(chuàng)建實(shí)例對象的時候?qū)?yīng)的函數(shù)對象的原型對象
//即obj.prototype = new obj();
//obj.prototype= {pMethod:function(){console.log('ddd');}}
//c.__proto__ = obj.prototype
//此時__proto__中有pMethod函數(shù)、__prototype__ 屬性
console.log('c.__proto__:',c.__proto__);
//原始對象Object
console.log('c.__proto__.__proto__:',c.__proto__.__proto__);
//原始對象 無中生有的無 即null绷跑,
console.log('c.__proto__.__proto__.__proto__:',c.__proto__.__proto__.__proto__);
//會抱錯拳恋,因?yàn)閚ull沒有__proto__屬性 //console.log('c.prototype.__proto__.__proto__.__proto__:',c.__proto__.__proto__.__proto__.__proto__);
-
chrome下輸出
總結(jié)
一個對象的proto記錄著自己的原型鏈,決定了自身的數(shù)據(jù)類型砸捏,改變proto就等于改變對象的數(shù)據(jù)類型谬运。
函數(shù)的prototype不屬于自身的原型鏈,其值是創(chuàng)建函數(shù)對象的實(shí)例带膜,它是子類創(chuàng)建的核心吩谦,決定了子類的數(shù)據(jù)類型,是連接子類原型鏈的橋梁膝藕。
在原型對象上定義方法和屬性的目的是為了被子類繼承和使用