javascript – 使用构造函数创建对象与返回对象有区别吗?

这些功能的运作方式有什么不同吗?第一个更通常是我在思考构造函数时的想法.

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

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

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

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

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

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

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

我想我想弄清楚的是,如果它们在创建对象的方式上有所不同吗?如果是这样的话比另一个好吗?是否有不同的情况,一个人会比另一个更好?

最佳答案 第一个是构造函数,因此可以通过原型扩展,并且您可以通过instanceof测试结果是这种类型的实例.

缺点:如果您忘记了新关键字,您的代码将会爆炸(除非您为每个构造函数编写一个解决方法)

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

第二个是工厂,而不是构造函数.你是否使用new-keyword是独立的.
使用此实现,它创建看起来相同但不共享类型或原型的对象(尽管底层JS引擎将它们识别为相似,因此它们共享相同的隐藏类,只要它们具有相同的属性,添加在相同的订单,…不同的主题)
长话短说,性能和内存占用都没有受到这种方法的影响(不再)

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

我的转到方法如果我需要继承,可以是两者的混合:
(如果我只需要一个数据对象,我通常使用工厂和普通对象).

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 of Instance而不克隆已存在的实例

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

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

点赞