簡體   English   中英

修改JavaScript基本類型的最佳做法

[英]Best practices for modifying JavaScript primitive types

我試圖找到一種在不修改本地String對象的情況下在字符串基元上調用自定義方法的方法。

String.prototype.addOne = function() { return this.length + 1};

let str = new String('abc')
str.addOne() // 4

上面的代碼的問題在於新的字符串也將具有新的方法,並且上面的方法創建可能會覆蓋在庫或代碼庫的其他區域內進行的其他原始修改,例如:

String.prototype.addTwo = function() {return  this.addOne + 1}
str.addTwo() // 5

String.prototype.addOne = function() { return this.length + 10};
str.addOne() // 13
str.addTwo() // 14, oops

有什么解決方案可以讓我創建String對象的副本,在其中我可以安全地修改其原型,而不必更改本地全局String對象?

編輯:

我特別在問是否有一種方法可以允許我向原始字符串添加方法,有人建議擴展String類,添加一個方法,然后返回String對象。 但是,這與原始字符串Object不同。 我基本上希望能夠這樣調用自定義方法:

class CustomString extends String{
  someMethod(){
    return 'someValue'
  }
}

let str = '123'
str.someMethod() // '123'                                             <<< this

let str2 = new CustomString('123')
str2.someMethod() // CustomString { [Iterator] 0: '4', 1:'5'. 2: '6'} <<< not this

這可行,但隨后的原始問題仍然存在,因為我們已經突變了全局String對象

String.prototype.someMethod = function() {return 'someValue'}

let str3 = '123'
str3.someMethod() // someValue

聽起來您可能想制作一個extends String的類:

 (() => { // In one module: class SpecialString extends String { addOne() { return this.length + 1 } } const str = new SpecialString('abc'); console.log(str.addOne()) // 4 })(); (() => { // In another module: class SpecialString2 extends String { addTwo() { return this.addOne() + 1 } addOne() { return this.length + 10 } } const str = new SpecialString2('abc'); console.log(str.addTwo()); console.log(str.addOne()); console.log(str.addTwo()); })(); 

只需創建一個子類:

class CustomString extends String{
  addOne(){...}
}

然后簡單地:

new CustomString("asd").addOne()

此類與String非常相似,但是您可以創建其他屬性,而不會與原始字符串和本機String類沖突。
即使instanceof也可以使用它:

new CustomString() instanceof String //true

但是請注意,您將無法使用此構造函數創建原始字符串:

String(1)       //"1"
CustomString(1) //Error

編輯:根據對問題的編輯:

經過一番混亂之后,我發現了一種在不影響其構造函數的情況下將屬性修補到原始函數原型的方法:

 function CustomString(from){ let string if(new.target){ //Whether or not was called as constructor string = new String(from) }else{ string = String(from) } Object.assign(Object.getPrototypeOf(string),CustomString.prototype) return string } //Add your custom properties like this: CustomString.prototype.addOne=function(){return this.length+1} //Without new, creates a primitive string const primitiveCustomString = CustomString('asd') //With new, creates a string object const objectCustomString = new CustomString('asd') console.log(primitiveCustomString) //"asd" console.log(objectCustomString) //String{0:"a",1:"s",2:"d",addOne(){...}} console.log(primitiveCustomString.addOne()) //4 console.log(objectCustomString.addOne()) //4 //You can even concatenate it together with normal strings, the custom properties still remain console.log(("asd" + primitiveCustomString + "asd").addOne()) //10 console.log(("asd" + objectCustomString + "asd").addOne()) //10 

您可以編寫工廠功能。

function addoneable_string(s) {
  let ns = new String(s);
  ns.addOne = function() { return this.length + 1};
  return ns;
}

let s = addoneable_string("1");
console.log( s.addOne() );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM