Javascript中call,apply,bind的区别

函数原型

一、探索call方法原理

Function.prototype.call = function(obj) {
// 1、让fn中的this指向obj
// eval(this.toString().replace("this","obj"));

// 2、让fn方法再执行
// this();
}
function fn1() {
  console.log(1);
  console.log(this);
}
function fn2() {
  console.log(2);
  console.log(this);
}
fn1.call(); //1,this指向window
fn1.call(fn2); //1,原来的this指向fn1,fn1.call(fn2)把this指向fn2,再让fn1方法执行。

fn1.call.call(); //报错了,fn1.call.call is not a function。
fn1.call.call(fn2); //2
/*设fn1.call = test;
test.call(fn2)原来的this指向test,test.call(fn2)把this指向fn2,再让test方法执行,即fn1.call的内部this()执行,即fn2()执行。
*/

二、call,apply,bind的调用语法

function fn(num1, num2) {
  console.log(num1 + num2);
  console.log(this);
}
//call方法
fn.call(obj , 100 , 200);
//apply方法
fn.apply(obj , [100, 200]);
//bind方法
var tempFn = fn.bind(obj, 1, 2);
tempFn();
//或者fn.bind(obj, 1, 2)();

1、相同点

  • 函数钩子,本质是函数,为了调用其他函数;
  • apply、call、bind三者都是用来改变函数的this对象的指向的;
  • apply、call、bind三者第一个参数都是this要指向的对象,也就是想指定的上下文;
  • apply、call、bind三者都可以利用后续参数传参。

2、不同点

  • call,bind在给fn传递参数的时候,以枚举形式传参;而apply以数组形式传参。
  • 明确知道参数数量时用call;不确定参数数量时用apply,然后把参数push进数组并传递进去,函数内部也可以通过arguments这个数组来遍历所有的参数。
  • bind是返回对应函数,便于稍后调用;apply、call则是立即调用。
  • bind这个方法在IE6~8下不兼容。在Javascript中,多次bind()是无效的,因为bind的实现,相当于使用函数在内部包了一个call/apply,第二次bind()相当于再包住第一次bind(),故第二次以后的bind是无法生效的。

四、应用场景
1、验证是否是数组

function isArray(obj){
  return Object.prototype.toString.call(obj) === '[object Array]';
}

2、获取数组最大最小值

var numbers = [5, 458 , 120 , -215];
var maxInNumbers = Math.max.apply(Math, numbers), //458
maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458

3、数组追加

var arr1 = [12 , "foo" , {name "Camille"} , -2458];
var arr2 = ["HouYi" , 555 , 100];
Array.prototype.push.apply(arr1, arr2);

4、伪数组使用数组方法

//定义一个log方法,让它可以代理console.log方法,常见的解决方法是:
function log(msg) {
  console.log(msg);
}
log('msg1'); //msg1
log('msg1','msg2'); //msg1
//当不确定传入参数的个数时,上面的方法就失效了,于是想到了apply.
function log(){
  console.log.apply(console, arguments);
};
log('msg1'); //msg1
log('msg1','msg2'); //msg1 msg2
//如果给log消息添加一个"app_"前辍,这时可以想到Array.prototype.slice.call可以把arguments伪数组转化为标准数组,再使用数组方法unshift即可。
function log(){
  var args = Array.prototype.slice.call(arguments);
  args.unshift('app_');
  console.log.apply(console, args);
};
log('msg1'); //app_ msg1

转载于:https://www.cnblogs.com/camille666/p/call_apply_bind.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值