实现 new 操作符
Opened this issue · 2 comments
JTangming commented
实例代码:
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 commented
BowenXiao1999 commented
也就是说JS的实例是可以更改构造函数的prototype的。。。(通过__proto__)
刚刚自己写了个例子测试,真的吓一跳