美文网首页
前端学习笔记--apply()和call()

前端学习笔记--apply()和call()

作者: 沧澈 | 来源:发表于2018-02-09 13:53 被阅读0次

    在ECMAscript标准标准中定义了call()和apply()两种方法,能够改变函数的上下文,也就是函数内部this的指向

    • call()

    call: 英 [kɔːl] 美 [kɔl]

    • vi. 呼叫;拜访;叫牌
    • vt. 呼叫;称呼;召集
    • n. 电话;呼叫;要求;访问

    Function.call(obj , arg1, arg2, ...)
    obj:这个对象将代替Function类里this对象
    params:这个是一个参数列表

    • apply()

    apply英 [ə'plaɪ] 美 [ə'plaɪ]

    • vt. 申请;涂,敷;应用
    • vi. 申请;涂,敷;适用;请求

    Function.apply(obj,args)
    obj:这个对象将代替Function类里this对象
    args:这个是数组,它将作为参数传给Function(args-->arguments)

    • 相同点

    call()和apply()都能通过点语法的调用方式,来指定上下文执行这个函数
    例子:

    function test() {
        console.log(this.name);
    }
    
    var obj = {
        name: '小明',
        age: 12
    };
    
    test.call(obj);
    test.apply(obj);
    

    控制台输出结果为:

    小明
    小明
    
    • 不同点

    call()和apply()唯一的区别就是接受的参数不一样,call的参数形式是一个参数列表,apply的参数是一个数组

    例子:

    function test(a,b,c) {
        console.log(a+b+c);
        console.log(this.name);
    }
    
    var obj = {
        name: '小明',
        age: 12
    };
    
    test.call(obj,1,2,3);
    test.apply(obj,[1,2,3]);
    

    控制台输出结果为:

    6
    小明
    6
    小明
    
    • 严格模式和非严格模式

    在非严格模式下,第一个参数传递为null或者undefined时,函数内的this会指向默认的宿主对象,在浏览器中是window

    例子:

    var test=function(){
        console.log(this===window);
    }
    
    test.apply(null);
    test.call(undefined);
    

    控制台输出结果为:

    true
    true
    
    • 关于继承

    例子:

    function Animal(name){   
        this.name = name;   
        this.showName = function(){   
            console.log(this.name);   
        }   
    }   
     
    function Cat(name){  
        Animal.call(this, name);  
    }   
     
    var cat = new Cat("Black Cat");   
    cat.showName();
    
    

    控制台输出结果为:

    Black Cat
    
    • 解决this被随意更改的问题

    在实际开发中,经常会遇到this指向被不经意改变的场景。
    有一个局部的fun方法,fun被作为普通函数调用时,fun内部的this指向了window,但我们往往是想让它指向该#test节点。
    例子:

    window.id="window";
    document.querySelector('#test').onclick = function(){
        console.log(this.id);
        var fun = function(){
            console.log(this.id);
        }
        fun();
    }
    
    

    控制台输出结果为:

    test
    window
    

    解决:

    window.id="window";
    document.querySelector('#test').onclick = function(){
        console.log(this.id);
        var fun = function(){
            console.log(this.id);
        }
        fun.call(this);
    }
    

    控制台输出结果为:

    test
    test
    

    也可以这样做,不过在ECMAScript 5的strict模式下,这种情况下的this已经被规定为不会指向全局对象,而是undefined
    例子:

    window.id="window";
    document.querySelector('#test').onclick = function(){
        var that = this;
        console.log(this.id);
        var fun = function(){
            console.log(that.id);
        }
        fun();
    }
    
    function func(){
        "use strict"
        alert ( this );   // undefined
    }
    func();
    

    控制台输出结果为:

    test
    test
    
    • 其他用法

    • 类数组

    这里把符合以下条件的对象称为类数组

    • 具有length属性

    • 按索引方式存储数据

    • 不具有数组的push,pop等方法

    常见类数组有 arguments,NodeList!

    (function(){
      Array.prototype.push.call(arguments,4);
      console.log(arguments);
    })(1,2,3)
    

    控制台输出结果为:

    [1, 2, 3, 4]
    

    这样就往arguments中push一个4进去了

    • Array.prototype.push 页可以实现两个数组合并

    同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN) 所以同样也可以通过apply来装换一下这个数组,即:

    var arr1=new Array("1","2","3"); 
    var arr2=new Array("4","5","6"); 
    Array.prototype.push.apply(arr1,arr2); 
    console.log(arr1);
    

    控制台输出结果为:

    ["1", "2", "3", "4", "5", "6"]
    

    也可以这样理解,arr1调用了push方法,参数是通过apply将数组装换为参数列表的集合.

    • 求类数组中的最大值
    (function(){
      var maxNum = Math.max.apply(null,arguments);
      console.log(maxNum);
    })(34,2,56);
    

    控制台输出结果为:

    56
    
    • 判断类型
    console.log(Object.prototype.toString.call(123)) 
    console.log(Object.prototype.toString.call('123')) 
    console.log(Object.prototype.toString.call(undefined)) 
    console.log(Object.prototype.toString.call(true)) 
    console.log(Object.prototype.toString.call({}))
    console.log(Object.prototype.toString.call([])) 
    console.log(Object.prototype.toString.call(function(){})) 
    

    控制台输出结果为:

    [object Number]
    [object String]
    [object Undefined]
    [object Boolean]
    [object Object]
    [object Array]
    [object Function]
    

    注:文章内容参考网络,后整理。

    相关文章

      网友评论

          本文标题:前端学习笔记--apply()和call()

          本文链接:https://www.haomeiwen.com/subject/aaqftftx.html