js prototype深入理解及應(yīng)用實例分析
本文實例講述了js prototype深入理解及應(yīng)用。分享給大家供大家參考,具體如下:
上一篇講了js的prototype概念,在這里回顧一下prototype的定義:
prototype是函數(shù)的一個屬性,并且是函數(shù)的原型對象。引用它的必然是函數(shù),這個應(yīng)該記住。
但是,很奇怪,各位看官,你有沒有看過類似下面這樣引用prototype的js代碼:
function func(){ var args = Array.prototype.slice.call(arguments, 1); return args; }
咦???看著上面這行代碼,你是不是對prototype只是屬于函數(shù)產(chǎn)生深深的懷疑呢?
你明白上面那個函數(shù)的意思嗎?我還是解釋一下吧。
call是函數(shù)的一個方法,關(guān)于這個方法,它也是只有····函數(shù)····才能夠調(diào)用的,它的作用是:調(diào)用引用它的函數(shù)。
就拿這個Array.prototype.slice.call(arguments,1)來講,這里面包含太多信息了,我一個個分析一下。
slice(start[,end])是js的一個原生數(shù)組函數(shù),作用是獲取數(shù)組中從start下標開始到end下標結(jié)束的元素。舉個例子:
var arr1 = [2,3,'l',4,5,'j','i']; alert(arr1.slice(1));//結(jié)束下標省略表示從開始下標截取到末尾 //這里alert的是3,'l',4,5,'j','i',你自己可以試一下
arguments是js函數(shù)對象的一個屬性,作用是獲取函數(shù)的實參,返回的是一個以函數(shù)實參為屬性元素的對象。舉個例子:
function args(){ return this.arguments;//這里的this可以省略,你自己可以試一下 //我加上是為了說明,調(diào)用arguments的只能是對象 } alert(JSON.stringify(args(1,3,5,6,8))); //返回的是{"0":"1","1":"3","2":"5","3":"6","4":"8"}
關(guān)于函數(shù)的對象屬性arguments這里就講這么多了,要詳細理解,可以百度。
而Array是js中生成數(shù)組的關(guān)鍵字。
這里為什么要用Array.prototype來調(diào)用slice函數(shù)呢?而不用Array.slice,原因很簡單,因為數(shù)組的關(guān)鍵字Array不能這樣子Array.xx直接調(diào)用js的數(shù)組函數(shù)。但為什么不能直接這樣調(diào)用呢?不急,下面我們來做實驗,你就會很清楚了。
alert(Array.slice()); //Uncaught TypeError: Array.slice is not a function
這里直接給你報錯了,說明了什么?呵呵,這說明Array關(guān)鍵字確實不能直接調(diào)用數(shù)組的函數(shù)。
alert(JSON.stringify(Array.prototype)); alert(JSON.stringify(Array.prototype.slice()));
這里返回都是空數(shù)組···[]···,說明了什么?說明了Array關(guān)鍵字確實是可以調(diào)用prototype函數(shù)的屬性的,同時也說明js是可以這樣子Array.prototype調(diào)用js的數(shù)組函數(shù)的。
說到這里,問題就來了,我上面不是說,prototype是js函數(shù)的一個屬性,只能被函數(shù)調(diào)用嗎?怎么這里Array關(guān)鍵字可以調(diào)用這個屬性prototype呢?那么,我這不是坑自己對prototype的定義是錯誤的嗎?我這不是給自己打臉嗎?哎,看官,沒錯,你這里看到的都是正確的??墒牵劣贏rray關(guān)鍵字可以調(diào)用函數(shù)的prototype屬性,我有沒有給自己打臉,這里,我們先別急得下結(jié)論。
轉(zhuǎn)個彎說,看官是否還記得js生成數(shù)組的幾種方式?應(yīng)該有多種,但,我這里就不介紹了。
不過,你是否看過這樣生成數(shù)組的方式?我們先來看下面的代碼:
var arr = new Array();
這個方式生成數(shù)組還記得吧?那么,我們js的function是不是也可以像下面這樣子生成對象呢?
function func(){ } var obj = new func();
上面生成數(shù)組的方式和下面構(gòu)造函數(shù)生成對象的方式是不是很相似?沒錯,js中function和Array都是可以通過new來生成對象這樣的東西,這說明了什么呢?你看Array()和func()是不是很像?是不是最后面都有一對圓括號?是就對了,呵呵,說了這么多,我只是想揭露一樣?xùn)|西,這個東西就是,假如我猜的的沒有錯的話,Array()這個東西其實是js一個·····構(gòu)造數(shù)組的內(nèi)置函數(shù)····,不然,可以用new Array()的方式生存數(shù)組的方式就說不過去了是吧?
講到這里,我們再返回來說js可以這樣子Array.prototype調(diào)用prototype就很明白不過了是吧?Array()是js的一個內(nèi)置函數(shù),既然Array是一個函數(shù),那么Array肯定擁有prototype這個屬性對吧?所以說,Array關(guān)鍵字調(diào)用prototype并沒有違反prototype是函數(shù)的一個屬性這個原則,prototype是函數(shù)的一個屬性依然是一個不變的結(jié)論。
關(guān)于Array生成數(shù)組的方式,類似的我們是否可以這樣子new Object()生成對象,或者new String()這樣子生成字符串?既然可以這樣子構(gòu)造對象和字符串,那么我們下面的代碼也應(yīng)該是可行的,對吧?
alert(JSON.stringify(String.prototype)); alert(JSON.stringify(Object.prototype));
根據(jù)上面的解釋,你應(yīng)該知道這里是可以執(zhí)行的吧?你應(yīng)該知道這里的之所以能執(zhí)行的原理吧?你自己試試。這里就不再解釋了。
講到這里,哎,我既然把行文開始的那個函數(shù)給忘了?這里講解一下本文開始那個func函數(shù)的作用:
func函數(shù)的作用就是,從第二個實參數(shù)開始獲取func函數(shù)的實參。
我來給你分析一下:
function func(){ var args = Array.prototype.slice.call(arguments, 1); return args; } alert(func(0,1,2,3,4));//給func函數(shù)傳實參
Array.prototype是一個空數(shù)組,
Array.prototype.slice()的意思是一個空數(shù)組調(diào)用數(shù)組的函數(shù)slice(),
Array.prototype.slice.call()的意思是call函數(shù)調(diào)用數(shù)組的函數(shù)slice(),
這里call()怎么調(diào)用slice()呢?
是這樣子的,Arguments獲取func函數(shù)實參列表,生成一個對象傳遞給call()函數(shù),call函數(shù)又把Arguments生成的對象傳遞給Array.prototype這個空數(shù)組,把第二個參數(shù)···1···傳遞給slice函數(shù),然后,call就讓引用它的函數(shù)slice執(zhí)行slice(1),所以slice就從1下標開始獲取數(shù)組的元素了,而這個數(shù)組的元素其實就是Arguments的元素,因此,這個函數(shù)func的作用就是獲取下標為1開始的所有實參。不相信,你自己可以執(zhí)行一下上面的函數(shù)。
下面講講prototype的應(yīng)用:
應(yīng)用1:
給原型對象增加函數(shù),就是讓對象擁有公用的函數(shù)。
例子:我給數(shù)組原型對象增加一個打亂數(shù)組方法:
//給數(shù)組原型增加一個打亂數(shù)組的函數(shù) Array.prototype.shuffle=function(){ var value = this.valueOf(),len = this.length,temp,key; while(len--){ //隨機生成數(shù)組的下標 key = Math.floor(Math.random()*len); //temp為中間交換變量 temp = value[key]; value[key] = value[len]; value[len] = temp; } return value; } var arr1 = [0,1,2,3,4,5,6,7,8,9]; var arr2 = ['a','b','c','d','e','f']; alert(JSON.stringify(arr1.shuffle())); alert(JSON.stringify(arr2.shuffle()));
你可以嘗試著再增加一個數(shù)組arr3看看它能不能調(diào)用shuffle函數(shù),因為我這里是給Array的原型對象增加的函數(shù),所以在這個腳本內(nèi),所有數(shù)組都擁有shuffle這個函數(shù)。
應(yīng)用2:
給原型對象增加屬性,也就是給對象增加公用的屬性
例子:
function fun(){ } fun.prototype.name = '小東'; fun.prototype.arr = [1,2,3,4];//這里的屬性可以是數(shù)組,也可以是對象 var ob1 = new fun(); var ob2 = new fun(); alert(JSON.stringify(ob1.name)); alert(JSON.stringify(ob2.arr));
應(yīng)用3:
實現(xiàn)原型繼承;
function P1(){ } function P2(){ } //原型對象增加屬性和方法 P2.prototype.name = 'P2"s name'; P2.prototype.get=function(value){ return value; } //實例化P2構(gòu)造函數(shù)的一個對象 var obp2 = new P2();//這個對象應(yīng)該包含所有原型對象的屬性和方法 //給P1的原型對象賦值一個對象,相當于P1繼承了obp2的所有屬性和方法 P1.prototype = obp2;//這個式子,簡單來講就類似于a = b, b賦值給a這個總該明白吧? //調(diào)用P1從obp2繼承過來的get函數(shù) alert(P1.prototype.get('out"s name')); //展示P1從obp2繼承過來的name屬性 alert(P1.prototype.name); //用構(gòu)造函數(shù)P1實例化一個obp1對象 var obp1 = new P1(); //P1的原型對象prototype既然已經(jīng)繼承了obp2的所有屬性和函數(shù),那么依據(jù)P1所實例化出來的對象也都有obp2的屬性和函數(shù)了 alert(obp1.get('obp1"s name'));
關(guān)于prototype就講到這里,假如本文有什么錯誤,還望各位看官指出,我好糾正。
特別指出:
- Array.prototype是一個數(shù)組
- String.prototype是一個字符串
- Object.prototype是一個對象
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)》
希望本文所述對大家JavaScript程序設(shè)計有所幫助。
- javascript 對象 與 prototype 原型用法實例分析
- 深入理解javascript prototype的相關(guān)知識
- js中的hasOwnProperty和isPrototypeOf方法使用實例
- JavaScript prototype 使用介紹
- js中prototype用法詳細介紹
- 詳解Javascript中prototype屬性(推薦)
- JS 面向?qū)ο笾衿娴膒rototype
- JS面向?qū)ο?、prototype、call()、apply()
- 深入了解javascript中的prototype與繼承
- javascript prototype的深度探索不是原型繼承那么簡單
- Javascript中的Prototype到底是什么
相關(guān)文章
利用原生JS與jQuery實現(xiàn)數(shù)字線性變化的動畫
最近在工作中遇到一個需要,需要將數(shù)字實現(xiàn)遞增的動態(tài)顯示,從網(wǎng)上找了相關(guān)的資料發(fā)現(xiàn)利用原生JS與jQuery都可以實現(xiàn),suoyi8下面這篇文章主要給大家介紹了利用原生JS與jQuery實現(xiàn)數(shù)字線性變化動畫的相關(guān)資料,需要的朋友可以參考下。2017-02-02js數(shù)組常用操作方法小結(jié)(增加,刪除,合并,分割等)
這篇文章主要介紹了js數(shù)組常用操作方法,結(jié)合實例總結(jié)了javascript數(shù)組的增加、刪除、合并、分割等操作技巧,需要的朋友可以參考下2016-08-08jquery中l(wèi)ive()方法和bind()方法區(qū)別分析
這篇文章主要介紹了jquery中l(wèi)ive()方法和bind()方法區(qū)別,結(jié)合實例形式簡單分析了live()方法和bind()方法的功能、使用方法與用法區(qū)別,需要的朋友可以參考下2016-06-06淺談js函數(shù)三種定義方式 & 四種調(diào)用方式 & 調(diào)用順序
下面小編就為大家?guī)硪黄獪\談js函數(shù)三種定義方式 & 四種調(diào)用方式 & 調(diào)用順序。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02詳解如何讓InstantClick兼容MathJax、百度統(tǒng)計等
本篇文章主要介紹了如何讓InstantClick兼容MathJax、百度統(tǒng)計等,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09