[英]What is the difference between a constructor function and function returning an object?
[英]What difference is there in JavaScript between a constructor function, and function returning object which is invoked as a constructor?
我知道这不是推荐的方法,但如果我声明以下函数,然后将它们作为构造函数调用,那么结果对象之间的区别(如果有的话)是什么?
function Something() {
this.foo = "bar";
}
function something2() {
var that = {};
that.foo = "bar";
return that;
}
var x = new Something();
var y = new something2();
var z = something2();
也就是说x
, y
和z
之间的区别是什么?
会不会something2
是编写构造的一个更好的方法,因为无论你使用new
或不将不影响功能的结果呢?
BTW应该something2
在这里资本? (我假设不是因为Crockford对大小写非常坚定,因为函数会破坏全局命名空间......)
简而言之:
new something2() instanceof something2 === false
相关地,如果您扩展您的示例以使用prototype属性
Something.prototype.method = function () { };
something2.prototype.method = function () { };
你会发现原型在后一种情况下不会继承:
typeof (new Something()).method === "function"
type (new something2()).method === "undefined"
真正的答案是你正在利用完全不同的底层机器。 使用new
调用会调用[[Construct]]机制,该机制涉及根据构造函数的.prototype
属性设置[[Prototype]]属性。
但是有趣的事情发生在[[Construct]]算法的第8-10步中:在设置一个新的空对象,然后附加其[[Prototype]]之后,它会对实际执行[[Call]]构造,使用这种新的空加原型对象作为this
。 然后,在步骤9中,如果事实证明该构造函数返回了某些东西---它抛弃了原型绑定,传递给this
对象,它花了所有时间设置!
注意:您可以使用Object.getPrototypeOf
访问对象的[[Prototype]](与构造函数的.prototype
):
Object.getPrototypeOf(new Something()) === Something.prototype // steps 5 & 6
Object.getPrototypeOf(new something2()) === Object.prototype // default
回答一些元问题:
something2
大写,因为它是一个工厂函数而不是构造函数。 如果某些东西是大写的,那么它应该具有构造函数语义,例如new A() instanceof A
。 "use strict";
在文件的顶部。 一个严格的模式很多很好的清理的是, this
默认为undefined
,而不是全局对象,所以如调用构造函数没有new
会导致错误的构造函数试图特性附加到时刻undefined
。 在第二种情况下,返回的对象不会从构造函数继承任何东西,因此使用它没有什么意义。
> var x = new Something();
> var y = new something2();
> var z = something2();
也就是说x,y和z之间的区别是什么?
x
继承自Something
, y
或z
都不会从something2
继承。
不会有更好的方法来编写构造函数,因为无论你是否使用new都不会影响函数的结果?
有呼吁没有点something2
作为一个构造函数,因为它返回的对象是未分配给它的新构造的对象this
是从继承something2.prototype
,这是另一些可能是打电话时得到new something2()
BTW应该在这里大写2? (我假设不是因为Crockford对大小写非常坚定,因为函数会破坏全局命名空间......)
不,因为将其称为构造函数是有点无意义的,因此将其描述为一个会产生误导。
调用函数作为构造函数(即使用new keyword
)运行以下步骤:
prototype
设置为函数的prototype
属性中的对象 this
是新对象) return
语句) 所以,你的第二个解决方案只返回一个带有属性“foo”的普通对象。 但是, y
和z
都不是instanceof Something2
的instanceof Something2
,也不会从该原型继承。 有这样的函数,是的,但它们不应该被称为构造函数(没有大写命名,没有new
调用)。 它们属于工厂模式。
如果您想要一个可以在没有new的情况下执行的构造函数,请使用该代码:
function Something(params) {
if (! this instanceof Something)
return new Something(params);
// else use "this" as usual
this.foo = "bar";
...
}
我要说最重要的是返回对象的原型。
function Something() {
this.foo = "bar";
}
Something.prototype = {
// Something prototype code
hello: function(){
//...
}
}
function something2() {
var that = {};
that.foo = "bar";
return that;
}
something2.prototype = {
// something2 prototype code
greetings : function() {
//...
}
}
var x = new Something();
var y = new something2();
var z = something2();
typeof x.hello === function // should be true
typeof y.greetings === undefined // should be true
typeof z.greetings === undefined // should be true
换句话说,我说你没有用某些东西实例化对象,你正在创建从Object继承的纯粹新对象。
new something2效率低下,因为您正在创建一个空白范围,您可以从中创建一个新对象
var that = {};
这相当于
var that = new Object();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.