js 中的apply
之一------(函数的劫持与对象的复制)
关于对象的继承,一般的做法是用复制法: Object.extend
见protpotype.js 的实现方法:
Object.extend = function(destination, source) ...{
for (property in source) ...{
destination[property] = source[property];
}
return destination;
}
除此以外,还有一种不太常见的方法: Function.apply.
apply 方法能劫持(<<Ajax in Action>> 书中用到"劫持"一语,很生动啊)另外一个对象的方法,
继承另外一个对象的属性。
示范代码如下:
Apply示范代码
<script>
function Person(name,age)...{ //定义一个类,人类
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)...{ //学生类
Person.apply(this,arguments)
Print.apply(this,arguments)
this.grade=grade //年级
this.school=school //学校
}
var p1=new Person("jake",10)
p1.sayhello()
var s1=new Student("tom",13,6,"清华小学")
s1.show()
s1.sayhello()
alert(s1.funcName)
</script>
学
生类本来不具备任何方法,但是在 Person.apply(this,arguments) 后,他就具备了
Person类的sayhello方法和 所有属性。 在 Print.apply(this,arguments) 后就自动得到了 show()
方法。
本文,作为抛砖引玉,只对 apply 的用法(在对象继承和函数劫持方面)做个小示范,其他更深入的应用要
靠大家慢慢去领会了。
之二------利用Apply的参数数组化来提高
我们再来聊聊Function.apply() 在提升程序性能方面的技巧。
我们先从 Math.max() 函数说起, Math.max后面可以接任意个参数,最后返回所有参数中的最大值。
比如
alert(Math.max(5,8)) //8
alert(Math.max(5,7,9,3,1,6)) //9
但是在很多情况下,我们需要找出数组中最大的元素。
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<arrLen;i++){
ret=Math.max(ret,arr[i]);
}
return ret;
}
这样写麻烦而且低效。如果用 apply呢,看代码:
function getMax2(arr){
return Math.max.apply(null,arr)
}
两段代码达到了同样的目的,但是getMax2却优雅,高效,简洁得多。
看性能测试:
getMax性能测试
<script>
var myArr=new Array()
function fillRnd(arrLen){ //填入 arrLen个1-10的随机数字到数组
for(var i=0,arr=[];i<arrLen;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<arrLen;i++){
ret=Math.max(ret,arr[i]);
}
return ret;
}
function getMax2(arr){
return Math.max.apply(null,arr)
}
myArr=fillRnd(20*10000) //生成20万个随机数填到数组
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]) //在我机器上 96,464 .不同的机器,结果可能有差异
</script>
通过20万个数据的比较, getMax2 时间为 96ms 而 getmax时间为464。 两者相差5倍
再比如数组的push方法。
var arr1=[1,3,4];
var arr2=[3,4,5];
如果我们要把 arr2展开,然后一个一个追加到 arr1中去,最后让 arr1=[1,3,4,3,4,5]
arr1.push(arr2) 显然是不行的。 因为这样做会得到 [1,3,4, [3,4,5] ]
我们只能用一个循环去一个一个的push (当然也可以用 arr1.concat(arr2) 但是concat方法并不改变 arr1本身)
var arrLen=arr2.length
for(var i=0;i<arrLen;i++){
arr1.push(arr2[i])
}
自从有了 Apply ,事情就变得如此简单
Array.prototype.push.apply(arr1,arr2)
From:http://www.cnblogs.com/xiaohongwu/archive/2011/06/15/2081237.html
js 中的apply的更多相关文章
- 深入理解js中的apply、call、bind
概述 js中的apply,call都是为了改变某个函数运行时的上下文环境而存在的,即改变函数内部的this指向. apply() apply 方法传入两个参数:一个是作为函数上下文的对象,另外一个是作 ...
- js中的apply和call API
借用网上的一个例子: fun.call(this,arg1,arg2,arg3) fun.apply(this,arguments) this.fun(arg1,arg2,arg3) 三种方法等效. ...
- js中call(),apply(),以及prototype的含义
最近段时间主要学习前端去了,然而所遇到的一些问题我觉得有必要去深究一下 prototype: 1 js中有三种表达方法 类方法,属性方法,原型方法 function People(name) { th ...
- js中call apply方法的使用介绍
js call call 方法 请参阅 应用于:Function 对象 要求 版本 5.5 调用一个对象的一个方法,以另一个对象替换当前对象. call([thisObj[,arg1[, arg2[, ...
- Js中的apply和call
1.call和apply都是为了改变某个函数运行时的上下文而存在的 2.也就是改变函数体内this的指向. 3.二者的作用完全一样,只是接受参数的方式不太一样. 4.call 需要把参数按顺序传递进去 ...
- js 中call,apply,bind的区别
call.apply.bind方法的共同点与区别: apply.call.bind 三者都是用来改变函数的this对象的指向: apply.call.bind 三者都可以利用后续参数传参: bind ...
- js中的apply调用
今天看了阮一锋老师的一篇文章,感觉很明了对闭包的理解,尤其是文章中的apply的介绍 apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象. ...
- 关于JS中的apply()与call()使用方法与区别
Js apply方法详解我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里 ...
- Js中call apply函数以及this用法
this介绍: C#里this关键字的意义比较确定的.JavaScript的this关键字,随着函数使用场合不同,this的值会发生变化,感觉用法比较混乱,所以,现在是有必要整理一下的时刻了! 总结一 ...
- 闲聊js中的apply、call和arguments
JavaScript提供了apply和call两种调用方式来确定函数中的this的指向,在现实编码中,我确实 很少接触到这两个方法.但很无奈,很多面试题都要考这两种方法,我又没怎么用到,所以我们先来 ...
随机推荐
- 如何创建效率高sql-建立索引
我们做开发的人员,虽说自己不是专业从事数据库方面研究的(如DBA),但很多时候,公司没有专门的DBA,所以拿到具体的项目中,整体的数据库设计都是开发人员自己写的,随着时间的推移,加上开发经验的增长 ...
- MySQL 事物和数据库锁
1.数据库事物 1. 什么是事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一 ...
- shell_script_查询主机名、ip地址 、DNS地址
#!/bin/bashhostnameip=`/sbin/ifconfig eth0|grep "inet addr:"|sed 's/Bcast.*$//'g |awk -F & ...
- mysql-jdbc创建connection理解
jdbc源码分析(http://blog.csdn.net/brilliancezhou/article/details/5499738) 创建JDBC连接代码 Class.forName(" ...
- js相关命令
echo "<script>alert('您尚未关注,关注成功后方可下单!');location.href='http://www.baidu.com';</script& ...
- HIVE-如何查看执行日志
HIVE既然是运行在hadoop上,最后又被翻译为MapReduce程序,通过yarn来执行.所以我们如果想解决HIVE中出现的错误,需要分成几个过程 HIVE自身翻译成为MR之前的解析错误 Hado ...
- LeetCode第五题:Longest Palindromic Substring
Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...
- 第二届PHP全球开发者大会(含大会的PPT)
PHP全球开发者大会于2016年5月14日至15日在北京召开 更多现场图片请猛击: http://t.cn/RqeP7y9 , http://t.cn/RqD8Typ 最后,这次大会的PPT可以在这 ...
- POJ1274(二分图最大匹配)
The Perfect Stall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 23356 Accepted: 104 ...
- Day2-VIM(五):复制
粘帖 p 粘帖 复制的形式可以很多,但是粘帖的形式却没多少 无非就是加数字达到多次粘帖什么的 其实准确的说,p应该是放置的意思 不过我也搞不清是paste还是put的缩写 单词和字符复制 ynl 向右 ...