2011-05-18 50 views
2

如果我將零填充擴展重寫爲Number.prototype爲真正的getter/setter模式,我很樂意。不是很困難。我結束了這段代碼(addSetteraddGetter使用prototype.__defineGetter__/__defineSetter__只是包裝函數setter/getter不能用於數字文字

實數
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?或者如果它到達setter,是不是一個數字?

我登錄這個控制檯從setter函數中:

this.constructor === Number // true 
this instanceof Number //true 

或者沒有達到吸氣,或當它達到將字面不是數量的實例?我在getter中記錄了相同的內容。一切都很好,也是真的。

那麼,可能是什麼原因,我們不能使用這種模式使用數字文字?或者我錯過了什麼?

注:如果我使用這臺樣機的擴展名(「猴子補丁」)不會發生這種情況:

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標準。反正我現在deviced我自己的對象是:

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 

回答

4

逐字數量不是Number

typeof 3 
// "number" 

typeof new Number(3) 
// "object" 

所以沒有原型的數字文字修改。

但是,當您嘗試在數字文字上設置屬性時,它首先看起來像是包裝在Number對象中的文字。然後,調用者被調用該對象,並且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/

我送四個警報出上述的幾種瀏覽器。

對不起,但我沒有這種行爲的權威性參考,只是經驗證據。

+0

我知道,但如果我在setter或getter中提醒'typeof this' for'b',我得到'object',真的是 – KooiInc 2011-05-18 20:05:50

+0

@Kooilnc:這很有趣:http://jsfiddle.net/ambiguous/ H77qk/2 /看起來像文字被包裹在一個數字中作爲屬性設置,所以你得到一個'this'的對象,然後它會立即被解包。數字文字畢竟是不可變的。 – 2011-05-18 20:23:50

+0

@shortmu:抓住我最後的評論,看起來像一個'jsdb'(http://www.jsdb.org/)artefact。必須首先在jsfiddle中運行它,我想 – KooiInc 2011-05-18 20:25:30

2

var b = 9;表示b是對原始類型的引用,而不是Number類型的對象。

var b = new Number(9)創建Number類型的對象,這將包含加入到Number原型,不是原始號碼類型的功能。

+0

正確,但它比這更復雜,似乎有一些隱式的對象包裝和展開繼續:http://jsfiddle.net/ambiguous/H77qk/2/ – 2011-05-18 20:31:39

相關問題