最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Javascript之旅 對(duì)象的原型鏈之由來

 更新時(shí)間:2010年08月25日 19:48:54   作者:  
本人是Javascript菜鳥,下面是前幾天學(xué)習(xí)Javascript的旅程心得,希望對(duì)和我一樣的入門者有點(diǎn)用,也希望高手批評(píng)指正。
以問題開始:

function Base(){}var base = new Base()
上面兩行代碼會(huì)創(chuàng)建幾個(gè)對(duì)象(object)?

要回答這個(gè)問題,先明確一下Javascript里object的概念。


Objects

在Javascript里,幾乎一切都是object(Arrays、Functions、Numbers、Objects……),而沒有C#里的class的概念。object的本質(zhì)是一個(gè)name-value pairs的集合,其中name是string類型的,可以把它叫做“property”,value包括各種objects(string,number,boolean,array,function…),指的是property的值。


typeof

既然object包含Arrays、Functions、Numbers、Objects……,那怎么區(qū)分這些呢?答案是typeof。 typeof返回一個(gè)字符串,如typeof(Null) = “object”,typeof(false) = “Boolean”, typeof(1) = “number”。既然總是返回字符串,那么對(duì)于typeof (typeof x),不管x是什么,總是返回”string”。


Constructor

JS里沒有class,也就沒有class里的構(gòu)造函數(shù),那么object是怎么被創(chuàng)建的呢?用構(gòu)造器:constructor。constructor其實(shí)就是Function,因此本身也是object。開頭的function Base(){}就是一個(gè)構(gòu)造器,var b = new Base()就是用這個(gè)構(gòu)造器(通過關(guān)鍵字new)創(chuàng)建了一個(gè)叫b的object。至此我們可以得出結(jié)論,開頭的兩行代碼至少創(chuàng)建了2個(gè)object:一個(gè)是Base,類型為function的object,一個(gè)是base,類型為object的object。

 

Function()和Object()

這是兩個(gè)重要的預(yù)定義好的構(gòu)造器。一切function(比如開頭的Base())都是由Function()構(gòu)造出來的;而Object的prototype將會(huì)被所有object繼承,下面會(huì)講到。

    

 

Function的創(chuàng)建過程

當(dāng)執(zhí)行function Base(){this.a = 1}時(shí),相當(dāng)于var Base = new Function(“this.a = 1”),也就是說,這行代碼本身,將使用預(yù)定義好的Function() constructor,來構(gòu)造一個(gè)function型object(即Base)出來。在這個(gè)創(chuàng)建過程中,js將做哪些事呢?

  1, 首先當(dāng)然會(huì)創(chuàng)建一個(gè)object起來,Base指向這個(gè)object。typeof 這個(gè)object = “function”
     
  2, 給Base附上__proto__屬性,讓它等于Function這個(gè)構(gòu)造器的prototype(也是預(yù)定義好的)。這是很重要的一步,也是規(guī)律性的一步。(規(guī)律:)在執(zhí)行任意類似varx = new X()時(shí),都會(huì)把X的prototype賦給x的__proto__,也就是說,x.__proto__和X.prototype此時(shí)會(huì)指向同一個(gè)對(duì)象。

     
  3, 為Base創(chuàng)建call屬性,該屬性是個(gè)function。因此我們可以這樣寫:Base.Call()

     
  4, 為Base創(chuàng)建Construct屬性,該屬性也是個(gè)function。在執(zhí)行var base = new Base()時(shí),即會(huì)調(diào)用這個(gè)Construct屬性。
  5, 為Base創(chuàng)建Scope,Length等屬性,略。
  6, 為Base創(chuàng)建prototype屬性:先用new Object()創(chuàng)建一個(gè)對(duì)象,為這個(gè)對(duì)象創(chuàng)建一個(gè)屬性叫constructor,該屬性值設(shè)置為Base。再把Base的prototype設(shè)置為這個(gè)新創(chuàng)建的對(duì)象。偽代碼如下:

var x = new Object();
x.constructor
= Base;
Base.prototype
= x;

 

先把關(guān)注點(diǎn)放到2和6。

 

__proto__和prototype

從2可以看出來,任意一個(gè)用構(gòu)造器構(gòu)造出來的object(包括Objects和Functions),都會(huì)有__proto__屬性,指向該構(gòu)造器的prototype屬性。注意__proto__是個(gè)私有屬性,在IE上是看不到的,我用的是chrome,可以看到。

