《你不知道的Javascript--上卷 學習總結》(原型)

[[Prototype]]

一、Javascript中的對象有一個特殊的[[Prototype]]內置屬性,其實就是對於其餘對象的引用。幾乎全部的對象在建立時[[Prototype]] 屬性都會被賦予一個非空的值。bash

二、當咱們獲取一個對象的值的時候,首先會執行默認的[[Get]]操做來講,若是沒法在對象自己找到須要的屬性,就會繼續訪問對象的[[Prototype]]鏈函數

三、全部普通的[[Prototype]]鏈最終都會指向內置的Object.prototype.ui

四、若是咱們想給一個對象賦值的時候,這個屬性既出如今myObject中也出如今myObject的[[Prototype]]鏈上層,那麼就會發生屏蔽。若是不存在myObject上而是存在原型鏈上,會出現下面這些狀況。spa

myObject.foo = 'bar'
複製代碼
  • 若是在[[Prototype]]鏈上層存在名爲foo的普通數據訪問屬性而且沒有被標記爲只讀,那就會直接在myObject中添加一個名爲foo的新屬性,它是屏蔽屬性
  • 如第一條,若是被標記爲只讀,則沒法修改已有屬性或者在myObject上建立屏蔽屬性
  • 若是在[[Prototype]]鏈上層存在foo而且它是一個setter,那就必定會調用這個setter。foo不會被添加到myObject,也不會從新定義foo這個setter。

若是但願上面二和三條也發生屏蔽,就不能使用=操做符來賦值,而是使用Object.defineProperty來向myObject添加foo。prototype

function Foo(){
        
    }
    
    Foo.prototype.constructor === Foo // true
    var a = new Foo();
    a.constructor === Foo // true  實際a上並無constructor,而是經過prototype來查找到的Foo的constructor
複製代碼

Foo.prototype默認有一個公有而且不可枚舉的屬性.constructor,這個屬性引用的是對象關聯的函數.code

兩種方法把Bar.prototype關聯到Foo.prototype:對象

Bar.prototype = Object.create(Foo.prototype)
    
    Object.setPrototypeOf(Bar.prototype,Foo.prototype)
複製代碼

instanceof 操做符的左操做數是一個普通的對象,右操做數是一個函數.判斷左側的對象是不是右側函數的實例。ip

isPrototypeOf 判斷左側對象是否出如今右側對象的[[prototype]]鏈中。原型鏈

getPrototypeOf(a) 獲取a的原型get

b.isPrototypeOf(c) 
    
    Object.getPrototypeOf(a)
複製代碼

Object.create的polyfill代碼(這個polyfill有一個問題,就是不支持第二個參數(屬性描述符))

if(!Object.create){
        Object.create = function(o) {
            function F(){}
            F.prototype = o;
            return new F();
        }
    }
    
    var myObject = Object.create(anotherObject,{
        b:{
            enumerable:false,
            writable:true,
            configurable:false,
            value:3
        }
    })
複製代碼
相關文章
相關標籤/搜索