JS中使用apply方法通过不同数量的参数调用函数的方法


Posted in Javascript onMay 31, 2016

apply()方法定义

函数的apply()方法和call方法作用相同,区别在于接收的参数的方式不同。
apply()方法接收两个参数,一个是对象,一个是参数数组。

apply()作用

1、用于延长函数的作用域

示例:

var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
sayColor();//"red"
sayColor.apply(o);//"blue"

这里通过apply()方法把函数动态绑定到了对象o上了,这时this指向o对象,得到结果"blue"。

2、对象不需要与方法有任何耦合关系

下面举个耦合的例子,看如何通过apply来解决这种耦合。

var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
o.sayColor=sayColor;
o.sayColor();//"blue"

这里先将函数放到了对象o中,这里对象和方法就紧耦合到一起了,方法的调用必须通过对象o。

没有使用apply()和call()方法那样灵活。
重构上面代码,得到前例中的代码。

var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
sayColor();//"red"
sayColor.apply(o);//"blue"

这里对象并没有绑定任何方法,只是在需要使用的时候,利用函数的apply或call方法来动态绑定。

对象和方法之间没有耦合在一起。这里还可以通过ES5提供的bind()方法来完成

3、实现可变参数函数传参

下面一个计算任意数量数字平均值的函数

average(,,);
average();
average(,,,,,,,,);
average(,,,,,,,,,);

average函数是一个称为可变参数或可变元函数(函数的元数是指其期望的参数个数)的例子。

当然这个函数也可以写成一个接收数组的形式。

averageOfArray([,,]);
averageOfArray([]);
averageOfArray([,,,,,,,,]);
averageOfArray([,,,,,,,,,]);

使用可变参数的函数更简洁、优雅。可变参数函数具有便捷的语法,至少让调用者预先明确地知道提供了多少个参数。

如果我有这样一个数组

var scores=getAllScores();

如何使用average函数计算平均值呢?

1.可变参数函数版本。

这时就可以和apply()方法配合使用,这里因为函数并没用引用this变量,因此第一个参数我们传入一个null。代码如下:

var scores=getAllScores();
average.apply(null,scores);

2.直接参数为数组的形式

这里可以直接传入数组参数。

var scores=getAllScores();
averageOfArray(scores);

以上两种形式,个人觉得都是可以,反而第二种更简单。多知道一种方法,对于遇到别人写的函数时,可以轻松应对,不需要重构代码。这个好处反而更多。

4、实现可变参数方法的传值

示例:buffer对象包含一个可变参数的append方法,该方法添加元素到函数内部的state数组中。

var buffer={
state:[],
append:function(){
for(var i=,n=arguments.length;i<n;i++){
this.state.push(arguments[i]);
}
}
};

这时append方法可以接受任意多个参数。

buffer.append('Hello,');
buffer.append('firtName',' ','lastName','!');
buffer.append('newLine');

形式如

buffer.append(arg1,arg2,arg3,...)

借助apply方法的this参数,我们可以指定一个可计算的数组调用append方法

buffer.append.apply(buffer,getInputStrings());

注意:这里的buffer很重要,如果传递不同的对象,则append方法将尝试修改该错误对象的state属性

提示

•使用apply方法指定一个可计算的参数数组来调用可变参数的函数
•使用apply方法的第一个参数给可变参数的方法提供一个接收者

附录一

average函数

function average(){
var args=[].slice.call(arguments);
var sum=args.reduce(function(prev,cur){
return prev+cur;
});
return parseInt(sum/args.length,);
}

averageOfArray函数

function averageOfArray(arr){ 
var sum=arr.reduce(function(prev,cur){
return prev+cur;
});
return parseInt(sum/arr.length,);
}

ES5 bind()方法

这个方法创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
例如

var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
var oSayColor=sayColor.bind(o);
oSayColor();//"blue"

兼容低版本,参考使用下面的版本 :