從6可以看出,任意一個(gè)用new Function()構(gòu)造出來的functions,都會(huì)有prototype屬性,該屬性是用new Object()構(gòu)建出來的,初始公開屬性只有一個(gè)constructor。

    

 

原型鏈

再來分析下第6步的偽代碼,也就是為function創(chuàng)建prototype的這一步:

var x = new Object(); // 參見2中的規(guī)律,會(huì)有x.__proto__= Object.prototype。
x.constructor = Base;
Base.prototype
= x;

此時(shí)我們用Base()構(gòu)造一個(gè)對(duì)象出來:

var base= new Base(); // 參見2中的規(guī)律,會(huì)有base.__proto__ = Base.prototype,也就是 = x。
  // 因此有base.__proto__.__proto__ = x.__proto__
// 而x.__proto__ = Object.prototype(見上一個(gè)代碼片段)  
// 所以,base.__proto__.__proto__ = Object.prototype.

__proto__.__proto__,這就是傳說中JS對(duì)象的原型鏈!由于用Function()創(chuàng)建構(gòu)造器時(shí)的關(guān)鍵的第6步,保證了所有object的原型鏈的頂端,最終都指向了Object.prototype。

    

 

Property Lookup

而我們?nèi)绻x某個(gè)object的某個(gè)屬性,JS會(huì)怎么做呢?

比如有個(gè)object叫xxx,我們執(zhí)行alert(xxx.a),也就是讀取xxx的a屬性,那么JS首先會(huì)到xxx本身去找a屬性,如果沒找到,則到xxx.__proto__里去找a屬性,由此沿著原型鏈往上,找到即返回(沒找到,則返回undefined)??梢詠砜磦€(gè)例子:

    

上圖得知:base本身是沒有constructor屬性的,但是base.constructor確實(shí)能返回Base這個(gè)函數(shù),原因就在于base.__proto__有這個(gè)屬性。(base.__proto__是啥?就是Base.prototype,上面構(gòu)建Function的第6步的偽代碼里,為Base.prototype.constructor賦值為Base本身。)

 

Object作為“基類”

另外,由于任意object的原型鏈的頂端都是Object.prototype。所以,Object.prototype里定義的屬性,就會(huì)通過原型鏈,被所有的object繼承下來。這樣,預(yù)定義好的Object,就成了所有對(duì)象的“基類”。這就是原型鏈的繼承。

    

看上圖,Object.prototype已經(jīng)預(yù)定義好了一些屬性,我們?cè)僮芳右粭l屬性叫propertyA,那么這個(gè)屬性和預(yù)定義屬性一樣,都可以從base上讀到。

 

原型繼承

已經(jīng)得知,

對(duì)于 var xxx =new Object(); 有xxx.__proto__= Object.prototype;

對(duì)于 var xxx =new Base(); 有xxx.__proto__.__proto__= Object.prototype;

看上去很像什么呢?從c#角度看,很像Base是Object的子類,也就是說,由Base()構(gòu)造出來的object,比由Object()構(gòu)造出來的object,在原型鏈上更低一個(gè)層級(jí)。這是通過把Base.prototype指向由Object()創(chuàng)建的對(duì)象來做到的。那么自然而然,如果我想定義一個(gè)繼承自Base的構(gòu)造器,只需把改構(gòu)造器的prototype指向一個(gè)Base()構(gòu)造出來的對(duì)象。

function Derived(){}
var base = new Base();
Derived.prototype
= base;
var d = newDerived(); //很容易推算出:d.__proto__.__proto__.__proto__ = Object.prototype.

推算過程:d.__proto__指向Derived.prototype,也就是base;則__proto__.__proto__指向base.__proto__,也就是Base.prototype,也就是某個(gè)new object()創(chuàng)建出來的東東,假設(shè)是o;則__proto__.__proto__.__proto__指向o.__proto__,也就是Object.prototype。

 

回答開頭的問題,以及幾個(gè)新的問題

那兩行代碼至少創(chuàng)建了三個(gè)對(duì)象:Base、base、Base.prototype。順便說說,base是沒有prototype屬性的,只有function類型的object,在被構(gòu)建時(shí)才會(huì)被創(chuàng)建prototype屬性。

    

 

d.constructor會(huì)返回什么呢?

