我想知道这之间有什么区别
MyClass = function() {};
MyClass.prototype.Foo = function();
还有这个
MyClass = {};
MyClass.prototype.constructor = function() {};
MyClass.prototype.Foo = function();
在 JavaScript 中为原型(prototype)声明构造函数时。
与常规函数相比,使用 prototype.constructor
有什么优势?
最佳答案
看看下图,取自 following answer :
当您创建一个新函数时,JavaScript 也会自动创建一个新对象(原型(prototype)):
- JavaScript 将构造函数的
prototype
属性设置为原型(prototype)对象。 - JavaScript 将原型(prototype)对象的
constructor
属性设置为构造函数。
因此当你这样做时:
function Foo() {}
JavaScript 实际上是这样的:
function Foo() {}
Foo.prototype = { constructor: Foo };
为什么 JavaScript 会这样做?考虑一下当您创建 Foo
的实例时会发生什么:
var foo = new Foo;
当您使用 new
关键字创建 Foo
的实例时,JavaScript 实际上创建的是 Foo.prototype
的实例,而不是 富
。这意味着 foo
继承了 Foo.prototype
而不是 Foo
的属性。为了明确这一点:
function Foo() {}
Foo.bar = true;
Foo.prototype.baz = true;
var foo = new Foo;
console.log(foo.bar); // undefined
console.log(foo.baz); // true
现在在原型(prototype)上有一个 constructor
属性的好处是,当你创建一个 Foo
的实例时,该实例继承了 constructor
来自原型(prototype)的属性。因此,您可以使用它来找出对象的类型:
function Foo() {}
function Bar() {}
function test(obj) {
switch (obj.constructor) {
case Foo: console.log("It's a Foo."); break;
case Bar: console.log("It's a Bar."); break;
default: console.log("It's something else.");
}
}
test(new Foo);
test(new Bar);
test(new Object);
除此之外,原型(prototype)的 constructor
属性并没有什么特别之处。这只是一个普通的属性(property)。用 Tyler Durden 的话来说:https://www.youtube.com/watch?v=4X2AvfSTi6Q
因为它是一个普通属性,您可以决定根本不使用构造函数属性:
function Foo() {}
Foo.prototype = {}; // no constructor property
你可以决定让它指向其他一些函数:
function Foo() {}
function Bar() {}
Foo.prototype.constructor = Bar;
你可以决定让它指向函数以外的东西:
function Foo() {}
Foo.prototype.constructor = "I am not a function.";
但是,关键在于它只是另一个原型(prototype)属性。事实上,我们可以利用这一优势来创建更简洁的代码。例如,这就是我们通常在 JavaScript 中创建“类”的方式。
function MyClass(a, b) {
this.a = a;
this.b = b;
}
MyClass.prototype.sum = function () {
return this.a + this.b;
};
MyClass.prototype.diff = function () {
return this.a - this.b;
};
不是很干净。但是请注意,所有三个函数 MyClass
、sum
和 diff
都是原型(prototype)函数:constructor
、sum
和 diff
分别。原型(prototype)只是一个对象,JavaScript 中的对象字面量提供了一种很好的封装形式。我们可以利用这一点来编写更清晰的代码:
function defclass(prototype) {
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
var MyClass = defclass({
constructor: function (a, b) {
this.a = a;
this.b = b;
},
sum: function () {
return this.a + this.b;
},
diff: function () {
return this.a - this.b;
}
});
这样就干净多了。此外,它向我们展示了 constructor
属性只是一个普通的原型(prototype)属性。希望这能回答您的问题。
关于javascript - 函数构造函数和原型(prototype)构造函数有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27307465/