if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = [].slice.call(arguments, ),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof fNOP? this: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype; 
}
fBound.prototype = new fNOP();
return fBound;
};
}
Javascript 相关文章推荐
类之Prototype.js学习
Jun 13 Javascript
jquery ajax中使用jsonp的限制解决方法
Nov 22 Javascript
JavaScript设计模式之原型模式(Object.create与prototype)介绍
Dec 28 Javascript
JS+CSS实现仿新浪微博搜索框的方法
Feb 24 Javascript
jquery+css3实现网页背景花瓣随机飘落特效
Aug 17 Javascript
学习JavaScript设计模式之状态模式
Jan 08 Javascript
有趣的bootstrap走动进度条
Dec 01 Javascript
javascript 中的继承实例详解
May 05 Javascript
jquery+css实现简单的图片轮播效果
Aug 07 jQuery
微信小程序如何获取群聊的openGid以及名称详解
Jul 17 Javascript
js中console在一行内打印字符串和对象的方法
Sep 10 Javascript
解决LayUI加上form.render()下拉框和单选以及复选框不出来的问题
Sep 27 Javascript
jQuery解决IE6、7、8不能使用 JSON.stringify 函数的问题
May 31 #Javascript
利用jQuery实现CheckBox全选/全不选/反选的简单代码
May 31 #Javascript
TinyMCE汉化及本地上传图片功能实例详解
May 31 #Javascript
JS定时器使用,定时定点,固定时刻,循环执行详解
May 31 #Javascript
BootStrap创建响应式导航条实例代码
May 31 #Javascript
浅谈js中的延迟执行和定时执行
May 31 #Javascript
温习Javascript基础语法之词法结构
May 31 #Javascript
You might like
php 大数据量及海量数据处理算法总结
2011/05/07 PHP
设置php页面编码的两种方法示例介绍
2014/03/03 PHP
PHP API接口必备之输出json格式数据示例代码
2017/06/27 PHP
php爬取天猫和淘宝商品数据
2018/02/23 PHP
MultiSelect左右选择控件的设计与实现介绍
2013/06/08 Javascript
jQuery - css() 方法示例详解
2014/01/16 Javascript
JavaScript仿静态分页实现方法
2015/08/04 Javascript
JavaScript实现点击按钮切换网页背景色的方法
2015/10/17 Javascript
JS简单模拟触发按钮点击功能的方法
2015/11/30 Javascript
JavaScript代码判断点击第几个按钮
2015/12/13 Javascript
JS简单循环遍历json数组的方法
2016/04/22 Javascript
使用plupload自定义参数实现多文件上传
2016/07/19 Javascript
教你用十行node.js代码读取docx的文本
2017/03/08 Javascript
JS实现静态页面搜索并高亮显示功能完整示例
2017/09/19 Javascript
vue: WebStorm设置快速编译运行的方法
2018/10/18 Javascript
详解小程序rich-text对富文本支持方案
2018/11/28 Javascript
JS实现鼠标拖拽盒子移动及右键点击盒子消失效果示例
2019/01/29 Javascript
Node.js API详解之 console模块用法详解
2020/05/12 Javascript
在Vue中获取自定义属性方法:data-id的实例
2020/09/09 Javascript
[02:03]永远的信仰DOTA2 中国军团历届国际邀请赛回顾
2016/06/26 DOTA
[33:33]完美世界DOTA2联赛PWL S2 FTD.C vs SZ 第二场 11.27
2020/11/30 DOTA
[32:07]完美世界DOTA2联赛PWL S3 LBZS vs Rebirth 第一场 12.16
2020/12/17 DOTA
Python 创建新文件时避免覆盖已有的同名文件的解决方法
2018/11/16 Python
利用Python如何实现一个小说网站雏形
2018/11/23 Python
python nohup 实现远程运行不宕机操作
2020/04/16 Python
Python爬取阿拉丁统计信息过程图解
2020/05/12 Python
详解python算法常用技巧与内置库
2020/10/17 Python
购买正版游戏和游戏激活码:Green Man Gaming
2019/11/06 全球购物
《记承天寺夜游》教学反思
2014/02/16 职场文书
公司股份合作协议书
2014/12/07 职场文书
客房服务员岗位职责
2015/02/09 职场文书
承诺书模板大全
2015/05/04 职场文书
2015年度信用社工作总结
2015/05/04 职场文书
银行反洗钱宣传活动总结
2015/05/08 职场文书
2019年自助餐厅创业计划书模板
2019/08/22 职场文书
《我在为谁工作》:工作的质量往往决定生活的质量
2019/12/27 职场文书