之一------(函數(shù)的劫持與對象的復(fù)制)
關(guān)于對象的繼承,一般的做法是用復(fù)制法: Object.extend?
見protpotype.js 的實(shí)現(xiàn)方法:
Object.extend = function(destination, source) ...{?
for (property in source) ...{?
destination[property] = source[property];?
}?
return destination;?
}?
除此以外嘴纺,還有一種不太常見的方法:? Function.apply.?
apply 方法能劫持(<> 書中用到"劫持"一語几睛,很生動啊)另外一個(gè)對象的方法房轿,?
繼承另外一個(gè)對象的屬性。?
示范代碼如下:?
Apply示范代碼
function Person(name,age)...{?? //定義一個(gè)類所森,人類?
this.name=name???? //名字?
this.age=age?????? //年齡?
this.sayhello=function()...{alert("hello")}?
}?
function Print()...{??????????? //顯示類的屬性?
this.funcName="Print"?
this.show=function()...{?
var msg=[]?
for(var key in this)...{?
if (typeof(this[key])!="function") msg.push([key,":",this[key]].join(""))?
}?
alert(msg.join(" "))?
}?
}?
function Student(name,age,grade,school)...{??? //學(xué)生類?
Person.apply(this,arguments)?
Print.apply(this,arguments)?
this.grade=grade????????????????? //年級?
this.school=school??????????????????? //學(xué)校?
}?
var p1=new Person("jake",10)?
p1.sayhello()?
var s1=new Student("tom",13,6,"清華小學(xué)")?
s1.show()?
s1.sayhello()?
alert(s1.funcName)?
學(xué)生類本來不具備任何方法囱持,但是在 Person.apply(this,arguments)? 后,他就具備了 Person類的sayhello方法和 所有屬性焕济。? 在 Print.apply(this,arguments) 后就自動得到了? show() 方法纷妆。
本文,作為拋磚引玉晴弃,只對 apply 的用法(在對象繼承和函數(shù)劫持方面)做個(gè)小示范掩幢,其他更深入的應(yīng)用要?
靠大家慢慢去領(lǐng)會了。
之二------利用Apply的參數(shù)數(shù)組化來提高
我們再來聊聊Function.apply() 在提升程序性能方面的技巧上鞠。
我們先從 Math.max() 函數(shù)說起际邻,? Math.max后面可以接任意個(gè)參數(shù),最后返回所有參數(shù)中的最大值芍阎。
比如?
alert(Math.max(5,8))?? //8
alert(Math.max(5,7,9,3,1,6))?? //9
但是在很多情況下世曾,我們需要找出數(shù)組中最大的元素。
var arr=[5,7,9,1]
alert(Math.max(arr))??? //?? 這樣卻是不行的谴咸。一定要這樣寫
function getMax(arr){
var arrLen=arr.length;
for(var i=0,ret=arr[0];i
ret=Math.max(ret,arr[i]);?
}
return ret;
}
這樣寫麻煩而且低效轮听。如果用 apply呢,看代碼:
function getMax2(arr){
return Math.max.apply(null,arr)
}
兩段代碼達(dá)到了同樣的目的寿冕,但是getMax2卻優(yōu)雅蕊程,高效,簡潔得多驼唱。
看性能測試:
getMax性能測試
var myArr=new Array()
function fillRnd(arrLen){? //填入 arrLen個(gè)1-10的隨機(jī)數(shù)字到數(shù)組
for(var i=0,arr=[];i
arr[i]=Math.ceil(Math.random()*10)
}
return arr
}
function getMax(arr){
var arrLen=arr.length;
for(var i=0,ret=arr[0];i
ret=Math.max(ret,arr[i]);?
}
return ret;
}
function getMax2(arr){
return Math.max.apply(null,arr)
}
myArr=fillRnd(20*10000)? //生成20萬個(gè)隨機(jī)數(shù)填到數(shù)組
var t1=new Date()
var max1=getMax(myArr)
var t2=new Date()
var max2=getMax2(myArr)
var t3=new Date()
if (max1!==max2) alert("error")
alert([t3-t2,t2-t1])?? //在我機(jī)器上 96,464 .不同的機(jī)器,結(jié)果可能有差異
通過20萬個(gè)數(shù)據(jù)的比較藻茂, getMax2 時(shí)間為 96ms 而 getmax時(shí)間為464。 兩者相差5倍
再比如數(shù)組的push方法。
var arr1=[1,3,4];
var arr2=[3,4,5];
如果我們要把 arr2展開辨赐,然后一個(gè)一個(gè)追加到 arr1中去优俘,最后讓? arr1=[1,3,4,3,4,5]
arr1.push(arr2)? 顯然是不行的。 因?yàn)檫@樣做會得到? [1,3,4, [3,4,5] ]
我們只能用一個(gè)循環(huán)去一個(gè)一個(gè)的push?? (當(dāng)然也可以用 arr1.concat(arr2) 但是concat方法并不改變 arr1本身)
var arrLen=arr2.length
for(var i=0;i
arr1.push(arr2[i])
}
自從有了 Apply??? ,事情就變得如此簡單
Array.prototype.push.apply(arr1,arr2)
注:文章來源于http://www.cnblogs.com/xiaohongwu/archive/2011/06/15/2081237.html