首頁  >  文章  >  web前端  >  js中什麼是原型物件和原型鏈

js中什麼是原型物件和原型鏈

巴扎黑
巴扎黑原創
2017-07-18 17:04:171419瀏覽

在Javascript中,萬物皆對象,但對像也有區別,大致可以分為兩類,即:普通對象Object 和 函數對象Function

一般而言,透過new Function產生的物件是函數對象,其他物件都是普通物件。

範例說明:

#1
##2
3
4
5
6
##10
11
12
13
14
15
16
# #17
1819
20#21
function f1 (){
    //todo
}
var  f2 = function(){
    //todo}; var f3 = new
 
Function(
'x'#,'console.log(x)'
);var o1 = {} ;
var o2 = #new Object();
var o3 = new f1();
 
console.log(    typeof
 
f1,//function    #typeof
 
f2,//function    typeof
 
f3,//function
#########    ######typeof### ###o1,#####//object######## #####    ######typeof### ###o2,######//object###########    #######type##########    #######type###########    #######type## # ###o3 ######//object############);#######
>> function function function object object object

##f1屬於函數的聲明,最常見的函數定義方式,f2實際上是一個匿名函數,把這個匿名函數賦值給了f2,屬於函數表達式,f3不常見,但也是一種函數物件。

Function是JS自帶的對象,f1,f2在創建的時候,JS會自動透過new Function()的方式來建構這些對象,因此,這三個物件都是透過new Function()創建的。

在Javascript中建立物件有兩種方式:物件字面量和使用new表達式,o1和o2的創建恰好對應了這兩種方式,重點講一下o3, 如果用Java和C#的思路來理解的話,o3是f1的實例對象,o3和f1是同一型,至少我以前這麼認為,其實不然...

那麼怎麼理解呢?很簡單,看o3是不是透過new Function產生的, 顯然不是,既然不是函數對象,那就是普通對象。

透過對函數物件和普通物件的簡單理解之後,我們再來了解Javascript中的原型和原型鏈:

在JS中,每當創建一個函數物件f1 時,該對像中都會內建一些屬性,其中包括prototype和__proto__,  prototype即原型對象,它記錄著f1的一些屬性和方法。

要注意的是,prototype 對f1是不可見的,也就是說,f1不會找出prototype中的屬性和方法。
1
#2
3
function f(){}
f.prototype.foo = "abc"#;
console.log(f.foo); #//undefined

那麼,prototype有什麼用呢? 其實prototype的主要作用就是繼承。 通俗一點講,prototype中定義的屬性和方法都是留給自己的「後代」用的,因此,子類別完全可以存取prototype中的屬性和方法。

想要知道f1是如何把prototype留給“後代”,我們需要了解一下JS中的原型鏈,此時,JS中的__proto__ 入場了,這哥們長的很奇特,隱藏的也很深,以致於你經常見不到它,但它在普通對象和函數對像中都存在, 它的作用就是保存父類的prototype對象,JS在通過new 表達式創建一個對象的時候,通常會把父類別的prototype賦值給新物件的__proto__屬性,這樣,就形成了一代代傳承...
##1
2
3
4
#function f(){}
f.prototype.foo = "abc";
var#obj = new f();
console.log(obj.foo); #/ /abc
#

現在我們知道,obj中__proto__保存的是f的prototype, 那麼f的prototype中的__proto__中保存的是什麼呢? 看下圖:

如圖所示,f.prototype的__proto__中保存的是Object.prototype,Object.prototype物件中也有__proto__,而從輸出結果看,Object. prototype.__proto__ 是null,表示obj物件原型鏈的終結。如下圖所示:

obj物件擁有這樣一個原型鏈以後,當obj.foo執行時,obj會先查找自身是否有該屬性,但不會查找自己的prototype,當找不到foo時,obj就沿著原型鏈依次去查找...

在上面的例子中,我們在f的prototype上定義了foo屬性,這時obj就會在原型鏈上找到這個屬性並執行。

 

最後,用幾句話總結本文中涉及到的重點:

  • 原型鏈的形成真正是靠__proto__ 而非prototype,當JS引擎執行物件的方法時,先查找物件本身是否存在該方法,如果不存在,會在原型鏈上查找,但不會查找自身的prototype。

  • 一個物件的__proto__記錄著自己的原型鏈,決定了自身的資料類型,改變__proto__就等於改變物件的資料類型。

  • 函數的prototype不屬於自身的原型鏈,它是子類別創建的核心,決定了子類別的資料類型,是連接子類別原型鏈的橋樑。

  • 在原型物件上定義方法和屬性的目的是為了被子類別繼承和使用。

#

以上是js中什麼是原型物件和原型鏈的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn