1

我想知道这是否可能。

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]

我不需要 number(7) 来返回 7,但这会很好。

4

5 回答 5

7

首先return num;对您的代码没有影响。函数返回的对象是this. 如果构造函数没有显式返回对象,它将始终隐式返回this(参见MDN 文档中的步骤 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

也就是说,如果您只想为原始类型创建一个包装器,请不要这样做。

正如 pimvdb 在他的评论中提到的那样,严格比较会失败(例如)。Number这是意料之中的,也是避免原始值( , String, )的对象版本的原因之一Boolean(即"foo" === new String("foo")也是false如此)。对象的行为根本不像原语,混合这些会创建更复杂的代码。

于 2012-06-09T13:54:34.203 回答
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
于 2012-06-09T13:54:02.717 回答
2

为了能够重用Number你需要在构造函数中返回对函数的引用:

var number = function(n) {

  var num = n;

  this.add = function(x){
    return num + x;
  };

  this.value = function() {
      return num;
  };
}
于 2012-06-09T13:52:40.933 回答
1

覆盖toString

number = function(n){

  var num = n;

  this.add = function(x){
    return num + x;
  };

  this.toString = function(){
    return num;
  };

  return num;

}
于 2012-06-09T13:54:21.510 回答
1

如果我做对了,你希望一个对象表现得像一个对象,除非它被传递给一个函数?您示例中的变量seven是一个对象,因此在7任何地方引用它时都不会简单地返回。

num重要的是,本质上是一个私有变量。所以使用for...inJSON.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 原生类型(字符串、数字、对象、函数...)冲突的名称

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 中的闭包、对象和构造函数。

于 2012-06-09T14:09:50.150 回答