2013-05-21 3 views
1

클래스로 첨부 할 객체를 받아 들일 수있는 클래스 MyClass이 있습니다. 이러한 메서드는 MyClass.push을 호출하여 개체의 내부 @_list 배열에 데이터를 추가합니다. 두 개의 동일한 테스트 케이스의 두 번째 실패,하지만 난 왜 이해가 안 :처음 모카 테스트가 실패한 이유는 무엇입니까?

v = new MyClass attach: 
    name: 'foo' 
    f: -> 
    for i in [1..5] 
     @push "Element #{i}" 
: 나는 그것이 내가 함께 두 번째 v = new MyClass attach: obj를 교체 할 때 때문에 기능이 결합가는 함께 할 수있는 뭔가가 생각

chai = require "chai" 
chai.should() 

obj = 
    name: 'foo' 
    f: -> 
    for i in [1..5] 
     @push "Element #{i}" 


class MyClass 
    constructor: (@options) -> 
    @methods = {} 
    @_list = [] 

    if 'attach' of @options 
     @attach @options.attach 

    push: (m) -> 
    @_list.push m 

    list: -> 
    @_list 

    method: (v) -> 
    @methods[v].f 

    run: (options) -> 
    @method('foo')() 

    attach: (o) -> 
    @methods[o.name] = o 
    @methods[o.name].f = o.f.bind(@) 

describe 'MyClass', -> 
    it 'list should have five elements', -> 
    v = new MyClass attach: obj 
    v.run() 
    v.list().length.should.equal 5 
    it 'list should have five elements (#2)', -> 
    v = new MyClass attach: obj 
    v.run() 
    v.list().length.should.equal 5 

두 가지 테스트가 모두 통과합니다. 그러나 나는이 동작을 이해하지 못한다. 나는 .bind()이 함수의 복사본을 생성한다고 생각했다. 그렇다면 여기서 진행되는 작업과 두 테스트를 독립적으로 실행하는 방법은 무엇입니까?

답변

1

JavaScript (따라서 coffeescript) 객체는 이며, 참조 번호는입니다. 두 번째 테스트를 시작하면 obj 개체를 수행하여 당신이 f 속성을 수정 한 이후 변경된 :

@methods[o.name].f = o.f.bind(@)

당신은이 문제를 피하기 위해 대신 사본을 전달할 수 있습니다.

+0

나는 이것을 이해해야한다고 느낀다. 그러나 나는하지 않는다 (나는 노력하고있다!). 5 개의 요소는'obj'가 아니라'v'에 설정됩니다. 배열을 각 객체 ('v') 내부에 유지하고 싶지만'obj' (함수를 포함하고 있습니다)는'MyClass'의 다른 인스턴스들 사이에서 공유 될 수 있어야합니다. 여기서 @push는'obj'가 붙어있는'v'를 가리키고 있다고 가정합니다. 나는 이해가 되니? – user2010963

+1

@ user2010963'@methods [o.name] .f = o.f.bind (@)'를 수행하여 첫 번째 객체에'o.f'를 바인딩 할 때'obj'가 참조로 전달되기 때문에 obj가 변경됩니다. 다음은 http://codepen.io/anon/pen/JlGyq에서 수정 된 코드입니다. 또한, 나는 처음의 대답이 틀렸다. –

관련 문제