简体   繁体   中英

Sharing 'this' between files

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.

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.

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.

This should keep your code modular

// index.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

// methods/name.js

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

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