• js的apply 和 call区别


    相同点:

    1.两者都用于改变函数上下文,第一个参数就是用来指定函数执行时的上下文。

    2.两者实现时都调用函数的内置函数[[Call]]。

    3.第一个参数为null或undefined,则用全局对象替换this。

    区别:

    1. 除了第一个参数,apply的第二个参数表示传入被调用函数的参数数组,call除了第一个参数外,后面的参数都是传入函数的参数是参数列表,

    2.两者还有个执行效率上的差别,以前看别人代码的时候传一个函数参数的时候(除了第一个this参数),用apply,多个参数的时候用call,一个为什么飘忽一过就过了。。。

    规范上两者大致的实现算法,明显apply复杂些,要把数组转参数列表再调用内部[[Call]]中间步骤比用call多。

    多的步骤主要是将数组构造为参数列表所需的步骤,取数组的长度,将数组数字索引转为字符形式索引,然后取数组值赋值给对应参数列表中。

    3.函数默认形参个数length不同,规范上call除了第一个参数后面的都是可选的,apply则是两个参数,call.length =1, apply.length = 2 (算区别?)

    ECMA 5.1 规范:

    15.3.4.3Function.prototype.apply (thisArg, argArray)

    When the apply method is called on an object func with arguments thisArg and argArray, the following steps are taken:

    1. If IsCallable(func) is false, then throw a TypeError exception.
    2. If argArray is null or undefined, then
      1. Return the result of calling the [[Call]] internal method of func, providing thisArg as the this value and an empty list of arguments.
    3. If Type(argArray) is not Object, then throw a TypeError exception.
    4. Let len be the result of calling the [[Get]] internal method of argArray with argument "length".
    5. Let n be ToUint32(len).
    6. Let argList be an empty List.
    7. Let index be 0.
    8. Repeat while index < n
      1. Let indexName be ToString(index).
      2. Let nextArg be the result of calling the [[Get]] internal method of argArray with indexName as the argument.
      3. Append nextArg as the last element of argList.
      4. Set index to index + 1.
    9. Return the result of calling the [[Call]] internal method of func, providing thisArg as the this value and argList as the list of arguments.

    The length property of the apply method is 2.

    NOTEThe thisArg value is passed without modification as the this value. This is a change from Edition 3, where a undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value.

    15.3.4.4Function.prototype.call (thisArg [ , arg1 [ , arg2, … ] ] )

    When the call method is called on an object func with argument thisArg and optional arguments arg1arg2etc, the following steps are taken:

    1. If IsCallable(func) is false, then throw a TypeError exception.
    2. Let argList be an empty List.
    3. If this method was called with more than one argument then in left to right order starting with arg1append each argument as the last element of argList
    4. Return the result of calling the [[Call]] internal method of func, providing thisArg as the this value and argList as the list of arguments.

    The length property of the call method is 1.

    NOTEThe thisArg value is passed without modification as the this value. This is a change from Edition 3, where a undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value.

    关于效率问题:underscore中函数剩余参数用数组接收返回

     1   var restArguments = function(func, startIndex) {
     2     startIndex = startIndex == null ? func.length - 1 : +startIndex;
     3     return function() {
     4       var length = Math.max(arguments.length - startIndex, 0),
     5           rest = Array(length),
     6           index = 0;
     7       for (; index < length; index++) {
     8         rest[index] = arguments[index + startIndex];
     9       }
    10       switch (startIndex) {
    11         case 0: return func.call(this, rest);//所有参数都从数组中接收
    12         case 1: return func.call(this, arguments[0], rest);
    13         case 2: return func.call(this, arguments[0], arguments[1], rest);
    14       }
    15       var args = Array(startIndex + 1);
    16       for (index = 0; index < startIndex; index++) {
    17         args[index] = arguments[index];
    18       }
    19       args[startIndex] = rest;
    20       return func.apply(this, args);//数组传参
    21     };
    22   };

    https://stackoverflow.com/questions/1986896/what-is-the-difference-between-call-and-apply

    http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.4.3

  • 相关阅读:
    Python之路【第二十九篇】:面向对象基础
    Python之路【第二十八篇】:生成器与迭代器
    爬虫实战---爬取猫眼电影
    Selenium库详解
    PyQuery库详解
    BeautifulSoup解析库详解
    深浅拷贝的使用场景分析
    关于大数据量下Core Data的数据迁移
    IOS5中的新增方法详解
    自定义UISearchBar
  • 原文地址:https://www.cnblogs.com/xiaozhuyuan/p/8904456.html
Copyright © 2020-2023  润新知