A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 小小K 初级黑马   /  2021-1-27 16:44  /  2066 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小小K 于 2021-1-27 16:46 编辑

相同点:
  • 都可以改变函数执行上下文。
  • 第一个参数都是函数执行上下文
不同点:
  • 函数执行参数传参方式不同,[backcolor=rgba(0, 0, 0, 0.04)]apply 是用数组而 [backcolor=rgba(0, 0, 0, 0.04)]call,和 [backcolor=rgba(0, 0, 0, 0.04)]bind 是用单独传参
  • 返回值不同,[backcolor=rgba(0, 0, 0, 0.04)]apply[backcolor=rgba(0, 0, 0, 0.04)]call 都是返回函数执行后的返回值而 [backcolor=rgba(0, 0, 0, 0.04)]bind 返回值是改变了函数执行上下文的函数
Function.prototype.call
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
语法
fun.call(thisArg, arg1, arg2, …)
thisArg
在 fun 函数运行时指定的 this 值。
  • [AppleScript] 纯文本查看 复制代码
    if (thisArg == undefined | null) {
        this = window
    }
    // 所有类型
    if (thisArg == number | boolean | string | ...others) {
        this == new Number()|new Boolean()| new String() | new Others()
    }

arg1, arg2, …
指定的参数列表。
Function.prototype.apply
apply() 方法使用一个指定的 this 值和一个数组组成的参数列表来调用一个函数。
语法
fun.call(thisArg, [argsArray])
thisArg
在 fun 函数运行时指定的 this 值。
方式同apply
argsArray
一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象
Function.prototype.bind
bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。
语法
fun.bind(thisArg, arg1, arg2, …)
thisArg
在 fun 函数运行时指定的 this 值。
方式同apply
arg1, arg2, …
指定的参数列表。
进阶:实现 call, apply, bindcall
  • [AppleScript] 纯文本查看 复制代码
    Function.prototype.myCall = function (context, ...args) {
      // 上下文判断及赋值
      if (context === null || context === undefined) {
        context = window
      } else {
        context = Object(context)
      }
      // 给 context 新增一个不可枚举的且唯一的属性
      // 隐式绑定 this
      const _this = this
      const localProperty = Symbol('localProperty')
      Object.defineProperty(context, localProperty, {
        enumerable: false,
        value: _this
      })
      // 执行函数
      const result = context[localProperty](...args)
      // 删除新增的属性
      delete context[localProperty
      return result
    }

apply
  • [AppleScript] 纯文本查看 复制代码
    Function.prototype.myApply = function (context, args) {
      // 如果参数不是 array like 的就抛出错误
      if (!isArrayLike(args)) {
        throw new TypeError('CreateListFromArrayLike called on non-object')
      }
      // 上下文判断及赋值
      if (context === null || context === undefined) {
        context = window
      } else {
        context = Object(context)
      }
      // 给 context 新增一个不可枚举的且唯一的属性
      // 隐式绑定 this
      const _this = this
      const localProperty = Symbol('localProperty')
      Object.defineProperty(context, localProperty, {
        enumerable: false,
        value: _this
      })
      // 执行函数
      const result = context[localProperty](...args)
      // 删除新增的属性
      delete context[localProperty
      return result
    }

bind
MDN polyfill
  • [AppleScript] 纯文本查看 复制代码
    if (!Function.prototype.bind) {
      Function.prototype.bind = function(oThis, ...aArgs) {
        if (typeof this !== 'function') {
          // closest thing possible to the ECMAScript 5
          // internal IsCallable function
          throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
        }
        const fToBind = this;
        const fNOP = function() {};
        const fBound  = function(...fBoundArg) {
          // this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用
          return fToBind.apply(
            this instanceof fBound
              ? this
              : oThis,
              // 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
            aArgs.concat(fBoundArg)
          );
        };
        // 维护原型关系
        if (this.prototype) {
          // 当执行Function.prototype.bind()时, this为Function.prototype
          // this.prototype(即Function.prototype.prototype)为undefined
          fNOP.prototype = this.prototype;
        }
        // 下行的代码使fBound.prototype是fNOP的实例,因此
        // 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
        fBound.prototype = new fNOP();
        return fBound;
      };
    }


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马