gpt4 book ai didi

javascript - 在 JavaScript 中,构造函数和作为构造函数调用的函数返回对象之间有什么区别?

转载 作者:可可西里 更新时间:2023-11-01 02:19:04 24 4
gpt4 key购买 nike

我知道这不是推荐的做法,但如果我声明以下函数,然后将它们作为构造函数调用,生成的对象之间会有什么区别(如果有的话)?

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();

xyz 之间有什么区别?

something2 不是更好的编写构造函数的方法吗,因为是否使用 new 不会影响函数的结果?

顺便说一句,something2 应该在这里大写吗? (我假设不是,因为 Crockford 对大写如此坚持,因为函数会破坏全局命名空间...)

最佳答案

简而言之:

new something2() instanceof something2 === false

相关地,如果您扩展示例以使用原型(prototype)属性

Something.prototype.method = function () { };
something2.prototype.method = function () { };

后一种情况你会发现原型(prototype)没有被继承:

typeof (new Something()).method === "function"
type (new something2()).method === "undefined"

真正的答案是您正在利用完全不同的底层机制。使用 new 调用会调用 [[Construct]]机制,涉及根据构造函数的 .prototype 属性设置 [[Prototype]] 属性。

但是在 [[Construct]] 算法的第 8--10 步发生了一件有趣的事情:在设置一个新的空对象,然后附加它的 [[Prototype]] 之后,它会执行 [[Call]]到实际的构造函数,使用这个新的空加原型(prototype)对象作为 this。然后,在第 9 步中,如果事实证明该构造函数返回了一些东西——它会丢弃它花费所有时间设置的原型(prototype)绑定(bind)、传递为 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
  • 如果您担心破坏全局 namespace 的危险,您应该开始使用 strict mode , 通过将 "use strict"; 放在文件的顶部。严格模式的许多不错的清理之一是 this 默认为 undefined,而不是全局对象,例如在构造函数尝试将属性附加到 undefined 时调用不带 new 的构造函数将导致错误。
  • 工厂函数(又名“闭包模式”)通常是构造函数和类的合理替代品,只要您 (a) 不使用继承; (b) 不构造该对象的太多实例。后者是因为,在闭包模式中,您将每个方法的新实例附加到每个新创建的对象,这不利于内存使用。在我看来,闭包模式的最大 yield 是能够使用 "private" variables (这是一个 good thing ,不要让任何人告诉你:P)。

关于javascript - 在 JavaScript 中,构造函数和作为构造函数调用的函数返回对象之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10328449/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com