JS核心系列 原型物件

2021-10-01 13:49:35 字數 3091 閱讀 3020

在js中,每當建立乙個函式物件f1 時,該物件中都會內建一些屬性,其中包括prototype和__proto__, prototype即原型物件。

每乙個建構函式都有乙個與之相關聯的物件,該物件稱之為原型物件。

每個例項物件都能共享其原型物件上的屬性和方法。

原型物件的作用主要用來實現屬性的繼承,讓例項物件能共享原型物件的屬性,減少記憶體分配。

所以,在上一節中,我們想在每個person物件中共享同乙個say方法,可以這樣來實現。

function person(name, age) //在原型物件上新增say函式,例項物件共享該函式

person.prototype.say = function();var p = new person(「zs」, 10, say);

p.say();var p2 = new person(「zs」, 10, say);

p2.say();

在原型物件上新增成員的方法:

​ 建構函式.prototype.成員名 = 成員值;

為person原型物件新增say方法後,實現了在多個例項物件上共享該方法的功能。

獲取原型物件的方法:

​ 建構函式.prototype

​ 例項物件.__ proto __

在每個例項物件上都有乙個__ proto的屬性,也是用來獲取該物件的原型物件。

person.prototype == p.proto __;//true

下圖詳細說明了各物件之間的關係:

物件導向中的核心概念

建構函式:person,和new關鍵字一起建立物件

建構函式的原型物件:person.prototype,

原型物件:和建立例項物件的建構函式相互關聯的物件

例項物件:由構造器建立出來的物件稱之為例項物件

例項化:由構造器建立例項物件的過程稱之為例項化

物件的成員:屬性+方法

例項成員:例項物件上的屬性和方法,name,age,只能當前例項物件才能訪問

原型成員:原型物件上的屬性和方法,say(),使用該原型物件對應構造器建立出來的所有例項物件都能訪問

靜態成員:直接新增在建構函式上的屬性和方法,只能使用建構函式才能訪問

__ proto屬性介紹

該屬性是在es6之後才納入規範,在這之前,只有部分瀏覽器實現。

該屬性可以獲取指定例項物件的原型物件,p.proto,和person.prototype獲取的一樣

我們也可以使用object構造器上的getprototypeof(例項物件)方法獲取指定例項物件的原型物件

以上提到的三種獲取原型物件的方法所得到的結果是一樣的。即:

object.getprototypeof§ == person.prototype == p.proto __

擴充套件內建物件

內建物件是js中事先定義好的物件,可以直接拿來使用的物件,在這類物件中已經封裝好了一堆的方法和屬性,方便開發者完成基本的功能。

但是在實際開發中,這些屬性或者方法不一定能夠滿足我們的需求,此時就需要對這些內建物件做功能擴充套件。

需求:為陣列物件新增乙個獲取元素個數的方法

var arr1 = [1, 2, 3];var arr2 = [「a」, 「b」, 「c」,「d」];

arr1.getlength = function () console.log(arr1.getlength());

上面為陣列arr1新增了乙個getlength()方法獲取其元素個數,那麼此時的arr2物件上有這個方法嗎?相信大家心裡都有答案。如果想要arr2擁有同樣的功能,也需要同樣的操作。

所以這種方式不可取,如果100個陣列都想都需要這樣的功能,操作起來就比較複雜了。

根據前面學過的知識點,我們完全可以使用原型來解決這個問題。

var arr1 = [1, 2, 3];var arr2 = [「a」, 「b」, 「c」,「d」];array.prototype.getlength = function () console.log(arr1.getlength());// 3console.log(arr2.getlength());// 4

我們直接在array的原型物件上新增getlength()方法,之後建立的所有的陣列物件都擁有了該方法,搞定!

這種方式能夠解決我們的問題,但是還是存在問題的:

在多人開發的環境中,如果使用這種方式對內建物件做擴充套件,可能會對其他開發人員造成影響

如果在原型物件上新增了過多的成員,會降低物件成員的搜尋效率。

安全的擴充套件內建物件

上面擴充套件內建物件的方法存在一定的問題,問題的關鍵其實在於我們是直接在內建物件的原型上進行拓展的,這樣導致對其他使用該物件的開發人員造成影響。

所以,我們的解決思路就是,自定義乙個物件,讓該物件繼承需要擴充套件的內建物件,然後只需要對自定的物件進行操作即可。

function myarray() //讓myarray的原型指向array物件//即繼承array中的所有成員

myarray.prototype= new array();

myarray.prototype.getlength=function () var arr1 = new myarray();

arr1.push(「a」,「b」,「c」,「d」,「e」);//內建物件的初始方法console.log(arr1.getlength());//擴充套件之後的方法

接下來,如果想要對陣列做擴充套件,我們只需要操作myarray即可,而不需要直接操作array,如此,就不會對其他使用array的開發人員操作影響了。看圖理解:

原型鏈的結構圖

每個例項物件都是由建構函式建立出來的

每乙個建構函式都有預設關聯的原型物件

原型物件本身也是物件,所以它也有自己的建構函式

原型物件的建構函式也有預設關聯的原型物件

以上就構成了一種鏈式訪問結構,稱之為原型鏈

下面畫出了person物件和array物件的原型鏈:

android 核心系列

編譯 1,需要jre1.6,64bit的機器。2,錯誤 this attribute must be localized 提示了錯誤 this attribute must be localized 這種問題一般情況是因為在res xml資料夾下的中 或者在res layout下的檔案中出現了沒有多...

JS 物件 JS原型 原型鏈

參考學習 js物件 構造器函式 建立物件的函式。物件分為普通物件和函式物件。所有物件都有 proto 屬性 函式物件不止有 proto 屬性,還有prototype屬性 稱為原型物件 1.new function 產生的物件都是函式物件。2.所有函式物件的 proto 都指向function.pro...

JS原型物件

原型prototype 將函式定義在全域性作用域中的缺點 1.會汙染全域性作用域的命名空間,如 函式functiona 那麼在全域性作用域中就不能再出現functiona這個命名了。2.定義在全域性作用域中不安全。因此,就用到了主角 原型 1.所有的函式都有原型物件 2.當函式以建構函式的形式呼叫時...