標籤:
JavaScript使用原型鏈來解析屬性值。原型鏈描述了JavaScript引擎如何從對象尋找到原型以及原型的原型,來定位對象的屬性值。當請求對象的屬性時,JavaScript引擎首先直接在該對象上尋找。如果找不到該屬性,則尋找原型(儲存在對象的_proto_屬性中)查看原型是否包含了請求的屬性。如果JavaScipt引擎在對象的原型上找不到該屬性,它就尋找原型的原型(原型只是一個對象它也有原型)。依次類推,當JavaScript到達通用的(generic)Object原型,原型鏈就結束了。如果JavaScript在原型鏈上的所有地方都找不到請求的屬性,則返回undefined。由於JavaScript引擎會檢查原型鏈,具體細節可能變得錯綜複雜,但是對於我們只需記得如果在對象上找不到屬性,則檢查它的原型。
可以使用_proto_屬性,手動的在原型鏈上“往上爬”。
//瀏覽器安全色Object.create方法var objectCreat = function ( arg ) { if ( ! arg ) { return {}; } function obj() {}; obj.prototype = arg; return new obj;};Object.create = Object.create || objectCreate;//1.定義原型的對象var proto = { sentence : 4, probation : 2};//2.定義對象的建構函式var Prisoner = function(name, id){ this.name = name; this.id = id;};//3.將建構函式關聯到原型Prisoner.prototype = proto;//4.執行個體化對象//使用 Object.create 的常見原廠模式是使用工廠函數來建立並返回最終的對象//所有的工廠函數我們以make<object_name>的形式進行命名var makePrisoner = function( name, id ) { var prisoner = Object.create( proto ); prisoner.name = name; prisoner.id = id; return prisoner;};var firstPrisoner = makePrisoner( ‘Joe‘, ‘12A‘ );//原型鏈請求:firstPrisoner對象上請求//如果請求firstPrisoner.name,//JavaScript會直接在對象上找到囚犯的名字並返回joeconsole.log( firstPrisoner );console.log( firstPrisoner.name );//原型鏈請求:firstPrisoner對象的firstPrisoner._proto_原型上請求//如果請求firstPrisoner.sentence,JavaScript在對象上找不到該屬性,//但在原型上找到了它,傳回值為4.console.log( firstPrisoner.sentence );//原型鏈請求:firstPrisoner對象的firstPrisoner._proto_原型的//firstPrisoner._proto_._proto_原型上請求//toString()在對象和他的原型上都沒有,所以尋找原型的原型,//正好是JavaScript的基礎對象(base object 的方法)//得到的是字串[object Object]console.log( firstPrisoner.toString() );//hopeless在對象上沒有定義,在原型上沒有定義,原型的原型上也沒有定義,//因此它的值是undefinedconsole.log( firstPrisoner.hopeless);var secondPrisoner = makePrisoner( ‘Sam‘, ‘2BC‘ );
在node下執行輸出如下:
{ name: ‘Joe‘, id: ‘12A‘ }Joe4[object Object]undefined
JavaScript原型鏈