• 理解javascript里的ABC--apply bind call


    一,三者共同点

    js中的apply,call,bind是对于初学者比较难的概念之一,比如说我。。参考几篇文章之后,统一来讲,

    1、这三个函数都属于Function.prototype下面的方法,如下图所示。从而可以被每一个函数实例所调用。

    2、他们的作用都是改变函数的执行上下文。举个例子:

    var a=1;
    function printA(){
    console.log(this.a);
    }
    var obj={a:2};
    printA();//相当于window.printA(),此时this指向window/global对象

    现在我想打印obj里面的a,可以这么做:


    obj.printA=printA;//将函数作为obj对象的方法 obj.printA();//调用该方法

    还可以这么做:

    printA.call(obj); //利用call将obj作为printA的上下文,this指向obj
    printA.apply(obj); //利用apply将obj作为printA的上下文,this指向obj
    var objPrintA=printA.bind(obj); //利用bind将obj作为printA的上下文,this指向obj,并让objPrintA变量名作为返回的新函数的引用
    objPrintA();

    上面的三种方法都成功的访问到了obj里的a;

    但是注意bind的用法,printA.bind(obj)仅仅将printA的上下文改变,并返回一个新函数,称为绑定函数。但是并没有立刻执行,需要手动调用新函数objPrintA来执行它。

    3、call、apply、bind都可以在第一个参数后传入别的参数,作为函数的参数传入

    第一个参数除了普通的对象之外,还可以传入以下值:

    (1) 不传,或者传入null,undefined,函数中的this指向window对象。

    (2)传递另一个函数的函数名,函数的this指向这个函数的引用。

    (3)传递字符串、数值或者布尔值等基础类型,函数中的this指向其对应的包装对象,String,Number,Boolean

    (4)传递一个对象,函数中的this指向该对象。

    function printThis(){
    console.log(this);
    }
    printThis.call(); //[object Window]
    printThis.call(null); //[object Window]
    printThis.call(undefined);//[object Window]
    printThis.call(1);//[object Number]
    printThis.call('1');//[object String]
    printThis.call(true);//[object Boolean]
    printThis.call({a:1});//[object Object]{a: 1}
    printThis.call(function(a){console.log(a)});//function (a){console.log(a)}
    

    二,call与apply的区别

    前面区分了bind与call,apply的区别,bind会返回一个新的绑定上下文之后的函数,而call和apply是会立即执行函数。下面的例子实现了es3对原生bind()方法的模拟,更能说明这个区别。

    function bind(f,o){
    if(f.bind) return f.bind(o);//如果有原生bind,则直接调用
    else return function(){//返回一个新的函数,调用这个函数会在o对象的上下文中执行
    return f.apply(o,arguments);
    }
    }

    call和apply的区别在于apply接受一个数组参数,所以当你的参数是明确知道数量时用 call,当参数不固定时应该用apply 。一个应用情景就是arguments和apply比较配

    arguments是函数的一个内部属性:

    function a(){
     console.log(arguments);
     console.log(a.arguments);
     console.log(this.arguments);   
    }
    obj={arguments:'arguments'}
    a();
    /*
    [object Arguments]{length: 0}
    [object Arguments]{length: 0}
    undefined
    */
    a(1,'1',true);
    /*
    [object Arguments]{0: 1, 1: "1", 2: true, length: 3}
    [object Arguments]{0: 1, 1: "1", 2: true, length: 3}
    undefined
    */
    a.call(obj);
    /*
    [object Arguments]{length: 0}
    [object Arguments]{length: 0}
    arguments
    */

    上面这个例子表明arguments是函数对象的一个属性,在函数内部可以直接通过arguments[i]来访问实参。还说明了this绝对不是指向函数本身。

    最后举一个求平方和的例子。

    function sum(){
    var args=Array.prototype.slice.apply(arguments);
    return args.reduce(function(prev,next){return prev+next*next},0);
    }
    sum(1,2,4,6,8)//121

    参考文章:深入浅出 妙用Javascript中apply、call、bind

  • 相关阅读:
    20155219 2017-2018-1 《信息安全系统设计》第4周学习总结
    20155219 2017-2018-1 《信息安全系统设计》第3周学习总结
    20155219实践题目实现od命令
    20155219 2017-2018-1 《信息安全系统设计》第4周课堂实践
    2017-2018-1 20155219《信息安全系统设计基础》第1周学习总结
    课堂实践6-7
    20155219 实验五《网络编程与安全》实验报告
    20155219 2016-2017-2《Java程序设计》课程总结
    20155212 mybash的实现
    20155212 2017-2018-1 《信息安全系统设计》第5周学习总结
  • 原文地址:https://www.cnblogs.com/imgss/p/6106607.html
Copyright © 2020-2023  润新知