// 第一个参数为构造函数: 内部具有this属性的非箭头函数,
function _new(constructor, ...rest) {
// 传入Object.create的对象, 最终会放到新对象的__proto__属性上
var context = Object.create(constructor.prototype);
// 执行构造函数, 让函数向this这个对象上添加属性, 并且把this从window改为需要return的对象
var result = constructor.apply(context, rest);
// new 操作符总是返回一个对象, 如果不是对象会被忽略并返回{}
return (typeof result === 'object' && result != null) ? result : context
}
function Person(name, age){
this.name = name;
this.age = age;
}
var actor = _new(Person, '张三', 28)
new 命令的作用 , 执行构造函数,返回一个实例对象 var obj = new Object()
一、 将一个空对象的 __propto__ 设为构造函数的prototype属性
对象具有一个名叫 __proto__ 的属性, __proto__ 的值为对象
函数具有一个名为 prototype 的属性, prototype 属性的值为对象
=== 符号判断两个对象,结果为true, 说明两个对象指向同一块内存地址, 意味着需要用到 = 赋值
如何完全的克隆 函数.prototype 对象呢?
JavaScript 提供了Object.create()方法,用来满足这种需求。该方法接受一个对象作为参数,然后以它为原型,返回一个实例对象。该实例完全继承原型对象的属性。
var A = {
print: function () {
console.log('hello');
}
};
// 实例对象
var B = Object.create(A);
console.log(B)
新建一个空的构造函数F,然后让F.prototype属性指向参数对象obj,最后返回一个F的实例,从而实现让该实例继承obj的属性。
Object.create = function(){
function F() {};
F.prototype = obj;
return new F();
}
需要实现: return出来的对象与传入的函数使用同一个内存地址
二、 this 指向问题
- 不用
new调用, 内部的this是window对象; - 用
new调用, 内部的this是return出来的那个对象,
var Vehicle = function (){
this.price = 1000;
};
var v = Vehicle();
v // undefined
price // 1000
这是构造函数,做的事情是向this 这个对象中添加属性;
额外提一点, 构造函数会挂载到 Vehicle.prototype.constructor 属性上, 所以有 Vehicle === Vehicle.prototype.constructor
普通函数(区别于箭头函数,箭头函数没有自己的this,也就不能做为构造函数)内部的 this 是一个对象, 独立调用时指向 window , 作为对象的方法调用时,指向调用对象
Vehicle 内部的 this 是 window 对象;
总结: 需要修改内部的this指向, 从window改到 待 return 出来的对象
最后, return 出来的对象, 需要有函数中设置的属性, 如上面的 price 属性, 如果添加属性呢? 只需要调用它, 让它向this上挂载属性就行
// 第一个参数为构造函数: 内部具有this属性的非箭头函数,
function _new(constructor, ...rest) {
// 传入Object.create的对象, 最终会放到新对象的__proto__属性上
var context = Object.create(constructor.prototype);
// 执行构造函数, 让函数向this这个对象上添加属性, 并且把this从window改为需要return的对象
var result = constructor.apply(context, rest);
// new 操作符总是返回一个对象, 如果不是对象会被忽略并返回{}
return (typeof result === 'object' && result != null) ? result : context
}
function Person(name, age){
this.name = name;
this.age = age;
}
var actor = _new(Person, '张三', 28)
参考: