使用构造函数创建对象与返回对象有区别吗? [英] Is there a difference in using a constructor to create an object versus returning an object?

查看:97
本文介绍了使用构造函数创建对象与返回对象有区别吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些功能的运作方式有何不同?第一个更通常是我在考虑构造函数时的想法。

Is there any difference in how these functions operate? The first one is more typically of what I think about when thinking of a constructor.

示例1:使用 this 来命名和设置属性。然后使用new来创建一个新的Book对象。

Example 1: using this to name and set properties. Then using new to create a new Book object.

    function Book(name, numPages) {
        this.name = name;
        this.numPages = numPages;
    }

    var myBook = new Book('A Good Book', '500 pages');

示例2:使用 new 返回一个对象并只调用该函数本身。

Example 2: returning a object by using new and just calling the function itself.

    function Movie(name, numMinutes) {
        return { name:name, numMinutes:numMinutes };
    }

    var best = new Movie('Forrest Gump', '150');

    var other = Movie('Gladiator', '180');

我想我想弄清楚的是,如果它们创建的方式不同宾语?如果是这样的话比另一个好吗?是否有不同的情况,哪一个会比另一个更好?

I guess what I'm trying to figure out is if these are different in the way they create an object? If so is one better than the other? Are there different situations where one would work better over the other?

推荐答案

第一个是构造函数,因此可以扩展通过原型,您可以通过 instanceof 进行测试,结果是此类型的实例。
下行:如果你忘记了 new -keyword,你的代码就会爆炸(除非你为每个 constuctor写一个解决方法

The first one is a constructor, and can therefore be extended by a prototype, and you can test via instanceof wether the result is an Instance of this type. Downside: if you forget the new-keyword your code will blow up (unless you write a workaround for that into each constuctor)

你不能真正使用 apply()和一个构造函数来传递一个实例化一个新Object时的参数数组;另一方面,即使你可以/可以,也不要这样做。

And you can't really use apply() with a constructor to pass an array of arguments, when you instantiate a new Object; on the other hand, don't do that, even if you can/could.

第二个是工厂,而不是构造函数。你是否独立使用 new -keyword。
使用此实现它创建看起来相同但不共享类型或原型的对象(尽管底层JS引擎将它们识别为相似,因此它们共享相同的隐藏类,只要它们具有相同的属性,以相同的顺序添加,...不同的主题)

长话短说,性能和内存占用都没有受到这种方法的影响(不再)

The second one is a factory, not a constructor. Independant wether you use the new-keyword or not. with this implementation it creates Objects that look the same but don't share a type or prototype (although the underlying JS-engine recognizes them as similar and so they share the same hidden Class as long as they have the same properties, added in the same order, ... different topic)
long story short, neither performance nor memory-footprint suffer from this approach (anymore)

但你无法检查它们是否属于同一类型,并且你没有可能影响所有实例的共享原型(可能是pro或con。)

But you can't check wether they are of the same type, and you don't have a shared prototype that may affect all instances (maybe a pro or a con.)

我的转到方法如果我需要继承,可以是两者的混合:

(如果我只需要一个数据对象,我通常使用工厂和普通对象)。

My goto-approach If I need inheritance, is kind of a mix of both:
(if I just need a data-object I usually use a factory and plain objects).

function Book(conf) {
    var book = Object.create(Book.prototype);
    //a book like this usually has multiple configs/properties
    if(typeof conf === "object"){
        for(var k in conf) book[k] = conf[k];
    }else if(conf){
        //assuming that I get at least the name passed
        book.name = String(conf);
    }
    return book;
}

//I have a prototype that can be extended
//with default-values for example; no idea for a good method 
//to add to the prototype in this example ;)
Book.prototype.numPages = 0;

//but I can also use it like a plain function; no error if you 
var myBook1 = Book("Peter Pan");
var myBook2 = Book({
    name: "American Gods",
    author: "Neil Gaiman"
});

如果我将以下行添加到函数的顶部我也可以使用它作为方法将任何内容转换为 Book 的实例,而不克隆已存在的实例

If I add the following line to the top of the function I can also use that as a method to cast anything into an Instance of Book without cloning already existing instances

function Book(conf) {
    //with this simple line I can also use this as a function to cast anything into a "Book"
    if(conf instanceof Book) return conf;

    var book = Object.create(Book.prototype);
    //...
    return book;
}

var data = [
    "Peter Pan",
    {name: "American Gods"},
    //...
];

var books = data.map(Book);

在我看来,通过这种方法,我可以获得两个世界的好处。

In my opinion, I have the benefits of both worlds with this approach.

这篇关于使用构造函数创建对象与返回对象有区别吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