YBFACC / blog

仅记录个人学习使用
3 stars 0 forks source link

奇怪的Function.prototype.call.bind() #40

Open YBFACC opened 3 years ago

YBFACC commented 3 years ago

奇怪的Function.prototype.call.bind()

Function.prototype.call.bind() 今天第一次在掘金上看到了这样的使用方法。

这样的用法看的我一脸蒙蔽。

这里我们找2个垫片,方便我们调试。

Function.prototype.mybind = function () {
    var slice = Array.prototype.slice
    var thatFunc = this,
        thatArg = arguments[0]
    var args = slice.call(arguments, 1)
    if (typeof thatFunc !== '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'
        )
    }
    return function () {
        var funcArgs = args.concat(slice.call(arguments))
        return thatFunc.apply(thatArg, funcArgs)
    }
}
Function.prototype.mycall = function (context, ...args) {
    if (!context) {
        console.log('不存在')
        context = global
    }
    if (typeof context !== 'object') {
        console.log('不是对象')
        context = global
    }
    let say = Symbol() // 防止覆盖掉原有属性
    context[say] = this // 这里的this为需要执行的方法
    const res = context[say](...args)
    delete context[say]
    return res
}

Function.prototype.call()

先看一个简单的:

var fun = Function.prototype.mycall(Object.prototype.toString)

Object.prototype.toString.Function.prototype()

Function.prototype是函数的原型对象,所有函数都要继承它,相当于执行了一个空函数。

Function.prototype.mycall.mycall()

接下来是升级版:

var toStr1 = Function.prototype.mycall.mycall(Object.prototype.toString)

Object.prototype.toString.mycall()

Object.prototype.toString.call(global)

Function.prototype.mycall.mybind()

终极版:

var toStr1 = Function.prototype.mycall.mybind(Object.prototype.toString)

Function.prototype.mycall.myapply(Object.prototype.toString, [[123]])

这与其他函数不同,bind会返回一个绑定好this的闭包函数。

  1. 返回的是一个可执行的函数。它不会像上面两个例子一样不停往前执行。
  2. 相当于一个柯里化函数,可以再次向它传参数。

参考

原型

手写实现call,apply,bind

一句有趣的JS代码

js Function.prototype.call.bind(Array.prototype.slice),为啥要这么写?

在JavaScript中借用方法

JS魔法堂:再次认识Function.prototype.call

关于Function.prototype.call.bind()的疑惑?

jeff-zhenz commented 2 years ago

给出ref,好评👍