Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

实现 new 操作符 #35

Open
JTangming opened this issue Nov 2, 2019 · 2 comments
Open

实现 new 操作符 #35

JTangming opened this issue Nov 2, 2019 · 2 comments

Comments

@JTangming
Copy link
Owner

JTangming commented Nov 2, 2019

实例代码:

function Person(name){ 
  this.name = name;
} 
Person.prototype.getName = function() {
    return this.name;
}

var p1 = new Person('Dan');

console.log(p1); // Person {name: "Dan"}
console.log(p1.__proto__ === Person.prototype); // true

new 操作符实现了如下的功能:

  • 创建一个新对象
  • 新对象的原型指向构造函数的原型对象性,即继承构造函数的原型
  • 改变构造函数 this 的指向到新建的对象,并执行构造函数
  • 判断返回的值是不是一个对象,若是则返回这个对象,否则返回新对象

构造函数如果返回基本类型,则还是会返回原来的 this (新对象)。如果返回的是引用类型,则返回该返回值。(可以自己在上面例子加上代码验证一下)

new 操作符的模拟实现

function createNew(func, ...args) {
    let obj = {};
    // 将空对象指向构造函数的原型链
    Object.setPrototypeOf(obj, func.prototype);
    // obj 绑定到构造函数上,便可以访问构造函数中的属性
    let result = func.apply(obj, args);
    // 如果返回的 result 是一个对象则返回该对象,new 方法失效,否则返回 obj
    return result instanceof Object ? result : obj;
}

Object.setPrototypeOf()是ECMAScript 6最新草案中的方法,相对于 Object.prototype.proto ,它被认为是修改对象原型更合适的方法

写个测试用例:

function Test(name, age) {
    this.name = name;
    this.age = age;
}

let test = createNew(Test, 'Dan', 20);
console.log(test.name); // Dan
console.log(test.age); // 20
@JTangming JTangming changed the title 哈希表 实现 new 操作符 Feb 1, 2020
@JTangming
Copy link
Owner Author

@BowenXiao1999
Copy link

也就是说JS的实例是可以更改构造函数的prototype的。。。(通过__proto__)
刚刚自己写了个例子测试,真的吓一跳

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants