Code Monkey home page Code Monkey logo

Comments (2)

fedono avatar fedono commented on May 28, 2024

实现 bind

// 来自MDN https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
//  Yes, it does work with `new (funcA.bind(thisArg, args))`
if (!Function.prototype.bind) (function(){
  var ArrayPrototypeSlice = Array.prototype.slice;
  Function.prototype.bind = function(otherThis) {
    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');
    }

    var baseArgs= ArrayPrototypeSlice.call(arguments, 1),
        baseArgsLength = baseArgs.length,
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          baseArgs.length = baseArgsLength; // reset to default base arguments
          baseArgs.push.apply(baseArgs, arguments);
          return fToBind.apply(
                 fNOP.prototype.isPrototypeOf(this) ? this : otherThis, baseArgs
                 // fNOP.prototype.isPrototypeOf(this) 是为了判断当前函数是否使用了new,因为new 会重新创建this,
                // 如果使用了new ,那么就使用new 创建的 this,否则就使用 bind 传过来的 this 对象
          );
        };
    
    // 这里也是判断是否使用了 new,如果使用了,就使用当前函数的 prototype
    if (this.prototype) {
      // Function.prototype doesn't have a prototype property
      fNOP.prototype = this.prototype; 
    }
    fBound.prototype = new fNOP();

    return fBound;
  };
})();

bind 还有个作用,就是可以预绑定一些参数

function foo(a, b) {
    console.log(a, b, '---a b');
}

let bar = foo.bind(null, 2); // 在 bind 的时候,可以先绑定一个参数
bar(3);

还有一个是不用 call / apply 来实现 bind,这个在 B 站的视频中有看到,得回去找找,应该是 工作-好 那个收藏夹

from fe-questions.

fedono avatar fedono commented on May 28, 2024

实现 new

  1. 创建一个空的简单JavaScript对象(即{});
  2. 链接该对象(即设置该对象的构造函数)到另一个对象 ;
  3. 将步骤1新创建的对象作为this的上下文 ;
  4. 如果该函数没有返回对象,则返回this。
function new_(){
    let args = arguments;
    //创建一个空对象
    let obj = new Object();
    //获取构造函数
    let Constructor = [].shift.call(args);
    //链接到原型
    obj.__proto__ = Constructor.prototype;
    //绑定this值
    let result = Constructor.apply(obj, args);//使用apply,将构造函数中的this指向新对象,这样新对象就可以访问构造函数中的属性和方法
    //返回新对象
    return Object.prototype.toString.call(result) === "[object Object]" ? result : obj;//如果返回值是一个对象就返回该对象,否则返回构造函数的一个实例对象
}

参考mdn-new

from fe-questions.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.