我最近偶然发现了JavaScript中的object .create()方法,并试图推断它与使用new SomeFunction()创建对象的新实例有何不同,以及当您想要使用其中一个而不是另一个时。
考虑下面的例子:
var test = {
val: 1,
func: function() {
return this.val;
}
};
var testA = Object.create(test);
testA.val = 2;
console.log(test.func()); // 1
console.log(testA.func()); // 2
console.log('other test');
var otherTest = function() {
this.val = 1;
this.func = function() {
return this.val;
};
};
var otherTestA = new otherTest();
var otherTestB = new otherTest();
otherTestB.val = 2;
console.log(otherTestA.val); // 1
console.log(otherTestB.val); // 2
console.log(otherTestA.func()); // 1
console.log(otherTestB.func()); // 2
请注意,在这两种情况下观察到相同的行为。在我看来,这两种情况的主要区别是:
在object .create()中使用的对象实际上形成了新对象的原型,而在new Function()中声明的属性/函数不形成原型。
不能像使用函数式语法一样使用Object.create()语法创建闭包。考虑到JavaScript的词法(相对于块)类型范围,这是合乎逻辑的。
上述说法正确吗?我是不是遗漏了什么?什么时候你会使用其中一种而不是另一种?
编辑:链接到上述代码示例的jsfiddle版本:http://jsfiddle.net/rZfYL/
Object.create(Constructor.prototype)是new Constructor的一部分
这是新的构造函数实现
// 1. define constructor function
function myConstructor(name, age) {
this.name = name;
this.age = age;
}
myConstructor.prototype.greet = function(){
console.log(this.name, this.age)
};
// 2. new operator implementation
let newOperatorWithConstructor = function(name, age) {
const newInstance = new Object(); // empty object
Object.setPrototypeOf(newInstance, myConstructor.prototype); // set prototype
const bindedConstructor = myConstructor.bind(newInstance); // this binding
bindedConstructor(name, age); // execute binded constructor function
return newInstance; // return instance
};
// 3. produce new instance
const instance = new myConstructor("jun", 28);
const instance2 = newOperatorWithConstructor("jun", 28);
console.log(instance);
console.log(instance2);
new构造函数实现包含Object。创建方法
newOperatorWithConstructor = function(name, age) {
const newInstance = Object.create(myConstructor.prototype); // empty object, prototype chaining
const bindedConstructor = myConstructor.bind(newInstance); // this binding
bindedConstructor(name, age); // execute binded constructor function
return newInstance; // return instance
};
console.log(newOperatorWithConstructor("jun", 28));