Javascript 尝试进行原型继承时的奇怪行为

Javascript 尝试进行原型继承时的奇怪行为,javascript,inheritance,design-patterns,Javascript,Inheritance,Design Patterns,我理解原型继承(即:如果属性未在当前对象上定义,则遍历原型链,直到找到属性或函数,然后执行它或返回null) 问题是当属性应该定义时,我得到了属性的“未定义”。此属性称为\u context 下面是Chrome的inspector控制台的输出。它清楚地表明,\u context是在YouAreConnected的原型上定义的。(靠近底部) 然而,我的Jasmine测试失败了,因为它说,\u上下文没有在实现中定义 下面是实现 define(['voice/states-new/State'],

我理解原型继承(即:如果属性未在当前对象上定义,则遍历原型链,直到找到属性或函数,然后执行它或返回null)

问题是当属性应该定义时,我得到了属性的“未定义”。此属性称为\u context

下面是Chrome的inspector控制台的输出。它清楚地表明,\u context是在YouAreConnected的原型上定义的。(靠近底部)

然而,我的Jasmine测试失败了,因为它说,\u上下文没有在实现中定义

下面是实现

define(['voice/states-new/State'],
function(State){

  var YouAreConnected = function YouAreConnected(context){

    Object.setPrototypeOf(this,new State());

    if(!context){
        throw Error('context must be set.');
    }
    else{
        this.__proto__._context = context;
    }

    /**
     * Initializes this state.
     *
     * pre:
     * - _context must be set with a socket connection
     *   which is 'connected'.
     *
     * post:
     * - Any initialization involving the server is
     *   executed.
     */
    this.init = function(){

      console.log(this);   // this produced the chrome console output.

      this._context.socket.emit('createRoom',_context.userId);
    }
  }

  return YouAreConnected;

});
下面是Jasmine测试用例

  it('emits a "createRoom" event to the server upon creation', ()=>{
      var _context = TestHelper.mockContext;
      var state = new YouAreConnected(_context);
      spyOn(_context.socket,'emit');
      state.init();
      expect(_context.socket.emit).toHaveBeenCalled();
  })
更新1 似乎当我将字符串而不是对象传递到YouAreConnected构造函数中时_上下文不再是未定义的

这失败了

it('emits a "createRoom" event to the server upon creation', ()=>{
      //var _context = TestHelper.mockContext;
      var state = new YouAreConnected({});  // object passed
      spyOn(_context.socket,'emit');
      state.init();
      expect(_context.socket.emit).toHaveBeenCalled();
  })
这是有效的(_上下文不再是未定义的)

更新2

它可以工作(这里不显示未定义的上下文)

但是,当我将“socket”属性添加到mock对象时,它再次表示没有定义上下文。我不明白为什么

  it('emits a "createRoom" event to the server upon creation', () => {
      var _context = {
        socket:{

        }
      }
      var state = new YouAreConnected(_context);
      state.init();
  })
您的电话是:

this._context.socket.emit('createRoom',_context.userId),
但是emit中的_context参数不是局部变量,因此需要使用:

this.\u context.userId

为了这个论点。i、 e:

this._context.socket.emit('createRoom',this._context.userId),

此外,您从未在_上下文上设置userId,但这是另一个问题。

不要使用u proto u,永远不要使用setprototypeof,我改进了问题的可能重复项。在原型上定义了_context属性,但仍然找不到它。您不需要在原型上放置_context,为什么一开始就尝试这样做?只需将其作为YouareConnect的一个属性,只需编写此内容。_context=context您是正确的mpm。但是,由于原型继承,它应该以任何一种方式工作。我确实尝试了你的建议,同样的失败也发生了。
this._context.socket.emit('createRoom',_context.userId),
this._context.socket.emit('createRoom',this._context.userId),