首页 > 移动平台 > 详细

深入浅出javascript call apply bind

时间:2016-02-27 20:43:56      阅读:113      评论:0      收藏:0      [点我收藏+]

在JavaScript中函数的调用可以有多种方式,但更经典的莫过于call和apply。call跟apply都绑定在函数上,他们两个的第一个参数意义相同,传入一个对象,他作为函数的执行环境(实质上是为了改变函数的Execution Context执行上下文),也就是this的指向;而第二个参数两者只是类型的不同,call传的是arguments,而apply传的是array。废话不多说,先上一个最基础的例子:

function add(c,d){
  return this.a + this.b + c + d;
}
var o = {
  a: 1,
  b: 2        
}
add.call(o,3,4)          // 10
add.apply(o,[3,4])    // 10

 

再比如我之前看过的Twitter上的关于call和apply的一个面试题:定义一个函数log,传入任意数量参数,让它模拟console.log的方法,形如log(‘hello‘,‘world‘);

function log(){
  console.log.apply(console,arguments);
}

  技术分享

当执行这个log函数时,该函数的执行上下文为console对象,arguments为传入的实参。

然后此题又有需求,如果要给每个log信息加一个(app)前缀,比如 ‘(app) hello world‘;

这时我们应该想到一点,那就是我们传入的实参,也就是arguments并不是一个数组,它实质上只是一个类数组的对象,我们在这里可以用 instanceof 来判断自定义对象。

技术分享技术分享

instanceof的意思就是看左边对象的原型链上是否有右边构造器的prototype属性。由上图可以看出arguments是一个类数组的对象,并且可以看出arguments没有array的方法。

所以回到刚才那个题,我们必须让传入的实参变为Array类型才可以调用数组的unshift方法(在它的前面加上app)。

function log(){
  var args = Array.prototype.slice.call(arguments);
  args.unshift(‘(app)‘);  
  console.log.apply(console,args);        
}

log(‘hello‘,‘world‘);  // (app) hello world

在OOP面向对象中此方法用的更加多一些,当我们不想为另一个对象创建方法的时候,可以用call调用foo的方法。

function foo () {}
foo.prototype.name = ‘james‘;
foo.prototype.sayHello = function(){
    console.log(this.name);
}
var obj1 = new foo();
obj1.sayHello();   //james
var obj2 = {
    name: ‘bond‘
}
obj1.sayHello.call(obj2);  //bond

 

深入浅出javascript call apply bind

原文:http://www.cnblogs.com/ssh-007/p/5223483.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!