我认为将Number.prototype的零填充扩展名重写为真正的getter / setter模式会很有趣。不是很难。我最终得到了这段代码(addSetter
和addGetter
只是使用prototype.__defineGetter__ / __defineSetter__
的包装函数。
Number.addSetter('leftPad0',
function(v){
var len = (String(v).length - String(this).length)+1;
this._leftPad0 = new Array(len).join('0')+this;
}
);
Number.addGetter('leftPad0',
function(){
return this._leftPad0;
}
);
适用于实际数字对象:
var a = new Number(977);
a.leftPad0 = 10000;
alert('a => '+a.leftPad0); // a => 00977
但不是数字文字:
var b = 977;
b.leftPad0 = 10000;
alert('b => '+b.leftPad0); // b => undefined
那么,是不是达到了二传手?或者,如果它到达了设定者,是不是数字?
我在setter函数中将其记录在控制台中:
this.constructor === Number // true
this instanceof Number //true
或者是没有达到吸气剂,或者当它到达时,文字不是数字的实例?我在getter中记录了相同的内容。一切都很好,也是如此。
那么,可能是因为我们无法使用数字文字来使用此模式?或者我错过了什么?
注意:如果我使用此原型扩展('monkey patch'),则不会发生这种情况:
Number.prototype.leftPad = function(base){
var len = (String(base).length - String(this).length)+1;
return new Array(len).join('0')+this;
}
alert( (977).leftPad(10000) ); // 00977
[编辑]我仍然想知道我们是否必须将此称为错误,或者是否遵循/ a标准。无论如何,我现在为此设计了自己的对象:
function NumPL(val,pval,chr){
if (!(this instanceof NumPL)){
return new NumPL(val,pval,chr);
}
this._value = new Number(val||0);
this._padValue = pval || 10;
this.chr = chr || '0';
}
NumPL.prototype = {
get value(){
return this._value;
},
set padValue(v) {
this._padValue = v%10 === 0 ? v : 10;
},
set value(v) {
this._value = v;
},
get padLeft(){
var len = (String(this._padValue).length -
String(this._value).length)+1;
return new Array(len).join(this.chr)+this._value;
}
}
// Usage
var a = NumPL(977,10000);
alert(a.padLeft); //=> 00977
// or a real world example
var dat = new Date,
datshort = [dat.getFullYear(),
NumPL(dat.getMonth()+1).padLeft,
NumPL(dat.getDate()).padLeft]
.join('/');
alert(datshort); //=> 2011/05/19
答案 0 :(得分:4)
字面数不是Number
:
typeof 3
// "number"
typeof new Number(3)
// "object"
因此没有可以修改数字文字的原型。
但是,当您尝试在数字文字上设置属性时,看起来文字首先包装在Number对象中。然后,在该对象上调用setter,this
将成为setter函数内的对象。然后,当setter返回时,文本被解包,这个展开将属性(在对象包装器上设置)留下。
Number.prototype.__defineSetter__('leftPad0',
function(v) {
alert('In setter: ' + v + ' ' + (this instanceof Number));
var len = (String(v).length - String(this).length) + 1;
this._leftPad0 = new Array(len).join('0') + this;
}
);
var a = new Number(977);
a.leftPad0 = 10000;
alert('a => ' + a._leftPad0);
var b = 977;
b.leftPad0 = 10000;
alert('b => ' + b._leftPad0);
http://jsfiddle.net/ambiguous/H77qk/2/
我在几个浏览器中收到了上述四个警告。
很抱歉,但我没有这种行为的权威参考,只是经验证据。
答案 1 :(得分:2)
var b = 9;
表示b
是对基本类型的引用,而不是Number
类型的对象。
var b = new Number(9)
创建一个Number
类型的对象,将包含添加到Number
原型的函数,而不是原始数字类型。