欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

圖解prototype、proto和constructor的三角關(guān)系

 更新時間:2016年07月31日 12:25:35   作者:xiaohuochai  
在javascript中,prototype、constructor以及__proto__之間有著“著名”的剪不斷理還亂的三角關(guān)系,樓主就著自己對它們的淺顯認(rèn)識,來粗略地理理以備忘,有不對之處還望斧正。

  javascript里的關(guān)系又多又亂。作用域鏈?zhǔn)且环N單向的鏈?zhǔn)疥P(guān)系,還算簡單清晰;this機(jī)制的調(diào)用關(guān)系,稍微有些復(fù)雜;而關(guān)于原型,則是prototype、proto和constructor的三角關(guān)系。本文先用一張圖開宗明義,然后詳細(xì)解釋原型的三角關(guān)系

圖示

概念

  上圖中的復(fù)雜關(guān)系,實際上來源就兩行代碼

function Foo(){};var f1 = new Foo;

【構(gòu)造函數(shù)】

  用來初始化新創(chuàng)建的對象的函數(shù)是構(gòu)造函數(shù)。在例子中,F(xiàn)oo()函數(shù)是構(gòu)造函數(shù)

【實例對象】

  通過構(gòu)造函數(shù)的new操作創(chuàng)建的對象是實例對象??梢杂靡粋€構(gòu)造函數(shù),構(gòu)造多個實例對象

function Foo(){};
var f1 = new Foo;
var f2 = new Foo;
console.log(f1 === f2);//false

【原型對象及prototype】

  構(gòu)造函數(shù)有一個prototype屬性,指向?qū)嵗龑ο蟮脑蛯ο?。通過同一個構(gòu)造函數(shù)實例化的多個對象具有相同的原型對象。經(jīng)常使用原型對象來實現(xiàn)繼承

function Foo(){};
Foo.prototype.a = 1;
var f1 = new Foo;
var f2 = new Foo;console.log(Foo.prototype.a);
//1
console.log(f1.a);//1
console.log(f2.a);//1

【constructor】

  原型對象有一個constructor屬性,指向該原型對象對應(yīng)的構(gòu)造函數(shù)

function Foo(){};
console.log(Foo.prototype.constructor === Foo);//true

  由于實例對象可以繼承原型對象的屬性,所以實例對象也擁有constructor屬性,同樣指向原型對象對應(yīng)的構(gòu)造函數(shù)

function Foo(){};
var f1 = new Foo;
console.log(f1.constructor === Foo);//true

【proto】

  實例對象有一個proto屬性,指向該實例對象對應(yīng)的原型對象

function Foo(){};
var f1 = new Foo;
console.log(f1.__proto__ === Foo.prototype);//true

說明

  概念介紹完了,現(xiàn)在對圖示的關(guān)系進(jìn)行詳細(xì)說明

function Foo(){};
var f1 = new Foo;

【第一部分: Foo】

  

實例對象f1是通過構(gòu)造函數(shù)Foo()的new操作創(chuàng)建的。構(gòu)造函數(shù)Foo()的原型對象是Foo.prototype;實例對象f1通過__proto__屬性也指向原型對象Foo.prototype

function Foo(){};
var f1 = new Foo;
console.log(f1.__proto === Foo.prototype);//true

  實例對象f1本身并沒有constructor屬性,但它可以繼承原型對象Foo.prototype的constructor屬性

function Foo(){};
var f1 = new Foo;console.log(Foo.prototype.constructor === Foo);//true
console.log(f1.constructor === Foo);//true
console.log(f1.hasOwnProperty('constructor'));//false

  下圖是實例對象f1的控制臺效果

【第二部分: Object】

  

Foo.prototype是f1的原型對象,同時它也是實例對象。實際上,任何對象都可以看做是通過Object()構(gòu)造函數(shù)的new操作實例化的對象  所以,F(xiàn)oo.prototype作為實例對象,它的構(gòu)造函數(shù)是Object(),原型對象是Object.prototype。相應(yīng)地,構(gòu)造函數(shù)Object()的prototype屬性指向原型對象Object;實例對象Foo.prototype的proto屬性同樣指向原型對象Object

function Foo(){};
var f1 = new Foo;
console.log(Foo.prototype.__proto__ === Object.prototype);//true

  實例對象Foo.prototype本身具有constructor屬性,所以它會覆蓋繼承自原型對象Object.prototype的constructor屬性

function Foo(){};
var f1 = new Foo;
console.log(Foo.prototype.constructor === Foo);//true
console.log(Object.prototype.constructor === Object);//true
console.log(Foo.prototype.hasOwnProperty('constructor'));//true

  下圖是實例對象Foo.prototype的控制臺效果

  如果Object.prototype作為實例對象的話,其原型對象是什么,結(jié)果是null。私以為,這可能也是typeof null的結(jié)果是'object'的原因之一吧

console.log(Object.prototype.__proto__ === null);//true

【第三部分: Function】

  前面已經(jīng)介紹過,函數(shù)也是對象,只不過是具有特殊功能的對象而已。任何函數(shù)都可以看做是通過Function()構(gòu)造函數(shù)的new操作實例化的結(jié)果

  如果把函數(shù)Foo當(dāng)成實例對象的話,其構(gòu)造函數(shù)是Function(),其原型對象是Function.prototype;類似地,函數(shù)Object的構(gòu)造函數(shù)也是Function(),其原型對象是Function.prototype

