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 相关文章推荐
说说掌握JavaScript语言的思想前提想学习js的朋友可以看看
Apr 01 Javascript
javascript 事件处理程序介绍
Jun 27 Javascript
node.js中实现同步操作的3种实现方法
Dec 05 Javascript
JavaScript中常用的验证reg
Oct 13 Javascript
浅谈js使用in和hasOwnProperty获取对象属性的区别
Apr 27 Javascript
npm国内镜像 安装失败的几种解决方案
Jun 04 Javascript
利用JQUERY实现多个AJAX请求等待的实例
Dec 14 jQuery
微信小程序实现城市列表选择
Jun 05 Javascript
详解django模板与vue.js冲突问题
Jul 07 Javascript
微信小程序实现禁止分享代码实例
Oct 19 Javascript
vue-router的钩子函数用法实例分析
Oct 26 Javascript
javascript实现贪吃蛇游戏(娱乐版)
Aug 17 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 Smarty生成EXCEL文档的代码
2008/08/23 PHP
php设置编码格式的方法
2013/03/05 PHP
php按单词截取字符串的方法
2015/04/07 PHP
PHP数组与字符串互相转换实例
2020/05/05 PHP
JTrackBar水平拖动效果
2007/07/15 Javascript
extjs3 combobox取value和text案例详解
2013/02/06 Javascript
jQuery中extend()和fn.extend()方法详解
2015/06/03 Javascript
JS实现模拟百度搜索“2012世界末日”网页地震撕裂效果代码
2015/10/31 Javascript
JS简单判断滚动条的滚动方向实现方法
2017/04/28 Javascript
JavaScript创建对象_动力节点Java学院整理
2017/06/27 Javascript
bootstrap下拉框动态赋值方法
2018/08/10 Javascript
vue 中基于html5 drag drap的拖放效果案例分析
2018/11/01 Javascript
通过实例讲解JS如何防抖动
2019/06/15 Javascript
JS实现音乐导航特效
2020/01/06 Javascript
vue中js判断长时间不操作界面自动退出登录(推荐)
2020/01/22 Javascript
微信小程序实现上传多个文件 超过10个
2020/03/30 Javascript
[04:02]DOTA2上海特锦赛小组赛第二日recap精彩回顾
2016/02/28 DOTA
[45:59]EG vs OG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
python列表操作实例
2015/01/14 Python
Python3里的super()和__class__使用介绍
2015/04/23 Python
python读写二进制文件的方法
2015/05/09 Python
python使用arcpy.mapping模块批量出图
2017/03/06 Python
5分钟 Pipenv 上手指南
2018/12/20 Python
python怎么判断模块安装完成
2020/06/19 Python
德国旅游网站:weg.de
2018/06/03 全球购物
Notino匈牙利:购买香水和化妆品
2019/04/12 全球购物
中英双版中文教师求职信
2013/10/27 职场文书
专科毕业生自我鉴定
2013/12/01 职场文书
货车司机岗位职责
2014/03/18 职场文书
养牛场项目建议书
2014/05/13 职场文书
开学典礼演讲稿
2014/05/23 职场文书
2014年药品销售工作总结
2014/12/16 职场文书
三好学生事迹材料
2014/12/24 职场文书
《用字母表示数》教学反思
2016/02/17 职场文书
创业项目大全(适合在家创业的项目)
2019/08/15 职场文书
使用feign服务调用添加Header参数
2021/06/23 Java/Android