apply与call方法,用起来(js)

首先在我谈及apply和call方法怎么用时,必须要说一下function(函数)。

函数是JavaScript中的特殊对象,既然是对象那它就一定可以有属性和方法,而它有几个内置的属性和方法

属性:length、name、arguments、caller、prototype;
var function a(){}
console.log(Object.getOwnPropertyNames(a))  用该法可查其不可配置的自有属性
//[“length”, “name”, “arguments”, “caller”, “prototype”]

方法:call、apply、bind、toString。  可以new 一个函数查看其原型就可以看见

对这些属性我就略过;着重讲我们今天的主题,有很多人都知道这两个方法但是大都不怎么用,但是这两个方法真的很有用,尤其在借助原生方法实现我们自己的方法时,我们众所周知的jQuery插件中大量运用这两个方法来实现自己包装过的方法。如$.each()$.extend()$.inArray()$.type()等,感觉是不是很强大。

1、先看定义(来源JavaScript权威指南6)

call()方法和apply()的第一个实参是要调用函数的母对象,它是调用上下文,在函数体内通过this来获得对它的引用。
在ECMAScript5的严格模式中,call()和apply()的第一个参数都会变为this的值,那怕传入的实参是原始值甚至是null或undefined。在ECMAScript3和非严格模式中,传入的null和undefined都会被全局对象代替,而其他原始值则会被相应的包装对象所替代。

call(),第一个调用上下文实参之后的所有实参就是要传入待调用函数的值;

apply()就两个参数,第二个是一个数组或类数组对象

var bigcall = Math.max.call(”,1,2,5);
var bigapply = Math.max.apply(”,[1,2,5])

在此我举例说明怎么用,以$.type()$.each()来举例子

首先针对这两个方法来简单的模拟jQuery

var toString  = Object.prototype.toString,class2type={};
var jQuery=function(){
//真实的jQuery不是这样的,我们只是为了例子简单写
}
jQuery.type=function(obj){
          return obj ==null? String(obj):
                      class2type[ toString.call(obj) ]  || “object”

      };

jQuery.each=function (object,callback){
          //这里只简单写一下
          var name,i=0,
          length=object.lenth,
          isObj = length===undefined || jQuery.type(object)===’function’;
          if(isObj){
                  for(name in object){
                            if(callback.call(object[name],name,object[name])===false)
                                break;
                        }
              }else {
                  for(;i<length;){
                            if(callback.call(object[i],i,object[i++])===false)
                                break;
                        }
                }
      return object

     }

jQuery.each(“Boolean Number String Function Array Date RegExp Object”.split(” “),function(i,name) {
class2type[“[object “+name+”]”] =name.toLowerCase();
});

//这里我们用了toString方法,如果你直接给该方法中传参不管是什么该方法都返回Object.prototype.toString([])  “[object Object]”。但是用了call方法就会显示的将该方法的this指向传入的第一个参数,所以会返回”[object Array]”。call和apply方法都有显示的改变this的功能
这个方法又可以这么改写;

var obj = [];  这个obj可以是任意类型,什么类型this指向谁。
obj.m = Object.prototype.toString;
obj.m()                                            //”[object Array]”

each方法可以看出,根据我们自己的方法来利用for循环,来适应类数组和数组的循环,扩展了数组forEach方法.

其实只要是方法不管内置的,自己定义的我们都可以调用call或apply(是个方法都能用,他是方法的方法,在此不纠结定义)。只要符合其传参要求即可,它们只是改变了this的指向。(干的是挂羊头卖狗的事情)

大家打开jQuery的源码看一遍就发现好多call和apply方法

    原文作者:sky_rainbow
    原文地址: https://www.jianshu.com/p/099bd16a893c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