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 相关文章推荐
从盛大通行证上摘下来的身份证验证js代码
Jan 11 Javascript
表单元素与非表单元素刷新区别详细解析
Nov 06 Javascript
js实现div闪烁原理及实现代码
Jun 24 Javascript
BootStrap初学者对弹出框和进度条的使用感觉
Jun 27 Javascript
JavaScript中this的四个绑定规则总结
Sep 26 Javascript
jQuery简单实现遍历单选框的方法
Mar 06 Javascript
js上下视差滚动简单实现代码
Mar 07 Javascript
jQuery复合事件结合toggle()方法的用法示例
Jun 10 jQuery
vue3.0 CLI - 2.2 - 组件 home.vue 的初步改造
Sep 14 Javascript
详解使用React.memo()来优化函数组件的性能
Mar 19 Javascript
解决Layui 表格自适应高度的问题
Nov 15 Javascript
antd配置config-overrides.js文件的操作
Oct 31 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开发大型项目的一点经验
2006/10/09 PHP
php中将html中的br换行符转换为文本输入中的换行符
2013/03/26 PHP
PHP模糊查询的实现方法(推荐)
2016/09/06 PHP
php str_getcsv把字符串解析为数组的实现方法
2017/04/05 PHP
PHP设计模式(五)适配器模式Adapter实例详解【结构型】
2020/05/02 PHP
CSS中简写属性要注意TRouBLe的顺序问题(避免踩坑)
2021/03/09 HTML / CSS
Discuz! 6.1_jQuery兼容问题
2008/09/23 Javascript
php跨域调用json的例子
2013/11/13 Javascript
使用javascript做的一个随机点名程序
2014/02/13 Javascript
node.js中的fs.chownSync方法使用说明
2014/12/16 Javascript
JavaScript实现计算字符串中出现次数最多的字符和出现的次数
2015/03/12 Javascript
探究JavaScript函数式编程的乐趣
2015/12/14 Javascript
javascript每日必学之多态
2016/02/23 Javascript
两种方法解决javascript url post 特殊字符转义 + &amp; #
2016/04/13 Javascript
微信小程序 教程之引用
2016/10/18 Javascript
jQuery 遍历map()方法详解
2016/11/04 Javascript
微信小程序 动态传参实例详解
2017/04/27 Javascript
JavaScript运行原理分析
2018/02/09 Javascript
详解vue-cli3 中跨域解决方案
2019/04/10 Javascript
详解关于html,css,js三者的加载顺序问题
2019/04/10 Javascript
JS删除数组指定值常用方法详解
2020/06/04 Javascript
vue Element左侧无限级菜单实现
2020/06/10 Javascript
解决idea开发遇到javascript动态添加html元素时中文乱码的问题
2020/09/29 Javascript
python中argparse模块用法实例详解
2015/06/03 Python
Python实现获取磁盘剩余空间的2种方法
2017/06/07 Python
Python实现模拟分割大文件及多线程处理的方法
2017/10/10 Python
Bottle框架中的装饰器类和描述符应用详解
2017/10/28 Python
python 借助numpy保存数据为csv格式的实现方法
2018/07/04 Python
Python3爬虫使用Fidder实现APP爬取示例
2018/11/27 Python
Python button选取本地图片并显示的实例
2019/06/13 Python
python and or用法详解
2019/06/26 Python
python中的colorlog库使用详解
2019/07/05 Python
python监控进程状态,记录重启时间及进程号的实例
2019/07/15 Python
交通事故协议书
2014/04/15 职场文书
党员个人自我剖析材料
2014/10/08 职场文书
一个都不能少观后感
2015/06/04 职场文书