JavaScript使用原型鏈來解析屬性值。原型鏈描述了JavaScript引擎如何從對象查找到原型以及原型的原型,來定位對象的屬性值。當請求對象的屬性時,JavaScript引擎首先直接在該對象上查找。若是找不到該屬性,則查找原型(保存在對象的_proto_屬性中)查看原型是否包含了請求的屬性。若是JavaScipt引擎在對象的原型上找不到該屬性,它就查找原型的原型(原型只是一個對象它也有原型)。依次類推,當JavaScript到達通用的(generic)Object原型,原型鏈就結束了。若是JavaScript在原型鏈上的全部地方都找不到請求的屬性,則返回undefined。因爲JavaScript引擎會檢查原型鏈,具體細節可能變得錯綜複雜,可是對於咱們只需記得若是在對象上找不到屬性,則檢查它的原型。javascript
能夠使用_proto_屬性,手動的在原型鏈上「往上爬」。java
//瀏覽器兼容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會直接在對象上找到囚犯的名字並返回joe console.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在對象上沒有定義,在原型上沒有定義,原型的原型上也沒有定義, //所以它的值是undefined console.log( firstPrisoner.hopeless); var secondPrisoner = makePrisoner( 'Sam', '2BC' );
在node下執行輸出以下:node
{ name: 'Joe', id: '12A' } Joe 4 [object Object] undefined