简体   繁体   中英

Weird behaviour when trying to do prototype inheritance

I understand prototypical inheritance, (ie: if the property is not defined on current object then the prototype chain is traversed until the property or function is found and then it is executed or null is returned).

The problem is that I am getting "undefined" for a property when it should defined. This property is called _context .

Below is the output of Chrome's inspector console. It clearly shows that _context is defined on the prototype of YouAreConnected . (near the bottom)

在此处输入图片说明

However my Jasmine test is failing because it says that _context is not defined in the implementation.

在此处输入图片说明

Below is the implementation.

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;

});

Below is the Jasmine test case.

  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();
  })

UPDATE 1 It seems when I pass a string instead of an object into the YouAreConnected constructor the _context is no longer undefined.

This fails

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();
  })

This works (_context is no longer undefined)

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();
  })

UPDATE 2

It works (does not show _context undefined here).

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

      var _context = {

      }
      var state = new YouAreConnected(_context);
      state.init();
  })

However when I add the 'socket' property to the mock object, it again says _context is not defined. I do not understand why.

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

        }
      }
      var state = new YouAreConnected(_context);
      state.init();
  })

You are calling:

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

But the _context argument in emit is not a local variable so you need to use:

this._context.userId

for that argument. ie:

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

Also, you never set userId on the _context, but that's a different problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM