摘要:我們畫張圖來表示圖中這條紅色的線就是原型鏈。我們把方法放到實例的原型對象上面,也就是上面來供所有實例使用小明小紅用圖表示補充說一下我的經歷,一開始理解原型鏈時,一直在在這個三個屬性中繞來繞去。
一直以來對于JavaScript 的原型鏈的概念,始終有些東西有一種模糊感,最近剛好有時間就塌下心認真的把《JavaScript高級程序設計》中相關內容認真讀了一遍,也查看了很多網上很多資料,以前很多不明白的地方也漸漸明白了起來。
寫一篇文章記錄一下最近學習的感悟。
我們通常創建一個對象無非就兩種方式:
1. var obj= new Object();//new 一個Object的實例 2. var obj= {};//對象字面量
使用對象字面量 和使用new的方式是一樣的。
為了簡便,一般推薦使用使用字面量:var o= {};
當我們想要創建自定義的對象時,需要用到構造函數。
構造函數和普通函數有兩個區別:
1. 便于和普通函數區分,函數名首字母大寫。 2. 使用 `new` 操作符調用,返回一個實例對象。
除此之外和普通函數一摸一樣。
我們使用構造函數Person來創建兩個實例對象:
function Person(name){ this.name = name; this.sayName= function (){ alert(this.name) } } var person1 = new Person("小明"); var person2 = new Person("小紅"); console.log(person1);//{name: "小明", sayName: fun} console.log(person2);//{name: "小紅", sayName: fun}
上面的例子不難理解,雖然這兩個實例對象都有sayName方法,而且他們兩個的作用也是一樣的,但卻是兩個方法,只是名字和作用一樣。
畫個圖表示一下:
如果還不明白,我在打個比喻:
就像A街上有一間麥當勞,在B街上也開了一間麥當勞,它們都叫麥當勞,作用也是一樣的。但是你總不能說他們是一間麥當勞吧?
person1.sayName === person2.sayName;//false
如果這樣的話,我們每構造出來一個對象,都要多帶帶為這個對象創建出一個專屬于它自己使用的sayName,這是很占用內存的。
那我們能不能讓所有的實例對象都共同使用一個sayName方法,來節省內存,提升效率呢?這需要我們先理解原型對象的概念。
原型對象我們先了解原型對象的概念。
每個對象都有原型對象(null除外),我們用__proto__表示,每個函數都有prototype屬性,指向實例的原型對象。
對照這句話,按照我們上面的例子,也就是說Person.prototype指向person1的原型對象(__proto__),
Person.prototype === person1.__proto__; // true
為了便于理解,來看一張圖。
恩~他們的關系大概就是這樣。
原型鏈原型鏈簡單用一句話概括就是:
原型鏈就是 對象的__proto__所連接的鏈狀結構
為了方便我們理解原型鏈,舉一個簡單的例子:
function F(){ this.a = 1; this.b = 2; } F.prototype.b = 3; F.prototype.c = 4; var o = new F();// {a: 1, b: 2} //原型鏈: //o --> o.__proto__ --> o.__proto__.__proto__ --> null // 其中的 --> 就表示 __proto__ 也就是原型鏈 console.log(o.a); // 1 // o上有a這個屬性嗎?有的,該屬性的值為1 console.log(o.b); // 2 // o上有b這個屬性嗎?有的,該屬性的值為2 // 原型上也有一個"b"屬性,但是它不會被訪問到.這種情況稱為"屬性遮蔽 " console.log(o.c); // 4 // o上有c這個屬性嗎?沒有,那看看原型上有沒有 // o.__proto__上有c這個屬性嗎?有的,該屬性的值為4 console.log(o.d); // undefined // o上有d這個屬性嗎?沒有,那看看原型上有沒有 // o.__proto__ 上有d這個屬性嗎?沒有,那看看它的原型上有沒有 // o.__proto__.__proto__ 為 null,停止搜索 // 沒有找到d屬性,返回undefined。
我們畫張圖來表示:
圖中這條紅色的線就是原型鏈。
由此可見,實例對象可訪問自己原型對象上的屬性和方法,額..準確來說是:
當一個對象 查找屬性或方法時,自己有,停止查找,返回結果。
自己沒有,順著__proto__一直向上查找,如找到,停止查找,返回結果。
如果一直找到了原型鏈的最頂端(null),還沒有找到,返回undefined。
我們先回顧一下那個sayName的問題:
怎么讓所有的實例對象都是用一個sayName方法呢。
現在我們可以使用原型對象來解決這個問題了。
我們把sayName方法放到實例的原型對象上面,也就是Person.prototype上面來供所有實例使用:
function Person(name){ this.name = name; } Person.prototype.sayName=function (){ alert(this.name); } var person1 = new Person("小明"); var person2 = new Person("小紅"); person1.sayName === person2.sayName;//true
用圖表示:
constructor
說一下我的經歷,一開始理解原型鏈時,一直在prototype、__proto__、constructor在這個三個屬性中繞來繞去。
為了便于理解,我把constructor放在最后了。
constructor字面意思就很容易理解,構造函數的意思。
一句話解釋:
每個原型對象都有一個 constructor 屬性指向 關聯的構造函數。
還是上面那個例子:
console.log(Person.prototype.constructor);//Person(){ fun }
需要注意的一點是,實例對象上沒有constructor屬性。
但是:
console.log(person1.constructor) ;//Person(){ fun }
得出這個結果很簡單:
實例上查找不到constructor屬性 --> 順著__proto__在原型對象上找 --> 找到并返回。
Object.prototype
剛才我們說了創建對象的兩種方式:字面量創建對象和使用new操作符創建對象。
這兩種方式創建出來的對象都會繼承Object.prototyoe上的方法。
比如,我們使用字面量新創建一個對象o:
var o = {value: 1}; o.toString();//"[object Object]" //查找過程: o --> o.__proto__ 找到返回 o.__proto__ === Object.prototype;//true
o這個的對象本身并沒有toString這個方法,但它卻可以使用toString方法。
因為它繼承了Object.prototyoe上的toString的方法。
null
既然對象都會繼承自Object.prototype上面的方法,那它自己的原型又是什么呢。答案是null
Object.prototype.__prototype__ === null;//true
以上僅自己學習所得,如有不當之處 望指出。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101194.html
摘要:一些額外的全局函數命名空間對象接口和構造函數與沒有典型的關聯,但卻是有效的。最后有幾點需要說明的是每個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。 文章來源:小青年原創發布時間:2016-07-03關鍵詞:JavaScript,原型鏈,jQuery類庫轉載需標注本文原始地址: http://zhaomenghuan.githu...
摘要:只是構造函數上的一個屬性,它是一個指針,指向原型對象,并不表示就是原型對象。在上一個例子中,就是一個對象,這個對象可以說是原生構造函數的實例,所以也是一個對象,所以它也有屬性,不過它的指向也就是原型鏈的頂端,再往上就沒有了。 上一篇講了①原型對象是什么;②__proto__、prototype、constructor的關系;③原型對象的作用;④原型對象帶來的一些需要注意的問題; 沒理解...
摘要:也就是說這個外部函數的作用域就是閉包本身。無論通過何種手段直接或間接將內部函數傳遞到所在的詞法作用域以外,它都會持有對原始定義作用域的引用,無論在何處執行這個函數都會使用閉包。 以下是個人對這三個老大難的總結(最近一直在學習原生JS,翻了不少書,不少文檔,雖然還是新手,但我會繼續堅持走我自己的路) 原型鏈 所有對象都是基于Object.prototype,Object.prototyp...
摘要:為什么要學習設計模式做事情之前問個為什么總是好的。設計模式的使用方法關于使用方式,像我這種初學者最容易犯的錯誤就是生搬硬套,但是模仿本來也是學習的一個過程,最重要的事情是在模仿中要學會思考。 為什么要學習設計模式? 做事情之前問個為什么總是好的。關于設計模式的好壞,我在知乎上也看過一些討論,有知友對其提出過一些疑問,里面有一些關于設計模式的觀點: 設計模式有何不妥,所謂的荼毒體現在哪...
閱讀 2444·2021-11-19 09:59
閱讀 1973·2019-08-30 15:55
閱讀 930·2019-08-29 13:30
閱讀 1330·2019-08-26 10:18
閱讀 3081·2019-08-23 18:36
閱讀 2382·2019-08-23 18:25
閱讀 1156·2019-08-23 18:07
閱讀 430·2019-08-23 17:15