摘要:可以看出,這個查找過程是一個鏈式的查找,每個對象都有一個到它自身原型對象的鏈接,這些鏈接組件的整個鏈條就是原型鏈。原型的構建字面量方式當通過字面量方式創建對象時,它的原型就是。
面向對象
JavaScript沒有類(class)的概念的(ES6 中的class也只不過是語法糖,并非真正意義上的類),而在JavaScript中,在 JavaScript 中,除了 String, Number, Boolean Undefined, Null, Symbol 這 6 種基本類型外,其他所有數據都是 Object 類型。
在基于類的傳統面向對象的編程語言中,對象由類實例化而來,實例化的過程中,類的屬性和方法會拷貝到這個對象中;對象的繼承實際上是類的繼承,在定義子類繼承于父類時,子類會將父類的屬性和方法拷貝到自身當中。因此,這類語言中,對象創建和繼承行為都是通過拷貝完成的。但在JavaScript中,對象的創建、對象的繼承是不存在拷貝行為的。
原型和原型鏈原型是為了共享多個對象之間的一些共有特性(屬性或方法),這個功能也是任何一門面向對象的編程語言必須具備的。A、B兩個對象的原型相同,那么它們必然有一些相同的特征。
JavaScript中的對象,都有一個內置屬性[Prototype],指向這個對象的原型對象。當查找一個屬性或方法時,如果在當前對象中找不到定義,會繼續在當前對象的原型對象中查找;如果原型對象中依然沒有找到,會繼續在原型對象的原型中查找;如此繼續,直到找到為止,或者查找到最頂層的原型對象中也沒有找到(Object.prototype),就結束查找,返回undefined。可以看出,這個查找過程是一個鏈式的查找,每個對象都有一個到它自身原型對象的鏈接,這些鏈接組件的整個鏈條就是原型鏈。
原型的構建 字面量方式Object.prototype: 最頂層的原型對象,這個對象中保存了最常用的方法,如toString、valueOf、hasOwnProperty等,因此我們才能在任何對象中使用這些方法。
當通過字面量方式創建對象時,它的原型就是Object.prototype。雖然我們無法直接訪問內置屬性[[Prototype]],但我們可以通過Object.getPrototypeOf()或對象的__proto__獲取對象的原型。
let obj = {}; Object.getPrototypeOf(obj) === Object.prototype; // true (obj).__proto__ === Object.prototype; // true函數的構造調用
通過函數的構造調用(注意,我們不把它叫做構造函數,因為JavaScript中同樣沒有構造函數的概念,所有的函數都是平等的,只不過用來創建對象時,函數的調用方式不同而已)也是一種常用的創建對象的方式。基于同一個函數創建出來的對象,理應可以共享一些相同的屬性或方法,但這些屬性或方法如果放在Object.prototype里,那么所有的對象都可以使用它們了,作用域太大,顯然不合適。于是,JavaScript在定義一個函數時,同時為這個函數定義了一個 默認的prototype屬性,所有共享的屬性或方法,都放到這個屬性所指向的對象中。由此看出,?通過一個函數的構造調用創建的對象,它的原型就是這個函數的prototype指向的對象。
let f = function(name) { this.name = name }; f.prototype.getName = function() { return this.name; }; let obj = new f("123"); obj.getName(); // 123 obj.__proto__ === f.prototype; // trueObject.create()
第三種常用的創建對象的方式是使用Object.create()。?這個方法會以你傳入的對象作為創建出來的對象的原型。
let obj = {}; let obj2 = Object.create(obj); obj2.__proto__ === obj; // true
這種方式還可以模擬對象的“繼承”行為。
function Foo(name) { this.name = name; } Foo.prototype.myName = function() { return this.name; }; function Bar (name,label) { Foo.call( this, name ); // this.label = label; } let temp = Object.create( Foo.prototype ); Bar.prototype = temp; Bar.prototype.myLabel = function() { return this.label; }; let a = new Bar( "a", "obj a" ); a.myName(); // "a" a.myLabel(); // "obj a" a.__proto__.__proto__ === Foo.prototype; //true?__proto__和prototype
__proto__指向當前對象的原型,prototype是函數才具有的屬性,默認情況下,new 一個函數創建出的對象,其原型都指向這個函數的prototype屬性。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84862.html
摘要:給添加屬性給的原型對象添加屬性原型鏈在中,每個對象都有一個屬性,其保存著的地址就構成了對象的原型鏈。實例變量實例函數原型鏈繼承有了原型鏈,就可以借助原型鏈實現繼承。是中唯一一個處理屬性但是不查找原型鏈的函數。 前端學習:教程&開發模塊化/規范化/工程化/優化&工具/調試&值得關注的博客/Git&面試-前端資源匯總 歡迎提issues斧正:原型&原型鏈&原型繼承 JavaScript-原...
摘要:基礎原型原型鏈構造函數默認有這一行張三李四構造函數擴展其實是的語法糖其實是的語法糖其實是使用判斷一個函數是否是一個變量的構造函數原型規則和示例所有的引用類型數組對象函數,都具有對象屬性即可自有擴展的屬性,除外所有的引用類型數組對象函數, JavaScript基礎 —— 原型&&原型鏈 構造函數 function Foo(name, age) { this.name = na...
我們在學習javascript時,經常會聽到萬物皆對象,但是呢,其實萬物皆對象的對象也有區別。分為普通對象和函數對象。1.對象分為函數對象和普通對象? ??通過new Function()創建的對象都是函數對象,其他的都是普通對象。showImg(https://segmentfault.com/img/bVbtWre?w=526&h=252); 2.構造函數而提到new關鍵字,我們不得不提到構造...
摘要:然而事實上并不是。函數本身也是一個對象,但是給這個對象添加屬性并不能影響。一圖勝千言作者給出的解決方案,沒有麻煩的,沒有虛偽的,沒有混淆視線的,原型鏈連接不再赤裸裸。所以是這樣的一個函數以為構造函數,為原型。 注意:本文章是個人《You Don’t Know JS》的讀書筆記。在看backbone源碼的時候看到這么一小段,看上去很小,其實忽略了也沒有太大理解的問題。但是不知道為什么,我...
摘要:而和的存在就是為了建立這種子類與父類間的聯系。創建一個基本對象建立新對象與原型我把它理解為類之間的連接執行構造函數小結可以理解為類,也就是存儲一類事物的基本信息。原型原型鏈和繼承之間的關系。 原型 原型的背景 首先,你應該知道javascript是一門面向對象語言。 是對象,就具有繼承性。 繼承性,就是子類自動共享父類的數據結構和方法機制。 而prototype 和 __proto__...
閱讀 1526·2023-04-26 00:20
閱讀 1121·2023-04-25 21:49
閱讀 803·2021-09-22 15:52
閱讀 577·2021-09-07 10:16
閱讀 972·2021-08-18 10:22
閱讀 2664·2019-08-30 14:07
閱讀 2237·2019-08-30 14:00
閱讀 2651·2019-08-30 13:00