在另一个对象中实例化对象

时间:2016-02-10 13:15:41

标签: javascript oop

有一个对象,比如Book,其中包含其他对象Page的集合。所以我从传递给Book的原始数据实例化页面:

function Book(data){
    this.pages = [];
    var self = this;
    data.forEach(function(item){
        self.add(item);
    });
}

Book.prototype.add = function(data){
    this.pages.push(new Page(data));
}


function Page(data){
    // some validation code
    this.prop = data.prop;
}
Page.prototype...

关于可测试性的讲座我听说在另一个对象中实例化(使用new)是一种不好的做法。做同样的事情的正确方法是什么?

如果没问题 - 如果我在Page方法中实例化新的add()或将其作为对象传递给它(this.add(new Page(data)))会有什么不同吗?

1 个答案:

答案 0 :(得分:5)

问题在于您想为代码编写单元测试。

让我们举个实例。有些时候,你的代码就是这个:

function Book(data){
    this.pages = [];
    var self = this;
    data.forEach(function(item){
        self.add(item);
    });
}

Book.prototype.add = function(data){
    var page = new Page(data);

    // Because the page need to know its book        
    page.book = this;

    this.pages.push(page);
}


function Page(data){
    // some validation code
    this.data = data;
}
Page.prototype...

现在您要为add方法编写单元测试,并且想要在书中添加新页面后检查page.book是否为本书。但是有了这样的代码,你就无法做到。如果页面是在方法内部创建的,则无法检查任何内容。

如果我们重写代码,请填写:

Book.prototype.add = function(page){
    page.book = this;
    this.pages.push(page);
}

我们现在可以编写一个单元测试:

describe('book.add', function() {

    it('should set the current book in the book property of the page', function() {
        var book = new Book(),
            page = new Page();

        book.add(page);

        expect(page.book).toBe(book);
    });

});

但是,如果您不想编写任何像这样的单元测试,那么没有理由不在方法add内创建新页面。