美文网首页
js中call、apply和bind

js中call、apply和bind

作者: 小溪流jun | 来源:发表于2021-07-26 08:52 被阅读0次
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>call和apply和bind</title>
</head>
<style>
    #app {
        color: #000;
    }
</style>

<body>
    <div id="app">

    </div>
    <script>
        /* 
            call、apply和bind
                1,call()、apply()、bind() 都是用来重定义 this 这个对象的!
                2,bind 返回的是一个新的函数,你必须调用它才会被执行。 
                3,apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,['成都', ..., 'string' ])。第一个参数是想改变的this指向
        */
        //手写call函数
        Function.prototype.myCall = function (context) {
            // 先判断调用myCall是不是一个函数
            // 这里的this就是调用myCall的
            if (typeof this !== 'function') {
                throw new TypeError("Not a Function")
            }

            // 不传参数默认为window
            context = context || window
            // 保存this
            context.fn = this

            // 保存参数
            //arguments 是一个对应于传递给函数的参数的类数组对象。
            let args = Array.from(arguments).slice(1)   //Array.from 把伪数组对象转为数组

            // 调用函数
            let result = context.fn(...args)

            delete context.fn

            return result
        }
        //手写apply函数
        Function.prototype.myApply = function (context) {
            // 判断this是不是函数
            if (typeof this !== "function") {
                throw new TypeError("Not a Function")
            }

            let result

            // 默认是window
            context = context || window

            // 保存this
            context.fn = this

            // 是否传参
            if (arguments[1]) {
                result = context.fn(...arguments[1])
            } else {
                result = context.fn()
            }
            delete context.fn

            return result
        }
        //手写bind函数
        Function.prototype.myBind = function (context) {
            // 判断是否是一个函数
            if (typeof this !== "function") {
                throw new TypeError("Not a Function")
            }
            // 保存调用bind的函数
            const _this = this
            // 保存参数
            const args = Array.prototype.slice.call(arguments, 1)
            // 返回一个函数
            return function F() {
                // 判断是不是new出来的
                if (this instanceof F) {
                    // 如果是new出来的
                    // 返回一个空对象,且使创建出来的实例的__proto__指向_this的prototype,且完成函数柯里化
                    return new _this(...args, ...arguments)
                } else {
                    // 如果不是new出来的改变this指向,且完成函数柯里化
                    return _this.apply(context, args.concat(...arguments))
                }
            }
        }
    </script>
</body>

</html>

相关文章

网友评论

      本文标题:js中call、apply和bind

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