JavaScript构造函数 - 返回JSON对象的影响

4
有没有性能或功能上的区别,在JavaScript构造函数中返回JavaScript对象字面量,与仅使用“this.XYZ”设置属性?例如:
    function PersonA(fname, lname) {
        this.fname = fname;
        this.lname = lname;
    }

    function PersonB(fname, lname) {
        return {
            "fname": fname,
            "lname": lname
        };
    }

两者都表现得很合适:

    PersonA.prototype.fullName = function() { return this.fname + " " + this.lname; };
    PersonB.prototype.fullName = function() { return this.fname + " " + this.lname; };

    var pA = new PersonA("Bob", "Smith");
    var pB = new PersonB("James", "Smith");

    alert(pA.fullName());
    alert(pB.fullName());

有没有任何原因使一种更可取,或只是个人口味而已?如果是口味的话,是否有一种更为标准?


1
请参见:https://dev59.com/VnE85IYBdhLWcg3wMAbc - Diodeus - James MacFarlane
2个回答

4

它们并不完全相同。

如果您返回从构造函数中创建的对象...

  • 它将继承自构造函数的prototype
  • 它将具有instanceof作为一种测试由哪个构造函数创建它的方式

fullName()方法似乎对于pB有效的原因是您对两者都使用PersonA构造函数。

var pA = new PersonA("Bob", "Smith");   // uses PersonA constructor
var pB = new PersonA("James", "Smith"); // uses PersonA constructor???

顺便提一下,正确的术语应该是"JavaScript对象字面量",而不是"JSON对象字面量"


编辑:你已经更新了问题中的代码,使用了PersonB构造函数。再次运行,你会在控制台中发现一个错误。


@Adam:重新运行代码,您会发现pB不再起作用,因为它没有一个fullName()方法。 - user113716
确实出错了。所以PersonB的构造函数是无效的JS?alert(pB instanceof PersonB);显示为false,因此这种方法存在许多问题。 - Adam Rackis
谢谢 - 真是个愚蠢的类型错误,隐藏了整个问题无意义的事实。我在网上看到了一个JS演示文稿中PersonB构造函数的布局,对我来说似乎比this.someNewProperty = ...更令人愉悦,但我想这样做(PersonA)只是正确的方法。 - Adam Rackis
@Adam:它是有效的JS,但它的行为与PersonA不同。当作为构造函数调用时,它会隐式返回新对象(由构造函数中的this引用)。但是,它确实允许您通过返回其他类型的对象来覆盖该隐式返回。此时,您返回的对象与构造函数实际上没有任何关系。例如,让PersonB执行return {foo:'bar',person:this};现在被返回的主要对象只是一个普通的旧对象,但person属性的值是实际从构造函数创建的对象。 - user113716
1
@Adam: 对的。以它当前的形式来看,它只是像普通函数一样行为。但是,你可能希望它返回其他类型的对象,但仍然需要对被构造的对象(由 this 表示)进行赋值,使其在其他地方可用。但是,确实,在当前状态下,它作为构造函数没有太多价值。 - user113716
显示剩余2条评论

1
当你使用函数构造器进行new操作时,会创建一个空对象,并在函数构造器内部通过this引用该对象。
因此,在PersonA中,可以这样理解:
// create an empty object
var emptyObj = {}; 

// call the function as a method of the empty object
PersonA.call(emptyObj, "Bob", "Smith");

这导致emptyObj等于:
{
   fname : "Bob",
   lname : "Smith"
}

当您调用 PersonB 时,仍然通过调用 new 创建一个空对象,但实际上并没有对其进行任何操作,并返回不同的对象作为结果。

没问题。请查看此文章的“自定义对象”部分:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/A_re-introduction_to_JavaScript。 - Steve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接