博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript中的call和apply应用
阅读量:5838 次
发布时间:2019-06-18

本文共 2413 字,大约阅读时间需要 8 分钟。

ECMAScript3给Function的原型定义了两个方法,他们是Function.prototype.call 和 Function.prototype.apply. 在实际开发中,特别是在一些函数式风格的代码编写中,callapply方法尤为有用。

call和apply区别

其实他们的作用是一样的,只是传递的参数不一样而已。

apply: 接受2个参数,第一个参数指定了函数体内this对象的指向,第二个参数为数组或者一个类数组。apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。

举个栗子:

const obj1 = {
name: 'microzz',
getName: function() {
return this.name;
}
};
 
const obj2 = {
name: 'Zhaohui'
}
 
console.log(obj1.getName()); // "microzz"
console.log(obj1.getName.call(obj2)); // "Zhaohui"
console.log(obj1.getName.apply(obj2)); // "Zhaohui"

call和apply的用途

改变this指向

call和apply可以改变this的指向,这点我们从上面这个例子中可以看出。我们还可以举一个实际当中可以遇到的情况:

有的时候我们会觉得 document.getElementById这个方法太长了,我们会尝试用一个短函数来代替它,如同prototype.js等一些框架所做过的事情,下面用代码说明:

const getId = function(id) {
return document.getElementById(id);
}
 
getId(
'id');

在Chrome、Firefox、IE10中执行会发现抛出异常,这是因为很多引擎的 document.getElementById 的方法内部需要用到this,这个this本来被期望指向document,但直接普通函数调用就指向了window。我们可以利用apply“修正” this

document.getElementById = (function(func) {
return function() {
return func.apply(document, arguments);
}
})(
document.getElement);
 
const getId = document.getElementById;

Function.prototype.bind

在大部分高级浏览器已经实现了内置的Function.prototype.bind,用来指定函数内部的this指向,如果没有原生的Function.prototype.bind,我们也可以模拟一个,代码如下:

Function.prototype.bind = function(context) {
var self = this;
return function() {
return self.apply(context, arguments);
}
}
 
var obj = {
name: 'microzz'
};
 
var func = function() {
console.log(this.name); // microzz
}.bind(obj);
 
func();

这是一个简化版的,通常我们会实现得稍微复杂一点:

 
Function.prototype.bind = function() {
var self = this;
 
// 需要绑定的this上下文
var context = [].shift.call(arguments);
 
// 剩余的参数转成数组
var args = [].slice.call(arguments);
 
return function() {
return self.apply(context, [].concat.call(args, [].slice.call(arguments)));
}
}
 
var obj = {
name: 'microzz'
};
 
var func = function(a, b, c, d) {
console.log(this.name); // microzz
console.log([a, b, c, d]); // [1, 2, 3, 4]
}.bind(obj,
1, 2);
 
func(
3, 4);

借用其他对象的方法

借用构造函数

借用方法的第一种场景是“借用构造函数”,可以实现类似继承的效果:

var A = function(name) {
this.name = name;
}
 
var B = function() {
A.apply(
this, arguments);
}
 
B.prototype.getName =
function() {
return this.name;
}
 
var b = new B('microzz');
console.log(b.getName()); // microzz

类数组

函数参数列表arguments是一个类数组对象,虽然它有下标,但是并不是真正的数组。为了能使用数组的一些方法,我们常常会借用Array.prototype对象上的方法。

比如想往arguments中添加新元素,通常会借用Array.prototype.push
想把arguments转成真正数组的时候,可以借用Array.prototype.slice或者也可以使用ES6的Array.from

About

转载地址:http://csjcx.baihongyu.com/

你可能感兴趣的文章
EventSystem
查看>>
用WINSOCK API实现同步非阻塞方式的网络通讯
查看>>
玩一玩博客,嘿嘿
查看>>
Ubuntu设置python3为默认版本
查看>>
JsonCpp 的使用
查看>>
问题账户需求分析
查看>>
32、SpringBoot-整合Dubbo
查看>>
HDU 2044 一只小蜜蜂(递归)
查看>>
spring两大核心对象IOC和AOP(新手理解)
查看>>
hp 服务器通过串口重定向功能的使用
查看>>
MongoDB CookBook读书笔记之导入导出
查看>>
shell如何快速锁定所有账号
查看>>
HTML 5实现的手机摇一摇
查看>>
此博客不再发表对自己私事的看法
查看>>
导致Asp.Net站点重启的10个原因
查看>>
【PMP】Head First PMP 学习笔记 第一章 引言
查看>>
抓住云机遇编排工作 搞定复杂IT工作流
查看>>
MYSQL的longtext字段能放多少数据?
查看>>
MTK 平台上如何给 camera 添加一种 preview size
查看>>
云计算最大难处
查看>>