【深刻理解javascript】原型

一、一切都是對象html

一切(引用類型)都是對象,對象是屬性的集合數組

typeof函數輸出的一共有幾種類型,在此列出:函數

       function show(x) {

            console.log(typeof(x));    // undefined
            console.log(typeof(10));   // number
            console.log(typeof('abc')); // string
            console.log(typeof(true));  // boolean

            console.log(typeof(function () { }));  //function

            console.log(typeof([1, 'a', true]));  //object
            console.log(typeof ({ a: 10, b: 20 }));  //object
            console.log(typeof (null));  //object
            console.log(typeof (new Number(10)));  //object
        }
        show();
以上代碼列出了typeof輸出的集中類型標識,其中上面的四種(undefined, number, string, boolean)屬於簡單的值類型,不是對象。剩下的幾種狀況——函數、數組、對象、null、new Number(10)都是對象。他們都是引用類型。

判斷一個變量是否是對象很是簡單。值類型的類型判斷用typeof,引用類型的類型判斷用instanceof。spa

var fn = function () { };
console.log(fn instanceof Object);  // true

疑問:typeof的輸出類型中,function和object都是對象,爲什麼卻要輸出兩種答案呢?都叫作object不行嗎?prototype

二、函數和對象的關係code

對象都是經過函數建立的。htm

疑問:對象是函數建立的,而函數卻又是一種對象——天哪!函數和對象究竟是什麼關係啊?對象

三、prototype原型blog

函數的prototype是一個屬性,每個函數都有這麼一個屬性,這個prototype的屬性值是一個對象,這個對象默認只有一個constructor的屬性,指向這個函數自己。對象是什麼來,對象是屬性的集合。原型鏈

每一個對象都有一個隱藏的屬性——「__proto__」,這個屬性引用了建立這個對象的函數的prototype

如如下代碼,fn是一個實例對象,Fn是一個函數,則fn.__proto__ === Fn.prototype

 function Fn() { }
        Fn.prototype.name = '王福朋';
        Fn.prototype.getYear = function () {
            return 1988;
        };

        var fn = new Fn();
        console.log(fn.name);
        console.log(fn.getYear());

總結:每一個函數function都有一個prototype,即原型。這裏再加一句話——每一個對象都有一個__proto__,可成爲隱式原型。

四、隱式原型(這節重點記憶)

  • 每一個對象的__proto__屬性,指向建立該對象的函數的prototype。
var fn = new Foo();

fn._proto_ =  Foo.prototype //fn是由函數Foo建立的

 

  • 函數也不是從石頭縫裏蹦出來的,函數也是被建立出來的。誰建立了函數呢?——Function——注意這個大寫的「F」

function Foo(){…}等價於var Foo = new Function(…),因此

Foo._proto_=Function.prototype //Foo是由函數Function建立的

//Object對象也是由函數Function建立的,Object=function Object(){[native code]}

Object._proto_ = Function.prototype

//Function對象也是由函數Function建立的,Function=function Function(){[native code]}

Function._proto_ = Function.prototype

//自定義函數Foo的prototype本質上就是和 var obj = {} 是同樣的,都是被Object建立,因此:

Foo.prototype._proto_ = Object.prototype

//Function.prototype指向的對象也是一個普通的被Object建立的對象

Function.prototype._proto_ = Object.prototype

//Object.prototype確實一個特例——它的__proto__指向的是null,切記切記!

Object.prototype._proto_ = null

五、instanceof

Instanceof的判斷隊則是:沿着A的__proto__這條線來找,同時沿着B的prototype這條線來找,若是兩條線能找到同一個引用,即同一個對象,那麼就返回true。若是找到終點還未重合,則返回false

六、原型鏈

訪問一個對象的屬性時,先在基本屬性中查找,若是沒有,再沿着__proto__這條鏈向上找,這就是原型鏈。

相關文章
相關標籤/搜索