我想知道这是否可行。
number = function(n){
var num = n;
this.add = function(x){
return num + x;
}
return num;
}
alert(number(7)); //returns 7
seven = new number(7);
alert(seven.add(3)); // returns 10
alert(seven); // want this to return 7, but will return [object Object]
我不需要数字(7)来返回7,但它会很好。
答案 0 :(得分:7)
首先return num;
对您的代码无效。函数返回的对象是this
。如果构造函数没有显式返回对象,它将始终隐式返回this
(参见MDN documentation中的第3步)。
也就是说,您可以覆盖两种方法,即toString
[MDN]和valueOf
[MDN]:
function MyNumber(n){
this.num = n;
}
MyNumber.prototype.add = function(x){
return this.num + x; // or `this + x` since we implemented `valueOf`
};
// Is called whenever the object has to be converted to a string
// e.g. alert(myNumber) ; myNumber + " is the answer to all questions"
MyNumber.prototype.toString = function() {
return this.valueOf().toString(); // or `this.num.toString()`
};
// Is called whenever the object has to be converted to a primitive value
// e.g. myNumber + 42 ; myNumber == 42
MyNumber.prototype.valueOf = function() {
return this.num;
};
覆盖valueOf
的额外好处是JavaScript将在内部调用此方法将对象转换为原始值。
例如,在正常添加中使用实例作为操作数也可以工作(而不是调用.add
):
> var n = new MyNumber(7);
> n + 10
17
那就是说,如果你只是想为原始类型创建一个包装器,那就不要这样做了。
As pimvdb mentions in his comment,严格比较会失败(例如)。这是可以预料的,并且避免原始值的对象版本(Number
,String
,Boolean
)(即"foo" === new String("foo")
为false
的原因之一也是)。对象根本不像基元,混合这些会产生更复杂的代码。
答案 1 :(得分:4)
给它一个“toString”:
number = function(n){
var num = n;
this.add = function(x){
return num + x;
}
this.toString = function() {
return num + "";
};
return num;
}
你也可以给它一个“valueOf”函数:
this.valueOf = function() { return num; }
那会让你这样做:
alert(seven + 7); // 14
答案 2 :(得分:2)
为了能够重用Number
,你需要在构造函数中返回对函数的引用:
var number = function(n) {
var num = n;
this.add = function(x){
return num + x;
};
this.value = function() {
return num;
};
}
答案 3 :(得分:1)
覆盖toString
:
number = function(n){
var num = n;
this.add = function(x){
return num + x;
};
this.toString = function(){
return num;
};
return num;
}
答案 4 :(得分:1)
如果我做对了,你希望一个对象表现为一个对象,除了它传递给一个函数的时候?您示例中的变量seven
是一个对象,因此在任何地方引用它时都无法返回7
。
更重要的是,num
本质上是一个私有变量。因此,使用for...in
和JSON.stringify
欺骗对您没有任何好处。您应该做的是将num
变量设为对象属性(this.num
)或创建成员函数(this.getNum(){return num};
)。
之后,您可以自由使用属性/方法:
alert(seven.num);//alerts 7, but requires num to be declared as a property
alert(seven.getNum());//alerts 7, requires the method
我建议在这种情况下使用一种方法,因为你显然使用这个函数作为构造函数和常规函数(我可以补充说,这不是一个好主意)。
稍微迂腐的说明:将构造函数的第一个字母大写,而不是使用可能与JS本机类型(String,Number,Object,Function ...)发生冲突的名称是自定义的。
function MyNumber(n)
{
this.num = n;//as a property
this.add = function(x)
{
return this.num + x;
}
}
var seven = new MyNumber(7);
alert(seven.num);//alerts 7
虽然,如果num不应该被改变 - 我猜这就是这种情况 - 一个额外的功能是我采取的路线:
function MyNumber(n)
{
var num = n;
this.add = function(x)
{
return num + x;
};
this.getNum = function()
{
return num;
};
}
alert(seven.getNum());
如果您仍然计划将构造函数用作常规函数,那么最好检查函数/构造函数的调用方式:
function MyNumber(n)
{
var num = n;
if (!(this instanceof MyNumber))
{//not called as constructor
return num;//or a function, or something else (treat this as a closure)
}
//Same code as above goes here
}
我可能会在这里讨论一些主题,但我不禁想到你可能想要阅读JavaScript中的闭包,对象和构造函数。