如何实现一个new

new做了什么

官方的解释:

1
2
3
4
5
6
7
8
9
10
new 关键字会进行如下的操作:
1. 创建一个空的简单JavaScript对象(即{});
2. 链接该对象(设置该对象的constructor)到另一个对象;
3. 将步骤1新创建的对象作为this的上下文;
4. 如果该函数没有返回对象,则返回this。

当代码 new Foo(...) 执行时,会发生以下事情:
1. 一个继承自 Foo.prototype 的新对象被创建;
2. 使用指定的参数调用构造函数 Foo,并将 this 绑定到新创建的对象。new Foo 等同于 new Foo(),也就是没有指定参数列表,Foo 不带任何参数调用的情况。
3. 由构造函数返回的对象就是 new 表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)

即 new 操作符其实做了这些事情:

  1. 创建一个新对象;
  2. 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象) ;
  3. 执行构造函数中的代码(为这个新对象添加属性) ;
  4. 如果构造函数没有显式返回一个对象,就返回步骤1创建的新对象,否则返回构造函数的结果。

    简单实现

    1
    2
    3
    4
    5
    6
    function myNew() {
    const constr = Array.prototype.shift.call(arguments);
    const obj = Object.create(constr.prototype);
    const result = constr.apply(obj, arguments);
    return result instanceof Object ? result : obj;
    }
    测试如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    }
    Person.prototype.sayName = function() {
    console.log(this.name);
    }
    // var person = new Person('cxs', 21, 'Front-end developer');
    var person = myNew(Person, 'cxs', 21, 'Front-end developer');
    console.log(person.name) // cxs
    person.sayName(); // cxs
    console.log(person.__proto__ === Person.prototype); // true
    显式返回对象的情况:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    return {
    love: "前端"
    };
    }
    var person = myNew(Person, 'cxs', 21, 'Front-end developer');
    console.log(person.name); // undefined
    console.log(person.love); // 前端
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2020-2021 苏御
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信