【发布时间】:2018-09-08 23:41:33
【问题描述】:
我理解原型继承,(即:如果属性未在当前对象上定义,则遍历原型链,直到找到属性或函数,然后执行或返回 null)。
问题是我在应该定义属性时得到“未定义”。此属性称为 _context。
以下是 Chrome 检查器控制台的输出。它清楚地表明 _context 是在 YouAreConnected 的原型上定义的。 (靠近底部)
但是我的 Jasmine 测试失败了,因为它说 _context 没有在实现中定义。
下面是实现。
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 构造函数时,_context 不再是未定义的。
失败了
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();
})
这可行(_context 不再未定义)
it('emits a "createRoom" event to the server upon creation', ()=>{
//var _context = TestHelper.mockContext;
var state = new YouAreConnected("mock"); // string passed
spyOn(_context.socket,'emit');
state.init();
expect(_context.socket.emit).toHaveBeenCalled();
})
更新 2
有效(此处不显示 _context undefined)。
it('emits a "createRoom" event to the server upon creation', ()=>{
var _context = {
}
var state = new YouAreConnected(_context);
state.init();
})
但是,当我将 'socket' 属性添加到模拟对象时,它再次显示 _context 未定义。我不明白为什么。
it('emits a "createRoom" event to the server upon creation', () => {
var _context = {
socket:{
}
}
var state = new YouAreConnected(_context);
state.init();
})
【问题讨论】:
-
永远不要使用 __proto__,使用 setprototypeof ,developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
-
我提炼了这个问题。 _context 属性已在原型上定义,但仍未找到。
-
你不需要把 _context 放在原型上,你为什么首先要这样做?只需让它成为 YouAreConnected 的属性,只需编写 this._context = context
-
你是正确的mpm。但是,由于原型继承,它应该以任何一种方式工作。我确实尝试了您的建议,但发生了同样的失败。
标签: javascript inheritance design-patterns