Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在另一个对象中实例化一个对象_Javascript_Oop - Fatal编程技术网

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

Javascript 在另一个对象中实例化一个对象,javascript,oop,Javascript,Oop,有一个对象,比如说书,它有一个其他对象的集合页面。因此,我从传递到书籍的原始数据实例化页面: 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 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
)是一种糟糕的做法。做同样事情的正确方法是什么


如果可以的话-如果我在
add()
方法中实例化一个新的
Page
,或者将它作为一个对象传递给它(
this.add(new Page(data))
),有什么区别吗?

问题是当您想要为代码编写单元测试时

让我们举一个实际的例子。有些时候,您的代码是:

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
就是这本书。但是有了这样的代码,你就做不到了。因为页面是在方法内部创建的,所以无法检查任何内容

Buf如果我们像这样重写代码:

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

中创建新页面,问题在于您想为代码编写单元测试

让我们举一个实际的例子。有些时候,您的代码是:

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
就是这本书。但是有了这样的代码,你就做不到了。因为页面是在方法内部创建的,所以无法检查任何内容

Buf如果我们像这样重写代码:

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

中创建新页面。我听说实例化是一种不好的做法。那是什么讲座?这是一个奇怪的说法,也许你误解了。如果需要创建对象,则需要在任何位置创建它。是否希望其他人能够调用
Book.prototype.add
?您希望他们传入构造的
页面
对象,还是传入数据以构造一个对象。取决于答案,这就是你的答案——这实际上取决于你想为
书的消费者提供什么样的界面。
@torazaburo:我想他们的意思是
Book.add(newpage(…)
Book.add(…)
更好。当然,对于具有静态类型和接口的语言来说,哪一种更好。请注意,
this=data
是无效的。@JosephYoung:这听起来像是“依赖函数调用被认为是有害的,因为如果忘记了参数,它就不起作用了”。我听说实例化是一种不好的做法。那是什么讲座?这是一个奇怪的说法,也许你误解了。如果需要创建对象,则需要在任何位置创建它。是否希望其他人能够调用
Book.prototype.add
?您希望他们传入构造的
页面
对象,还是传入数据以构造一个对象。取决于答案,这就是你的答案——这实际上取决于你想为
书的消费者提供什么样的界面。
@torazaburo:我想他们的意思是
Book.add(newpage(…)
Book.add(…)
更好。当然,对于具有静态类型和接口的语言来说,哪一种更好。请注意,
this=data
是无效的。@JosephYoung:这听起来像是“依赖函数调用被认为是有害的,因为如果忘记了参数,它就不起作用了”。真的很喜欢看到后面的参考“/,因为页面需要知道它的书”!真的很喜欢看到后面的参考“/,因为页面需要知道它的书”!