JTangming / blog

My repository on GitHub.
Other
53 stars 0 forks source link

实现 new 操作符 #35

Open JTangming opened 4 years ago

JTangming commented 4 years ago

实例代码:

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 (新对象)。如果返回的是引用类型,则返回该返回值。(可以自己在上面例子加上代码验证一下)

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 commented 4 years ago

JavaScript深入之call和apply的模拟实现 JavaScript深入之bind的模拟实现 JavaScript深入之new的模拟实现

可以参考冴羽的博客

BowenXiao1999 commented 4 years ago

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