在文件之间共享 'this'
Sharing 'this' between files
我正在努力创建一个将有很多方法的对象,并试图避免我的文件非常长。问题是一些方法引用了对象中的其他信息。我希望能够做这样的事情:
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;
}
};
为什么 this
在这种情况下不起作用是有道理的,但是是否有其他解决方案可以引用其他文件?我唯一能想到的是使用 fs 和 eval()
而不是 require,但这对我来说似乎是一个 hack,或者显然有一个长文件。还有更好的吗?
我计划在原型上有大约 35 个对象,每个对象平均有 4 个方法。建议?谢谢。
您可以像这样绑定这些函数:
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.
此外——在您的需求路径中丢失 .js
。
这个问题与它在单独的文件中没有任何关系。如果你这样定义用户,你会在一个文件中遇到同样的问题:
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;
}
};
因为当您调用 someuser.name.full()
时,this
将绑定到 someuser.name
而不是 someuser
。
如果您不需要为这些函数命名空间并且只是因为您不确定如何从另一个文件扩展原型而这样做,您可以使用 Object.assign:
Object.assign( User.prototype, require('./methods/name.js') );
然后您将能够调用 someuser.full()
或 someuser.formal()
,当然 this
将具有正确的值。
这应该使您的代码模块化
// 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;
}
};
我正在努力创建一个将有很多方法的对象,并试图避免我的文件非常长。问题是一些方法引用了对象中的其他信息。我希望能够做这样的事情:
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;
}
};
为什么 this
在这种情况下不起作用是有道理的,但是是否有其他解决方案可以引用其他文件?我唯一能想到的是使用 fs 和 eval()
而不是 require,但这对我来说似乎是一个 hack,或者显然有一个长文件。还有更好的吗?
我计划在原型上有大约 35 个对象,每个对象平均有 4 个方法。建议?谢谢。
您可以像这样绑定这些函数:
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.
此外——在您的需求路径中丢失 .js
。
这个问题与它在单独的文件中没有任何关系。如果你这样定义用户,你会在一个文件中遇到同样的问题:
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;
}
};
因为当您调用 someuser.name.full()
时,this
将绑定到 someuser.name
而不是 someuser
。
如果您不需要为这些函数命名空间并且只是因为您不确定如何从另一个文件扩展原型而这样做,您可以使用 Object.assign:
Object.assign( User.prototype, require('./methods/name.js') );
然后您将能够调用 someuser.full()
或 someuser.formal()
,当然 this
将具有正确的值。
这应该使您的代码模块化
// 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;
}
};