• 深入浅出妙用 Javascript 中 apply、call、bind


    原文地址:深入浅出妙用 Javascript 中 apply、call、bind

    apply、call

    在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。

    JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。

    先来一个栗子:
    eg1:

    function fruits() {}
    
    fruits.prototype = {
    color: "red",
    say: function() {
    console.log("My color is " + this.color);
    }
    }
    
    var apple = new fruits;
    
    banana = {
    color: "yellow"
    }
    apple.say.call(banana); //My color is yellow
    apple.say.apply(banana); //My color is yellow



    但是如果我们有一个对象banana= {color : "yellow"} ,我们不想对它重新定义 say 方法,那么我们可以通过 call 或 apply 用 apple 的 say 方法。

    所以,可以看出 call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法(本栗子中banana没有say方法),但是其他的有(本栗子中apple有say方法),我们可以借助call或apply用其它对象的方法来操作。


     apply、call 的区别

    对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。例如,有一个函数定义如下:

    var func = function(arg1, arg2) {
    
    };


    就可以通过如下方式来调用:

    func.call(this, arg1, arg2);
    func.apply(this, [arg1, arg2])


    其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。  

    JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时用 call 。

    而不确定的时候用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数。

    拜读此文后,思索:


    问题1:

    eg2:

    var numbers = [5, 458 , 120 , -215 ];
    Math.max.apply(numbers);
    -Infinity


    给numbers绑定Math.max为什么不行?

    而此方式却可以:

    eg3:

    var numbers = [5, 458 , 120 , -215 ];
    var maxInNumbers = Math.max.apply(Math, numbers); //458


    分析:
    当任意声明一个空对象:

    eg4:

    var numbers = [5, 458 , 120 , -215 ];
    var obj = {};
    Math.max.apply(obj,numbers); //458


    所以,可以看出:Math.max方法是需要传参,而需要进行比较的数组numbers不是作为this指向的对象obj,而是作为比较的参数传入。与eg1中不同的是,是否需要参数。

    问题2:

    对象方法继承的有效期多久?是继承后一直拥有吗?还是只存在call ,apply方法运行时?

    eg5:

    function fruits() {}
    
    fruits.prototype = {
    color: "red",
    say: function() {
    console.log("My color is " + this.color);
    }
    }
    
    var apple = new fruits;
    
    banana = {
    color: "yellow"
    }
    apple.say.call(banana); //My color is yellow
    console.log(banana);//Object{color: "yellow",__proto__: Object}


    分析:
    banana没有say方法。所以,利用call ,apply方法继承后是有期限的,只是在函数「运行时上下文」有效。

  • 相关阅读:
    golang垃圾回收和SetFinalizer
    读《我编程,我快乐--程序员职业规划之道》
    golang cache--go-cache
    golang web framework--Martini
    golang http proxy反向代理
    php 设计模式之简单工厂模式
    php 设计模式之责任链模式
    什么是反向索引
    ip地址二进制转十进制
    架构师之路
  • 原文地址:https://www.cnblogs.com/xmyun/p/6404976.html
走看看 - 开发者的网上家园