js中apply()和call()方法的使用
1.apply()方法
apply方法能劫持另外一个对象的方法,继承另外一个对象的属性。
Function.apply(obj,args)方法能接收两个参数
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args-->arguments)
使用apply()方法时可以直接将当前函数的arguments对象作为apply的第二个参数传入
(1)apply()方法可实现继承
eg:function Person(name,age){ //定义一个类,人类
this.name=name; //名字
this.age=age; //年龄
this.sayhello=function(){console.log("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(""));
}
}
console.log(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(); //hello
var s1=new Student("tom",13,6,"清华小学");
s1.show(); //name:tom age:13 funcName:Print grade:6 school:清华小学
s1.sayhello(); //hello
console.log(s1.funcName); //Print
学生类本来不具备任何方法,但是在Person.apply(this,arguments)后,它就具备了Person类的sayhello方法和所有属性。在Print.apply(this,arguments)后就自动得到了show()方法。
(2) apply()方法可以将参数数组默认的转换为参数列表
我们先从Math.max()函数说起,Math.max后面可以接任意个参数,最后返回所有参数中的最大值。
eg: Math.max(5,8) //8
Math.max(5,7,9,3,1,6) //9
但是在很多情况下,我们需要找出数组中最大的元素。
var arr=[5,7,9,1]
console.log(Math.max(arr)) // NaN 这个方法无法实现
需要按如下所示的方法才可以实现:
eg: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(Math,arr);
}
两段代码达到了同样的目的,但是getMax2却更高效简洁。这里主要是由于apply可以将一个数组默认的转换为一个参数列表(即可以将数组[param1,param2,param3] 转换为 param1,param2,param3) ,如果让我们用程序来实现将数组的每一个项来转换为参数列表,像getMax方法一样会比较麻烦。借助apply的这点特性,就有了更加高效的解决方法如getMax2方法所示。
再比如数组的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) 或者 arr1.push.apply(arr1,arr2);
2.call()方法
call()方法与apply()方法的功能是一样的,只不过是参数列表不一样。如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])
Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表
eg:function Animal(){
this.name = "Animal";
this.showName = function(){
console.log(this.name); }
}
function Cat(){
this.name = "Cat";
this.sayWorld=function(){
console.log("hello world")};
this.sayName=function(){
console.log(this.name);}
}
var animal = new Animal();
var cat = new Cat();
Cat.call(animal);
animal.showName.call(cat); // Cat
animal.sayWorld(); //hello world
animal.sayName(); // Cat
3.什么情况下用apply()什么情况下用call()
在给对象参数的情况下,如果参数的形式是数组的时候,比如apply示例里面传递了参数arguments,这个参数是数组类型,并且在调用Person的时候参数的列表是对应一致的(也就是Person和Student的参数列表前两位是一致的) 就可以采用 apply , 如果我的Person的参数列表是这样的(age,name),而Student的参数列表是(name,age,grade),这样就可以用call来实现了,也就是直接指定参数列表对应值的位置(Person.call(this,age,name,grade));
学习自:http://www.cnblogs.com/delin/archive/2010/06/17/1759695.html
http://www.cnblogs.com/KeenLeung/archive/2012/11/19/2778229.html
js中apply()和call()方法的使用的更多相关文章
- 原生JS中apply()方法的一个值得注意的用法
今天在学习vue.js的render时,遇到需要重复构造多个同类型对象的问题,在这里发现原生JS中apply()方法的一个特殊的用法: var ary = Array.apply(null, { &q ...
- js中apply方法的使用
js中apply方法的使用 1.对象的继承,一般的做法是复制:Object.extend prototype.js的实现方式是: Object.extend = function(destinat ...
- node.js中的url.parse方法使用说明
node.js中的url.parse方法使用说明:https://blog.csdn.net/swimming_in_it_/article/details/77439975 版权声明:本文为博主原创 ...
- javascript 中 apply(或call)方法的用途----对象的继承
一直以来,我的理解就是 js中的Function.apply(或者是Function.call)方法是来改变Function 这个函数的执行上下文(excute Context),说白了,就是改变执 ...
- JavaScript中apply与call方法
一.定义 apply:应用某一对象的一个方法,用另一个对象替换当前对象. call:调用一个对象的一个方法,以另一个对象替换当前对象. 二.apply //apply function Person( ...
- javascript中apply()和call()方法及区别
call()和apply()方法 1.方法定义 call方法: 语法:obj.call(thisObj, arg1, arg2, ...); 定义:调用一个对象的一个方法,以另一个对象替换当前对象. ...
- prototype.js中Function.prototype.bind方法浅解
prototype.js中的Function.prototype.bind方法: Function.prototype.bind = function() { var __method = this; ...
- js中apply详解
学习http://www.cnblogs.com/delin/archive/2010/06/17/1759695.html 1.对象的继承,一般的做法是复制:Object.extend protot ...
- JS中的对象和方法简单剖析
众所周知,在js中对象就是精髓,不理解对象就是不理解js. 那么什么事js中的对象呢? 在js中,几乎一切皆对象: Boolean ,String,Number可以是对象(或者说原生数据被认作对象): ...
随机推荐
- python高级之生成器&迭代器
python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container):多个元素组织在一起的数据结构 可迭代对象( ...
- 物联网平台设计心得:你所不知道的CRC校验
在物联网平台设计过程中,我的中间件一方面需要处理来自于硬件端的包,另一方面需要处理来自于用户端的包,用户端包括web端和手机端等等.所以编写一个统一的CRC认证是非常必须要. 那么,在设计开始,CRC ...
- title与alt的区别
html中的title属性和alt属性让人有些混淆. 以前不知道有title这个属性,第一次用到它时,就和alt产生了混淆.一位朋友告诉我说,alt是图片img标签里用的,title是超链接里用的, ...
- 微信小程序之触控事件(四)
[未经作者本人同意,请勿以任何形式转载] >>>什么是事件 事件是视图层到逻辑层的通讯方式. 事件可以将用户的行为反馈到逻辑层进行处理. 事件可以绑定在组件上,当达到触发事件,就会执 ...
- 使用adb shell 进入手机修改文件的权限
1.将android的tools目录加入到path中,或者直接在adb.exe路径下启动cmd窗口2.adb shell 进入手机后,发现是 $ ,不是 # 号3.在进入shell后运行 su ,就可 ...
- xcode升级导致git无法使用
skytraveler:lucas$ git Agreeing to the Xcode/iOS license requires admin privileges, please re-run as ...
- nodejs+express+mysql 增删改查
之前,一直使用的是nodejs+thinkjs来完成自己所需的项目需求,而对于nodejs中另外一中应用框架express却了解的少之又少,这两天就简单的了解了一下如何使用express来做一些数据库 ...
- 【原】KMeans与深度学习模型结合提高聚类效果
这几天在做用户画像,特征是用户的消费商品的消费金额,原始数据(部分)是这样的: id goods_name goods_amount 男士手袋 1882.0 淑女装 2491.0 女士手袋 345.0 ...
- 关于 MonoDevelop on Linux 单步调试问题的解决
在 MonoDevelop 中默认是关闭对外部程序集(.dll)的调试,可通过如下步骤来解决这个问题. 通过菜单[Edit]-[Preferences]-[Debugger]进入到调试器的设置页,把“ ...
- HTML 转 PDF
使用WkHtmlToXSharp,免费的软件,内集成了chrome 的内核,可以对CSS进行渲染,很好用 是需要传入 HTML 网页地址就可以转化为PDF文件,不过网页的编码要是 utf-8 Nuge ...