摘要:系列文章原型鏈原型鏈函數對象和普通對象中,萬物皆對象。原型對象在中,每當定義一個對象,對象中都會有一些預定義的屬性。參考文章原型與原型鏈終極詳解附自己理解的原文章中的內存分析圖
系列文章:
js原型鏈1
js原型鏈2
js中,萬物皆對象。對象分為函數對象和普通對象。記住Object和Function是js自帶的函數對象。
console.log(typeof Object); //function console.log(typeof Function); //function
函數對象是function;普通對象是object。下面看常用的幾種生成對象的方法:
var o1 = {}; var o2 = new Object; var o3 = new Object(); var o4 = new Object(undefined); var o5 = new Object(null); var o6 = Object.create(Object.prototype); var o7 = Object.create(null); console.log(typeof o1); // object console.log(typeof o2); // object console.log(typeof o3); // object console.log(typeof o4); // object console.log(typeof o5); // object console.log(typeof o6); // object console.log(typeof o7); // object function f1(){}; var f2 = function(){}; var f3 = new Function("str","console.log(str)"); console.log(typeof f1);// function console.log(typeof f2);// function console.log(typeof f3);// function var o8 = new f1(); console.log(typeof o8);// object
記住,凡是通過new Function()或function關鍵字創建的對象都是函數對象,其他是普通對象。Object和Function也都是通過new Function()創建的。
2. 原型對象在js中,每當定義一個對象,對象中都會有一些預定義的屬性。其中函數對象的一個屬性就是原型對象prototype;普通對象沒有prototype,但有__proto__屬性。打印o1-o8發現,除了o7其他都一樣。
o7: Object{No Properties} 其他: Object{__proto__: Object}
而f1-f3卻都不一樣。
f1: function f1(){} f2: function (){} // 匿名函數 f3: function anonymous(str/**/) { // anonymous意思是匿名 console.log(str) }
發現打印不出prototype,我們直接打印prototype試試:
console.log(typeof f1.prototype);console.log(f1.prototype); 結果如下: object Object{constructor: f1(), __proto__: Object} console.log(typeof f2.prototype);console.log(f2.prototype); 結果如下: object Object{constructor: (),__proto__: Object} console.log(typeof f3.prototype);console.log(f3.prototype); 結果如下: object Object{constructor:anonymous(str/**/),__proto__:Object}
再打印Object.prototype和Functjion.prototype試試
console.log(typeof Object.prototype);console.log(Object.prototype); 結果如下: object Object{ __defineGetter__:__defineGetter__() __defineSetter__:__defineSetter__() __lookupGetter__:__lookupGetter__() __lookupSetter__:__lookupSetter__() constructor:Object() hasOwnProperty:hasOwnProperty() isPrototypeOf:isPrototypeOf() propertyIsEnumerable:propertyIsEnumerable() toLocaleString:toLocaleString() toString:toString() valueOf:valueOf() get __proto__:__proto__() set __proto__:__proto__() } console.log(typeof Function.prototype);console.log(Function.prototype); 結果如下: function function () {}3. 原型對象的作用
var person = function(name){ this.name = name }; person.prototype.getName = function(){ return this.name; } var zzz = new person("zzz"); console.log(zzz.getName()); // zzz
原型鏈中增加一個函數,他的實例就可以直接使用這個函數了。
4. 原理js在創建對象的時候都有一個__proto__屬性,指向創建它的函數的prototype屬性。
1. console.log(zzz.__proto__ == person.prototype);// true 2. console.log(person.__proto__ == Function.prototype);// true 3. console.log(person.prototype.__proto__ == Object.prototype);// true 4. console.log(Object.__proto__ == Function.prototype);// true 5. console.log(Function.__proto__ == Function.prototype);//true 6. console.log(Function.prototype.__proto__ == Object.prototype);//true
分析1:zzz是person創建的,所以person.__proto__指向person.prototype.
分析2:person是Function創建的,所以person.__proto__指向Function.prototype.
分析3:person.prototype是個對象,是Object創建的。
分析4:Object是Function創建的。
分析5:Function也是自己創建的,比較特殊。
分析6:Function的prototype是對象,Object創建的。
總結:
1. 有prototype都是object,所以所有prototype的__proto__都指向Object的prototype。 2. Object的prototype的__prototype__特殊,指向null. 3. Function的__proto__也比較特殊,指向自己的prototype.
圖解如下:
另外,原型對象prototype中都有一個constructor屬性,用來引用他的函數對象,即。
person.prototype.constructor === person;// true5. 參考文章
JS原型與原型鏈終極詳解
附自己理解的原文章中的內存分析圖:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81641.html
摘要:原型鏈和對象的原型是對象實例和它的構造函數之間建立的鏈接,它的值是構造函數的。對象的原型根據上文提到的構造調用函數的時候會創建一個新對象,自動將的原型指向構造函數的對象。 showImg(https://segmentfault.com/img/remote/1460000020185197); JS的原型、原型鏈一直是比較難理解的內容,不少初學者甚至有一定經驗的老鳥都不一定能完全說清...
摘要:相當于在用原型繼承編寫復雜代碼前理解原型繼承模型十分重要。同時,還要清楚代碼中原型鏈的長度,并在必要時結束原型鏈,以避免可能存在的性能問題。 js是一門動態語言,js沒有類的概念,ES6 新增了class 關鍵字,但只是語法糖,JavaScript 仍舊是基于原型。 至于繼承,js的繼承與java這種傳統的繼承不一樣.js是基于原型鏈的繼承. 在javascript里面,每個對象都有一...
摘要:圖片描述缺點是無法實現多繼承可以在構造函數中,為實例添加實例屬性。 對象的方法 Object.assign() 對象可以簡寫 ,如果 key 和 value 相等則可以簡寫 let name = xm; let age = 2; let obj = { name, age, fn(){ // 可以省略函數關鍵字和冒號: console.log(2...
摘要:從實現角度分析原型鏈歡迎來我的博客閱讀從實現角度分析原型鏈網上介紹原型鏈的優質文章已經有很多了,比如說作為補充,就讓我們換個角度,從實現來分析一下吧本文假設你對原型鏈已經有所了解。 從實現角度分析js原型鏈 歡迎來我的博客閱讀:《從實現角度分析js原型鏈》 網上介紹原型鏈的優質文章已經有很多了,比如說: https://github.com/mqyqingfeng/Blog/issu...
摘要:構造函數,實例,原型三者的關系如下圖構造函數是構成整個原型鏈的關鍵,是他利用將原型傳給了后代。因此,通過操縱構造函數的,就能夠操縱原型鏈,從而對原型鏈進行自在的拼接。 要理解js的原型鏈主要就是理清楚以下三者的關系: 構造函數的protitype屬性 對象的__proto__屬性 對象的constructor屬性 在js中,函數作為一等公民,它是一個對象,可以擁有自己的屬性,可...
摘要:給添加屬性給的原型對象添加屬性原型鏈在中,每個對象都有一個屬性,其保存著的地址就構成了對象的原型鏈。實例變量實例函數原型鏈繼承有了原型鏈,就可以借助原型鏈實現繼承。是中唯一一個處理屬性但是不查找原型鏈的函數。 前端學習:教程&開發模塊化/規范化/工程化/優化&工具/調試&值得關注的博客/Git&面試-前端資源匯總 歡迎提issues斧正:原型&原型鏈&原型繼承 JavaScript-原...
閱讀 642·2021-11-25 09:43
閱讀 1655·2021-11-18 10:02
閱讀 1033·2021-10-15 09:39
閱讀 1877·2021-10-12 10:18
閱讀 2115·2021-09-22 15:43
閱讀 756·2021-09-22 15:10
閱讀 2084·2019-08-30 15:53
閱讀 978·2019-08-30 13:00