2012-06-09 3 views
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] 

Мне не нужно число (7), чтобы вернуть 7, но было бы хорошо.

+0

Возможно, вы хотите узнать о фабричном шаблоне функции: https://developer.mozilla.org/en/JavaScript/Guide/Closures – nhahtdh

+2

Вы хотите иметь как числовое значение *, так и * его свойства, такие как '.add '? – pimvdb

+0

Напоминает мне образец декоратора питонов. –

ответ

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

Чтобы иметь возможность повторно использовать Number вам необходимо вернуть ссылку на функцию в конструкторе:

var number = function(n) { 

    var num = n; 

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

    this.value = function() { 
     return num; 
    }; 
} 
+0

ОК :-) Я не видел изменения ясно – Pointy

+0

@Pointy: Не совсем верно. Конструктор возвращает 'this', если объект явно не возвращен. (Это не работает для чисел, потому что они не являются объектами, но вы можете вернуть «Номер».) – Ryan

+0

Ах, да, я думаю, что где-то в голове я знал это; это не тот код, который я обычно писал бы! – Pointy

1

Override toString:

number = function(n){ 

    var num = n; 

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

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

    return num; 

} 
7

Первый return num; не имеет никакого эффекта в вашем коде. Объект, возвращаемый функцией, - this. Если функция конструктора не возвращает объект явно, он всегда будет неявно возвращать this (см. Шаг 3 в MDN documentation).

Тем не менее, есть два метода можно переопределить, а именно, 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). Объекты просто не ведут себя как примитивы, и их смешивание создает более сложный код.

+0

return num имеет эффект, если я просто называю его функцией, но верно? И никакого неблагоприятного эффекта, когда я этого не делаю? – user1446253

+0

Да, если вы просто назовете его как функцию, он вернет номер, который вы ему передали (с 'return num;'). Но при этом 'add' будет присвоен глобальному объекту (' window'), поэтому вы действительно не должны называть его нормальной функцией. –

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 (строка, число, объект, функции ...)

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.

Смежные вопросы