function Foo(){};
var f1 = new Foo;console.log(Foo.__proto__ === Function.prototype);//true
console.log(Object.__proto__ === Function.prototype);//true

  原型對象Function.prototype的constructor屬性指向構(gòu)造函數(shù)Function();實例對象Object和Foo本身沒有constructor屬性,需要繼承原型對象Function.prototype的constructor屬性

function Foo(){};
var f1 = new Foo;
console.log(Function.prototype.constructor === Function);//true
console.log(Foo.constructor === Function);//true
console.log(Foo.hasOwnProperty('constructor'));//false
console.log(Object.constructor === Function);//true
console.log(Object.hasOwnProperty('constructor'));//false

  所有的函數(shù)都可以看成是構(gòu)造函數(shù)Function()的new操作的實例化對象。那么,F(xiàn)unction可以看成是調(diào)用其自身的new操作的實例化的結(jié)果

  所以,如果Function作為實例對象,其構(gòu)造函數(shù)是Function,其原型對象是Function.prototype

console.log(Function.__proto__ === Function.prototype);//true
console.log(Function.prototype.constructor === Function);//true
console.log(Function.prototype === Function);//true

  如果Function.prototype作為實例對象的話,其原型對象是什么呢?和前面一樣,所有的對象都可以看成是Object()構(gòu)造函數(shù)的new操作的實例化結(jié)果。所以,F(xiàn)unction.prototype的原型對象是Object.prototype,其原型函數(shù)是Object()

console.log(Function.prototype.__proto__ === Object.prototype);//true

  第二部分介紹過,Object.prototype的原型對象是null

console.log(Object.prototype.__proto__ === null);//true

總結(jié)

  【1】函數(shù)(Function也是函數(shù))是new Function的結(jié)果,所以函數(shù)可以作為實例對象,其構(gòu)造函數(shù)是Function(),原型對象是Function.prototype

  【2】對象(函數(shù)也是對象)是new Object的結(jié)果,所以對象可以作為實例對象,其構(gòu)造函數(shù)是Object(),原型對象是Object.prototype

  【3】Object.prototype的原型對象是null

相關(guān)文章

  • js函數(shù)調(diào)用常用方法詳解

    js函數(shù)調(diào)用常用方法詳解

    js的函數(shù)調(diào)用會免費奉送兩個而外的參數(shù)就是 this 和 arguments,我們所知道的應(yīng)該有4中調(diào)用方式吧,接下來將為您詳細(xì)介紹,感興趣的朋友可以參考下
    2012-12-12
  • JavaScript基本編碼模式小結(jié)

    JavaScript基本編碼模式小結(jié)

    本文中筆者整理的這些模式包含了編寫JavaScript代碼時一些常用的方法或者小技巧,可以幫助初學(xué)JavaScript的同學(xué)迅速提升代碼質(zhì)量
    2012-05-05
  • JavaScript 無符號右移賦值操作

    JavaScript 無符號右移賦值操作

    無符號右移賦值操作 (>>>=)是對變量值根據(jù)表達(dá)式值所規(guī)定的位數(shù)進(jìn)行無符號右移,并將結(jié)果賦給該變量。
    2009-04-04
  • 優(yōu)化RequireJS項目的相關(guān)技巧總結(jié)

    優(yōu)化RequireJS項目的相關(guān)技巧總結(jié)

    這篇文章主要介紹了優(yōu)化RequireJS項目的相關(guān)技巧總結(jié),RequireJS是一個人氣JavaScript庫,需要的朋友可以參考下
    2015-07-07
  • 詳解js閉包

    詳解js閉包

    閉包是一個比較抽象的概念,尤其是對js新手來說.書上的解釋實在是比較晦澀,對我來說也是一樣.
    2014-09-09
  • Javascript的時間戳和php的時間戳轉(zhuǎn)換注意事項

    Javascript的時間戳和php的時間戳轉(zhuǎn)換注意事項

    需要注意的是js的時間戳是13位,php的時間戳是10位,轉(zhuǎn)換函數(shù)如下,感興趣的朋友可以參考下哈
    2013-04-04
  • Javascript call和apply區(qū)別及使用方法

    Javascript call和apply區(qū)別及使用方法

    JavaScript中通過call或者apply用來代替另一個對象調(diào)用一個方法,將一個函數(shù)的對象上下文從初始的上下文改變?yōu)橛?thisObj 指定的新對象
    2013-11-11
  • JavaScript中的toLocaleLowerCase()方法使用詳解

    JavaScript中的toLocaleLowerCase()方法使用詳解

    這篇文章主要介紹了JavaScript中的toLocaleLowerCase()方法使用詳解,是JS入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-06-06
  • JavaScript入門教程(4) js瀏覽器對象

    JavaScript入門教程(4) js瀏覽器對象

    navigator 瀏覽器對象,包含了正在使用的 Navigator 的版本信息。反映了當(dāng)前使用的瀏覽器的資料。JavaScript 客戶端運行時刻引擎自動創(chuàng)建 navigator 對象。
    2009-01-01
  • js實現(xiàn)單元格拖拽效果

    js實現(xiàn)單元格拖拽效果

    這篇文章主要為大家詳細(xì)介紹了js實現(xiàn)單元格拖拽效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02

最新評論