1. 程式人生 > >JS(原型和原型鏈)

JS(原型和原型鏈)

property 擴展 ret alt ron back 技術分享 繼承 style

題目1.如何準確判斷一個變量是數組類型

技術分享圖片

使用 instanceof 方法

題目2.寫一個原型鏈繼承的例子

技術分享圖片

實例:封裝 DOM 查詢

定義構造函數 Elem,屬性封裝成 id

技術分享圖片

打印出所有的 html

技術分享圖片

將所有的 html 變為 hello imooc ,並且點擊彈出 ‘clicked’

技術分享圖片

將所有的 html 變為 hello imooc ,並且點擊彈出 ‘clicked’

技術分享圖片

鏈式操作

技術分享圖片

題目3.描述 new 一個對象的過程

技術分享圖片

1.創建一個新對象

2.this 指向這個新對象

3.執行代碼,即對 this 賦值

4.返回 this

一、構造函數

技術分享圖片

大寫字母開頭一般都是構造函數

new 的過程:

1.var f = new Foo(‘zhangsan‘,20) 將參數傳進去,函數中的 this 會變成空對象

2.this.name = name;this.age = age;this.class = ‘class-1‘ 為賦值;return this 為實際的運行機制

3.return 之後賦值給 f ,f 具備了 f.name = zhangsan、f.age = 20、f.class = ‘class-1‘

4.繼續執行到 f1 ,則 f1.name = lisi、f1.age = 22、f1.class = ‘class-1‘

二、構造函數(擴展)

1.var a = {} 其實是 var a = new Object()的語法糖 (a 的構造函數是 Object 函數)

2.var a = [] 其實是 var a = new Array()的語法糖 (a 的構造函數是 Array 函數)

3.function Foo(){...}其實是 var Foo = new Function(...) (Foo 的構造函數是 Function 函數)

4.使用 instanceof 判斷一個函數是否是一個變量的構造函數 (判斷一個變量是否為“數組” 變量 instanceof Array)

三、原型規則

1.所有的引用類型(數組、對象、函數)都具有對象特性,即可自由擴展屬性(除了“null”)

技術分享圖片

2.所有的引用類型(數組、對象、函數)都有一個 _proto_ 屬性(隱式原型屬性),屬性值是一個普通的對象

技術分享圖片

3.所有的函數,都有一個 prototype(顯式原型)屬性,屬性值也是一個普通的對象

技術分享圖片

4. 所有的引用類型(數組、對象、函數), _proto_ 屬性值(隱式原型屬性)指向它的構造函數的“prototype”屬性值

技術分享圖片

當試圖得到一個對象的某個屬性時,如果這個對象本身沒有這個屬性,那麽會去它的_proto_(即它的構造函數的 prototype(顯式原型))中尋找

5.

技術分享圖片

f.printName() 中 f 的(自身)屬性是 name ,屬性值是 zhangsan

f.alertName() 中 f 的隱式原型正好指向 Foo 的顯式原型 Foo.prototype, f 本身沒有 alertName 的屬性,會去其隱式原型中尋找,故執行f.alertName()時會執行Foo.prototype.alertName = function (),因為 Foo 擴展 function,故輸出 zhangsan

故通過對象的屬性的形式來執行函數的時候,無論函數是自身的屬性還是從原型中得到的屬性, this 永遠指向 f 自身,沒有指向函數,故執行f.alertName()時,alert(this.name) 中的 this 就是 f 。

6.循環對象自身的屬性

技術分享圖片

if (f.hasOwnProperty(item)) 中遍歷 f 時,判斷遍歷中的 item,是否可以通過 hasOwnProperty 驗證,通過則表明它是 f 自身的屬性,未通過則表明 是 f 通過原型獲得的屬性

四、原型鏈

技術分享圖片

f.toString(),當這個對象沒有這個屬性的時候,去它自身的隱式原型中找,它自身的隱式原型就是它構造函數(Foo)的顯式原型(Foo.prototype)但顯式原型(Foo.prototype)中並沒有 toString ;但顯式原型(Foo.prototype)也是對象,也要在它的隱式原型中找,即在其構造函數 (Object )的顯式原型中去找 toString. 故要在 f._proto_(隱式原型)的._proto_(隱式原型)中找,如圖所示,故輸出 null

技術分享圖片

方框為 構造函數,圓框為 對象,特例:Object.prototype 的 隱式原型是 null (JS避免死循環)

五、instanceof

判斷 引用類型 屬於哪個 構造函數 的方法

技術分享圖片

f instanceof FOO 的判斷邏輯:f 是 Foo new出來的一個類型(正確)

判斷方式:f 的隱式原型(proto)一層一層往上,能否對應到 Foo.prototype(顯式原型)

試判斷:f instance of Object (正確)見上圖

JS(原型和原型鏈)