js call 以及apply

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js call 以及apply相关的知识,希望对你有一定的参考价值。

用实例来讲;一半什么场合用到bind、call、apply呢?
【一个对象 A】的方法被【另一个对象 B】【引用】的时候(请注意 引用 的意思,区分调用 );【对象A】的方法内的this作用域就不指向【对象A】了,这个时候你再用this.XX项调用【对象A】的某个属性就会发生错误。

举个例子吧;
var aHello = {
    name : "hello",
    showName : function(){
        console.log(this.name);
        //console.log(this.tagName);
    }
}

document.querySelector(‘a‘).onclick = aHello.showName;

这个时候因为【对象aHello】的方法showName被【对象document.querySelector(‘a‘)】引用,所以showName内的this就不指向【aHello】了,指向【对象document.querySelector(‘a‘)】,可以去掉注释进行验证。

但是我们的需求是,点击a的时候就显示aHello的名称。

这个时候该怎么做呢?

方法一:在onclick的时候改用匿名函数,匿名函数内再调用 【对象aHello】的方法;
如:
var aHello = {
    name : "hello",
    showName : function(){
        console.log(this.name);
    }
}

document.querySelector(‘a‘).onclick = function(){
    aHello.showName();
}
ok!开心的解决了;

然而,是不是觉得太怂了。我们来衍生一下第二种方法,然后再说bind和call和apply的区别;

方法二:因为引用, onclick改变了【对象aHello】showName内this的指向。所以我们必须在【引用】的时候对showName方法进行重新绑定新的指向;
如:

var aHello = {
    name : "hello",
    showName : function(){
        console.log(this.name);
    }
}

document.querySelector(‘a‘).onclick = aHello.showName.bind(aHello);

恩!高大上,不用写太多代码。

接下来讲一下bind和apply、call的区别;
首先这些方法多属于【原型prototype】的方法。

题主的老师 可能没听过【引用】与【调用】所以用了一个临时与永久的概念来讲解,做技术,最好不要听老师的......



还用前面例子来讲(随便举的主要区分区别,大家别挑刺);
var aHello = {
    name : "hello",
    setYourAge : function(name,age){
       console.log(name);
       console.log(age);
    }
}

document.querySelector(‘a‘).onclick = aHello.setYourAge.call(aHello,‘王佳欣‘,25);

这个时候你可以看到打开页面,浏览器控制台就会马上输出 “王佳欣”,“25”;
然后,你再点击的时候,根本不会,再输出的;ok,这就是 【调用】含义;
call和apply是调用对象方法的意思;也就是说下面的3句代码其实实现是一样的;
aHello.setYourAge.call(aHello,‘王佳欣‘,25);
aHello.setYourAge.apply(aHello,[‘王佳欣‘,25]);
aHello.setYourAge(‘王佳欣‘,25);
既然可以直接调用干嘛还要call、apply方法呢,我先说一下call、apply 和bind的区别吧;

var aHello = {
    name : "hello",
    setYourAge : function(name,age){
       console.log(name);
       console.log(age);
    }
}

document.querySelector(‘a‘).onclick = aHello.setYourAge.bind(aHello,‘王佳欣‘,25);
bind的作用是【引用】,这个时候你打开浏览器控制台不会有输出。你点击a 标签的后,才会有输出,点一次,输出一次。
粗暴一点说,这就是区别马上【调用】和【引用】的区别。

上面我们说到,下面三局代码实现是一样的。那么call、apply有什么作用呢?
aHello.setYourAge.call(aHello,‘王佳欣‘,25);
aHello.setYourAge.apply(aHello,[‘王佳欣‘,25]);
aHello.setYourAge(‘王佳欣‘,25);

call、apply有什么作用
大家开发中是不是有这样的需求(我总是喜欢用需求来作为入口)
我们经常会在我们项目中做一些通用的对象,这些对象用来处理我们的一些通用的过程。比如:通用验证方法;(注:很多人喜欢用 继承的基础类 来作为例子.....我一时想不到好的继承例子,就用通用类的例子吧!)

/*通用验证对象*/
var validator = {
    validateName : function(){
         console.log(this.name);
    },
    validateAge  : function(){
         console.log(this.age)
    }
    //.....
}

大家可以看到我们的 【通用对象validator】内,是没有定义属性(name、age)的。

这个时候比如我们有两个对象需要验证;

/*对象kobe*/
var kobe = {
    name : ‘kobe bryant‘,
    age  : -1
}

/*对象 allen*/ 
var allen = {
    name : ‘allen iverson‘,
    age  : 10
}


那我们调用验证的时候就需要用到call或者apply了
如:
var isKobeAgeValid = validator.call(kobe);

var isAllenAgeValid = validator.call(allen);

额!差不多了了.....
 
转载自 王佳欣
链接:http://www.zhihu.com/question/20289071/answer/93261557
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

以上是关于js call 以及apply的主要内容,如果未能解决你的问题,请参考以下文章

转 - JS 中 call 和 apply 以及 bind 的区别

JS里面的call, apply以及bind

js中call(),apply(),以及prototype的含义

[JavaScript-Function] Function Invocation/Call(函数调用) 以及call() and apply() 方法

js中的call()和apply()方法

CALL/APPLY一些编程基础以及一些基础知识正则