構(gòu)造器Base()和Derived()里都是空的,如果有代碼,將會(huì)怎么被執(zhí)行呢?

……

待續(xù)。見下篇

相關(guān)文章

  • iframe如何動(dòng)態(tài)創(chuàng)建及釋放其所占內(nèi)存

    iframe如何動(dòng)態(tài)創(chuàng)建及釋放其所占內(nèi)存

    一個(gè)項(xiàng)目后期測試發(fā)現(xiàn)瀏覽器內(nèi)存一直居高不下,而且打開iframe頁面越多內(nèi)存占用越大,在IE系列瀏覽器中尤其明顯,下面與大家分享下iframe動(dòng)態(tài)創(chuàng)建及釋放內(nèi)存
    2014-09-09
  • JavaScript對(duì)象拷貝與Object.assign用法實(shí)例分析

    JavaScript對(duì)象拷貝與Object.assign用法實(shí)例分析

    這篇文章主要介紹了JavaScript對(duì)象拷貝與Object.assign用法,結(jié)合實(shí)例形式分析了javascript深拷貝與淺拷貝以及Object.assign的功能與相關(guān)使用技巧,需要的朋友可以參考下
    2018-06-06
  • JavaScript利用正則表達(dá)式去除日期中的“-”

    JavaScript利用正則表達(dá)式去除日期中的“-”

    第一種,將日期字符串先截取,然后拼接;第二種,就是利用正則表達(dá)式去掉“-”本例選擇第二種,比較快捷不容易出錯(cuò)
    2014-07-07
  • Javascript中window.name屬性詳解

    Javascript中window.name屬性詳解

    這篇文章主要介紹了Javascript中window.name屬性詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 在JavaScript中讓this保持正確的指向的解決方案

    在JavaScript中讓this保持正確的指向的解決方案

    這篇文章主要介紹了關(guān)于在 JavaScript 中如何讓 this 保持正確的指向的解決方案,文中給大家介紹了三種解決方案,使用閉包,使用箭頭函數(shù)和換綁 this這三種方法,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2024-01-01
  • javascript正則表達(dá)式模糊匹配IP地址功能示例

    javascript正則表達(dá)式模糊匹配IP地址功能示例

    這篇文章主要介紹了javascript正則表達(dá)式模糊匹配IP地址功能,結(jié)合簡單實(shí)例形式演示了JS模糊匹配IP地址的實(shí)現(xiàn)方法,涉及針對(duì)數(shù)字及字符串的相關(guān)正則判定與匹配操作技巧,需要的朋友可以參考下
    2017-01-01
  • uni-app的基本使用教程

    uni-app的基本使用教程

    uni-app??? 是一個(gè)使用 ???Vue.js?? 開發(fā)所有前端應(yīng)用的框架,開發(fā)者編寫一套代碼,可發(fā)布到iOS、Android、H5、以及各種小程序(微信/支付寶/百度/頭條/QQ/釘釘)等多個(gè)平臺(tái),這篇文章主要介紹了uni-app的基本使用,需要的朋友可以參考下
    2022-11-11
  • 微信小程序?qū)崿F(xiàn)tab頁面切換效果

    微信小程序?qū)崿F(xiàn)tab頁面切換效果

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)tab頁面切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Javascript如何實(shí)現(xiàn)雙指控制圖片功能

    Javascript如何實(shí)現(xiàn)雙指控制圖片功能

    這篇文章主要介紹了Javascript如何實(shí)現(xiàn)雙指控制圖片功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • TypeScript中的類型斷言[as語法|<>語法]的使用

    TypeScript中的類型斷言[as語法|<>語法]的使用

    本文主要介紹了TypeScript中的類型斷言[as語法|<>語法]的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06

最新評(píng)論

特克斯县| 临高县| 雷山县| 云林县| 新津县| 饶平县| 炉霍县| 泸定县| 平江县| 湖口县| 石家庄市| 涿鹿县| 司法| 福海县| 凤冈县| 宿迁市| 江达县| 涞水县| 赤壁市| 呼图壁县| 抚州市| 墨江| 夏邑县| 开阳县| 石林| 阿拉善右旗| 台中县| 荣昌县| 定安县| 嵩明县| 霸州市| 衡阳县| 内乡县| 梨树县| 德化县| 丹棱县| 丰顺县| 泰宁县| 喀喇沁旗| 胶南市| 老河口市|