Sharing 'this' between files

时间:2016-04-04 18:49:10

标签: javascript node.js this

I'm working on creating an object that will have many methods, and trying to avoid my files being incredibly long. The problem is some of methods refer to other information in the object. I'd like to be able to do something like this:

index.js

var User = function(first, last){
  this.firstname = first;
  this.lastname = last;
};

User.prototype.name = require('./methods/name.js')

methods/name.js

module.exports = {
  full: function(){
      return this.firstname + " " + this.lastname;
  },
  formal: function(){
      return "Mr. " + this.lastname;
  }
};

It makes sense why this doesn't work in this situation, but is there a different solution to be able to reference the other file? The only I can think of is using fs and eval() instead of require, but that seems like a hack to me, or the obvious of have a long file. Is there something better?

I'm planning on having about 35 objects on the prototype with each having an average of 4 methods on it. Suggestions? Thanks.

3 个答案:

答案 0 :(得分:4)

The problem doesn't have anything to do with it being in separate files. You would get the same problem all in one file if you defined User like this:

var User = function(first, last){
  this.firstname = first;
  this.lastname = last;
};

User.prototype.name = {
  full: function(){
      return this.firstname + " " + this.lastname;
  },
  formal: function(){
      return "Mr. " + this.lastname;
  }
};

Since when you call someuser.name.full() the this will be bound to someuser.name not someuser.

If you don't need to namespace those functions and only did so because you were unsure how else to extend the prototype from another file, you can use Object.assign:

Object.assign( User.prototype, require('./methods/name.js') );

Then you'll be able to call someuser.full() or someuser.formal() and of course this will have the correct value.

答案 1 :(得分:1)

You can bind those functions like this:

User.prototype.name = require('./methods/name').bind(this)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

Also—lose the .js in your require path.

答案 2 :(得分:0)

这应该保持代码模块化

// index.js

Any? from = ...
KClass<T> toClass = ...

T result = // toClass.cast(from) - how to convert this line to Kotlin?

// methods / name.js

var userMethods = require('.methods/name.js');
var User = function(first, last){
  this.firstname = first;
  this.lastname =  last;
};

User.prototype.name = userMethods.full;
User.prototype.formalName = userMethods.formal;

var Abbey = new User('Abbey', 'Jack');

console.log(Abbey.firstname); // Abbey
console.log(Abbey.lastname); // Jack
console.log(Abbey.name()); // Abbey Jack
console.log(Abbey.formalName()); // Mr. Jack