原生JS重写Function.prototype.bind( )方法

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    Function.prototype.myBind = function (context) {
     
     
      // fn.bind(obj) fn必须为函数,否则会报错
      if (typeof this !== "function") {
     
     
        throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
      }

      var self = this; // 这里的this是调用bind()方法的函数(fn),保存给 self
      var args = Array.prototype.slice.call(arguments, 1); // 获取 myBind函数 从第二个参数到最后一个参数
      var fNOP = function () {
     
     }; // 使用圣杯模式来继承时的中间函数

      var fbound = function () {
     
     
        // 当作为构造函数时,this 指向实例,self 指向绑定函数,因为下面一句 `fbound.prototype = this.prototype;`,已经修改了 fbound.prototype 为 绑定函数的 prototype,此时结果为 true,当结果为 true 的时候,this 指向实例。
        // 当作为普通函数时,this 指向 window,self 指向绑定函数,此时结果为 false,当结果为 false 的时候,this 指向绑定的 context。

        self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments)));
        // 上面的 arguments 是 fbound函数(返回的新函数) 的实参
      }

      fNOP.prototype = self.prototype;
      fbound.prototype = new fNOP();

      return fbound;
    }

    // 测试重写后的效果
    var value = 2;

    var foo = {
     
     
        value: 1
    };

    function bar(name, age) {
     
     
        this.habit = 'shopping';
        console.log(this.value);
        console.log(name);
        console.log(age);
    }

    bar.prototype.friend = 'kevin';

    var bindFoo = bar.bind(foo, 'daisy');

    var obj = new bindFoo('18');
    // undefined
    // daisy
    // 18
    console.log(obj.habit); // shopping
    console.log(obj.friend); // kevin
    console.log(obj);
    
    

  </script>
</body>
</html>

在这里插入图片描述
本文学习链接

猜你喜欢

转载自blog.csdn.net/qq_27575925/article/details/113739773
今日推荐