美文网首页
JavaScript中的call、apply和bind方法

JavaScript中的call、apply和bind方法

作者: 流浪的三鮮餡 | 来源:发表于2019-05-08 14:45 被阅读0次

    JavaScript中的call(), apply()和bind()是Function.prototype下的方法,都是用于改变函数运行时上下文,最终的返回值是你调用的方法的返回值,若该方法没有返回值,则返回undefined。这几个方法很好地体现了js函数式语言特性,在js中几乎每一次编写函数式语言风格的代码,都离不开call和apply。

    1. call()

    • 描述:
      call()方法使用一个指定的this值和单独给出的一个或多个参数来调用一个函数。
      call()允许为不同的对象分配和调用属于一个对象的函数/方法。
      call()提供新的 this 值给当前调用的函数/方法。你可以使用 call 来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。
    • 语法
    function.call(thisArg, arg1, arg2, ...)
    
    • 参数:
      thisArg
      function 函数运行时指定的 this需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数在[非严格模式]下运行,则指定为 nullundefinedthis 值会自动指向全局对象(浏览器中就是 window 对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。
      arg1, arg2, ...
      指定的参数列表。
    • 返回值:
      使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined。
    • 示例:
    function Product(name, price) {
      this.name = name;
      this.price = price;
    }
    
    function Food(name, price) {
      Product.call(this, name, price);
      this.category = 'food';
    }
    
    console.log(new Food('cheese', 5).name);
    // expected output: "cheese"
    

    2. apply()

    • 描述
      apply() 方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。
      在调用一个存在的函数时,你可以为其制定一个this对象,this指当前对象,也就是正在调用这个函数的对象。使用apply,你可以只写一次这个方法然后在另一个对象中继承它,而不用在新对象中重复写该方法。
      applycall() 非常相似,不同之处在于提供参数的方式。apply 使用参数数组而不是一组参数列表。apply 可以使用数组字面量(array literal),如 fun.apply(this, ['eat', 'bananas']),或数组对象, 如 fun.apply(this, new Array('eat', 'bananas'))
      你也可以使用 arguments对象作为 argsArray 参数。 arguments 是一个函数的局部变量。 它可以被用作被调用对象的所有未指定的参数。 这样,你在使用apply函数的时候就不需要知道被调用对象的所有参数。 你可以使用arguments来把所有的参数传递给被调用对象。 被调用对象接下来就负责处理这些参数。
      从 ECMAScript 第5版开始,可以使用任何种类的类数组对象,就是说只要有一个 length 属性和(0..length-1)范围的整数属性。例如现在可以使用 NodeList 或一个自己定义的类似 {'length': 2, '0': 'eat', '1': 'bananas'} 形式的对象。

    需要注意:Chrome 14 以及 Internet Explorer 9 仍然不接受类数组对象。如果传入类数组对象,它们会抛出异常。

    • 语法
    function.apply(thisArg, [argsArray])
    
    • 参数
      thisArg
      可选的。在 function 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 nullundefined 时会自动替换为指向全局对象,原始值会被包装。
      argsArray
      可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给function函数。如果改参数的值为nullundefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。
    • 返回值
      调用有指定this值和参数的函数的结果。
    • 示例
    var numbers = [5, 6, 2, 3, 7];
    
    var max = Math.max.apply(null, numbers);
    
    console.log(max);
    // expected output: 7
    
    var min = Math.min.apply(null, numbers);
    
    console.log(min);
    // expected output: 2
    
    

    3. bind()

    • 描述
      bind()方法创建一个新的函数,在调用时设置this关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。
      bind() 函数会创建一个新绑定函数(bound function,BF)。绑定函数是一个exotic function object(怪异函数对象,ECMAScript 2015中的术语),它包装了原函数对象。调用绑定函数通常会导致执行包装函数
      绑定函数具有以下内部属性:
      [[BoundTargetFunction]] - 包装的函数对象
      [[BoundThis]] - 在调用包装函数时始终作为this值传递的值。
      [[BoundArguments]] - 列表,在对包装函数做任何调用都会优先用列表元素填充参数列表。
      [[Call]] - 执行与此对象关联的代码。通过函数调用表达式调用。内部方法的参数是一个this值和一个包含通过调用表达式传递给函数的参数的列表。
      当调用绑定函数时,它调用[[BoundTargetFunction]]上的内部方法[[Call]],就像这样Call(boundThis, args)。其中,boundThis[[BoundThis]]args[[BoundArguments]]加上通过函数调用传入的参数列表。
      绑定函数也可以使用new运算符构造,它会表现为目标函数已经被构建完毕了似的。提供的this值会被忽略,但前置参数仍会提供给模拟函数。
    • 语法
    function.bind(thisArg[, arg1[, arg2[, ...]]])
    
    • 参数
      thisArg
      调用绑定函数时作为this参数传递给目标函数的值。 如果使用new运算符构造绑定函数,则忽略该值。当使用bindsetTimeout中创建一个函数(作为回调提供)时,作为thisArg传递的任何原始值都将转换为object。如果bind函数的参数列表为空,执行作用域的this将被视为新函数的thisArg
      arg1, arg2, ...
      当目标函数被调用时,预先添加到绑定函数的参数列表中的参数。
    • 返回值
      返回一个原函数的拷贝,并拥有指定的this值和初始参数。
    • 示例
    var module = {
      x: 42,
      getX: function() {
        return this.x;
      }
    }
    
    var unboundGetX = module.getX;
    console.log(unboundGetX()); // The function gets invoked at the global scope
    // expected output: undefined
    
    var boundGetX = unboundGetX.bind(module);
    console.log(boundGetX());
    // expected output: 42
    

    相关文章

      网友评论

          本文标题:JavaScript中的call、apply和bind方法

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