您好,登錄后才能下訂單哦!
小編這次要給大家分享的是如何使用JavaScript進(jìn)階(四)原型與原型鏈,文章內(nèi)容豐富,感興趣的小伙伴可以來(lái)了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。
一句話說(shuō)明什么是原型:原型就是一個(gè)JavaScript對(duì)象,原型能存儲(chǔ)我們的方法,構(gòu)造函數(shù)創(chuàng)建出來(lái)的實(shí)例對(duì)象能夠引用原型中的方法。
有如下代碼
function Foo(){ this.sayHello = function(){ } }
由于對(duì)象是調(diào)用new Foo()
所創(chuàng)建出來(lái)的,因此每一個(gè)對(duì)象在創(chuàng)建的時(shí)候,函數(shù) sayHello 都會(huì)唄創(chuàng)建一次
那么有沒(méi)一個(gè)對(duì)象都含有一個(gè)獨(dú)立的,不同的,但是功能邏輯一樣的函數(shù),比如:{} == {}
。
在代碼中方法就會(huì)消耗性能,最典型的資源就越是內(nèi)存
這里最好的方法就是將函數(shù)放在構(gòu)造函數(shù)之外,那么在構(gòu)造函數(shù)中引用該函數(shù)即可
function sayHello () {} function Foo () { this.say = sayHello; }
會(huì)在開(kāi)發(fā)中變得困難:引入框架危險(xiǎn),代碼繁冗不好維護(hù)。解決方法就是如果外面的函數(shù)不占用其名字,而且在函數(shù)名下。
每一個(gè)函數(shù)在定義的時(shí)候,有一個(gè)神秘對(duì)象(就是原型對(duì)象,暫且這么稱呼)被創(chuàng)建出來(lái)。
每一個(gè)由構(gòu)造函數(shù)創(chuàng)建的對(duì)象都會(huì)默認(rèn)的連接到該神秘對(duì)象上。
var f1 = new Foo(); var f2 = new Foo(); f1.sayHello(); //如果f1沒(méi)有sayHello那么就會(huì)在Foo.prototype中去找
由構(gòu)造函數(shù)創(chuàng)建出來(lái)的眾多對(duì)象共享一個(gè)對(duì)象就是:構(gòu)造函數(shù).prototype
只需要將共享的東西,重復(fù)會(huì)多占用內(nèi)存的東西放到構(gòu)造函數(shù).prototype
中,那么所有的對(duì)象就可以共享了。
function Foo(){} Foo.prototype.sayHello = function(){ console.log("…."); } var f1 = new Foo(); f1.sayHello(); var f2 = new Foo(); f2.sayHello(); console.log(f1.sayHello === f2.sayHello); // true
類class:在JS中就是構(gòu)造函數(shù)
實(shí)例(instance)與對(duì)象(object)
鍵值對(duì)與屬性和方法
父類與子類(基類和派生類)
在JavaScript中,原型也是一個(gè)對(duì)象,通過(guò)原型可以實(shí)現(xiàn)對(duì)象的屬性繼承,JavaScript的對(duì)象中都包含了一個(gè)[[Prototype]]
內(nèi)部屬性,這個(gè)屬性所對(duì)應(yīng)的就是該對(duì)象的原型。
[[Prototype]]作為對(duì)象的內(nèi)部屬性,是不能被直接訪問(wèn)的。所以為了方便查看一個(gè)對(duì)象的原型,F(xiàn)irefox和Chrome中提供了__proto__
這個(gè)非標(biāo)準(zhǔn)(不是所有瀏覽器都支持)的訪問(wèn)器(ECMA引入了標(biāo)準(zhǔn)對(duì)象原型訪問(wèn)器"Object.getPrototype(object)")。
下面通過(guò)一個(gè)例子來(lái)看看原型相關(guān)概念:
function Person() {} // 神秘對(duì)象就是Person.prototype //那么只有使用構(gòu)造函數(shù)才可以訪問(wèn)它 var o = new Person(); //以前不能直接使用o來(lái)訪問(wèn)神秘對(duì)象 //現(xiàn)在有了__proto__后, o.__proto__也可以直接訪問(wèn)神秘對(duì)象 //那么o.__proto__ === Person.prototype
神秘對(duì)象(原型)中都有一個(gè)屬性constructor
,翻譯為 構(gòu)造器 。表示該原型是與什么構(gòu)造函數(shù)聯(lián)系起來(lái)的。
__proto__
有什么用?可以訪問(wèn)原型。由于在開(kāi)發(fā)中除非特殊要求,不要使用實(shí)例去修改原型的成員,因此該屬性開(kāi)發(fā)時(shí)使用較少。但是在調(diào)試過(guò)程中非常方便,可以輕易的訪問(wèn)原型進(jìn)行查看成員
如果在早期的瀏覽器中使用實(shí)例需要訪問(wèn)原型如何處理?可以使用實(shí)例對(duì)象訪問(wèn)構(gòu)造器,然后使用構(gòu)造器訪問(wèn)原型
var o = new Person(); o.constructor.prototype
如果給實(shí)例繼承自原型的屬性賦值
function Foo(); Foo.prototype.name = "test"; var o1 = new Foo(); var o2 = new Foo(); o1.name = "張三"; // 不是修改原型中的name而是自己增加了一個(gè)name屬性 console.log(o1.name + ','+ o2.name); // 張三,test
對(duì)于如下代碼:
function Person(){} var p = new Person() console.log(Person.prototype.constructor); //function Person(){} console.log(Person.prototype.constructor.name); //Person console.log(typeof Person.prototype.constructor); //function console.log(p.__prop__); console.log(p.__prop__ === Person.prototype);//true
于是他們的關(guān)系圖如下:
凡是對(duì)象就有原型,原型也是對(duì)象。因此凡是給定一個(gè)對(duì)象,那么就可以找到他的原型,原型還有原型,那么如此下去,就構(gòu)成一個(gè)對(duì)象的序列,稱該結(jié)構(gòu)為原型鏈。
問(wèn)題:
凡是使用構(gòu)造函數(shù),創(chuàng)建出對(duì)象,并且沒(méi)有利用賦值的方式修改原型,就說(shuō)該對(duì)象保留默認(rèn)的原型鏈。
默認(rèn)原型鏈結(jié)構(gòu)是什么樣子呢?
function Person(){} var p = new Person(); //p 具有默認(rèn)的原型鏈
默認(rèn)的原型鏈結(jié)構(gòu)就是:當(dāng)前對(duì)象 -> 構(gòu)造函數(shù).prototype -> Object.prototype -> null
在實(shí)現(xiàn)繼承的時(shí)候,有時(shí)候會(huì)利用替換原型鏈結(jié)構(gòu)的方式實(shí)現(xiàn)原型繼承,那么原型鏈結(jié)構(gòu)就會(huì)發(fā)送改變
function DunizbCollection(){} DunizbCollection.prototype = []; var arr = new DunizbCollection(); // arr -> [] -> Array.prototype -> Object.prototype -> null
在JS中使用Function可以實(shí)例化函數(shù)對(duì)象 。也就是說(shuō)在JS中函數(shù)與普通對(duì)象一樣,也是一個(gè)對(duì)象類型。函數(shù)是JS中的一等公民。
要解決的問(wèn)題
語(yǔ)法
new Function( arg0,arg1,arg1,….argN, body );
Function 中的參數(shù)全部是字符串
該構(gòu)造函數(shù)的作用是將參數(shù)鏈接起來(lái)組成函數(shù)
舉例:創(chuàng)建一個(gè)打印一句話的函數(shù)
// 傳統(tǒng)的 function foo () { console.log( '你好' ); } //Function var func = new Function( 'console.log( "你好" );' ); // 功能上,這里foo 與 func 等價(jià)
再比如,創(chuàng)建一個(gè)空函數(shù)
//傳統(tǒng) function foo () {} //Function var func = new Function(); func();
傳入函數(shù)內(nèi)一個(gè)數(shù)字,打印該函數(shù)
//傳統(tǒng) function foo ( num ) { console.log( num ); } //Function var func = new Function( "num" ,"console.log( num )" ); func();
任意的一個(gè)函數(shù),都是相當(dāng)于Function的實(shí)例,類似于{}與new Object()的關(guān)系。
function foo () {}
上面的代告訴解析器,有一個(gè)對(duì)象叫foo,它是一個(gè)函數(shù);相當(dāng)于new Function()
得到一個(gè)函數(shù)對(duì)象
__proto__
對(duì)于Function,我們還必須知道
Object作為對(duì)象是繼承自Function.prototype的,又“Function.prototype”繼承自O(shè)bject.prototype
foo.prototype.__proto__ === Object.prototype // true
下面繪制出 Function 的構(gòu)造原型實(shí)例三角形結(jié)構(gòu)
Function是使用字符串構(gòu)建函數(shù),那么就可以在程序運(yùn)行過(guò)程中構(gòu)建函數(shù).
以前的函數(shù)必須一開(kāi)始就寫(xiě)好,再經(jīng)過(guò)預(yù)解析,一步一步的運(yùn)行
假定從服務(wù)器里拿到“[1,2,3,4,5]”,將數(shù)組形式的字符串轉(zhuǎn)換成數(shù)組對(duì)象
var arr = ( new Function( 'return ' + str + ' ;' ) )();
看完這篇關(guān)于如何使用JavaScript進(jìn)階(四)原型與原型鏈的文章,如果覺(jué)得文章內(nèi)容寫(xiě)得不錯(cuò)的話,可以把它分享出去給更多人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。