为字符串类添加方法

83

我想在JavaScript中能够像这样表达:

   "a".distance("b")

我如何将自己的距离函数添加到字符串类中?


当有人这样做时,它被称为什么?由于您只是添加了一个新方法,这是否被认为是猴子补丁或其他什么东西? - still_dreaming_1
@still_dreaming_1 这被称为扩展:https://dev59.com/zG865IYBdhLWcg3wfuwk - spectre-d
6个回答

155

你可以扩展 String 原型;

String.prototype.distance = function (char) {
    var index = this.indexOf(char);

    if (index === -1) {
        alert(char + " does not appear in " + this);
    } else {
        alert(char + " is " + (this.length - index) + " characters from the end of the string!");
    }
};

...并且像这样使用它;

"Hello".distance("H");

在这里查看 JSFiddle


45
请使用“this”关键字来获取调用该函数的字符串。 - Brian Low
5
实际上,对于我来说,this 返回的是一个对象,例如 String {0: "t", 1: "e", 2: "s", 3: "t", length: 4, [[PrimitiveValue]]: "test"}。要使用实际的文本内容,我需要调用 this.toString() - Wesley Smith
1
有没有办法以ECMA脚本的方式编写"String.prototype.distance = function(char) {}"? - Biswajit Maji
5
扩展原生JavaScript对象通常是一种不良做法。参阅https://dev59.com/T2Yr5IYBdhLWcg3wAFg0。 - Chris Halcrow
怎么样使用数组?Array.prototype.myFunc = function(a)[/*...*/].myFunc(5) 不能正常工作。 - undefined

22
String.prototype.distance = function( arg ) {
    // code
};

19

最简示例:

没有人提到valueOf方法。

==================================================

String.prototype.
OPERATES_ON_COPY_OF_STRING = function ( 
    ARGUMENT 
){

    //:Get primitive copy of string:
    var str = this.valueOf();

    //:Append Characters To End:
    str = str + ARGUMENT;

    //:Return modified copy:
    return( str );
};

var a = "[Whatever]";
var b = a.OPERATES_ON_COPY_OF_STRING("[Hi]");
console.log( a ); //: [Whatever]
console.log( b ); //: [Whatever][Hi]

从我的研究来看,没有办法直接编辑字符串。

即使你使用的是字符串对象而不是字符串原始数据类型。

下面的方法不起作用,并且在调试器中会得到非常奇怪的结果。

String.prototype.
EDIT_IN_PLACE_DOES_NOT_WORK = function ( 
    ARGUMENT 
){

    //:Get string object:
    var str = this;

    //:Append Characters To End:
    var LN = str.length;
    for( var i = 0; i < ARGUMENT.length; i++){
        str[LN+i] = ARGUMENT[ i ];
    };

};

var c = new String( "[Hello]" );
console.log( c );
c.EDIT_IN_PLACE_DOES_NOT_WORK("[World]");
console.log( c );

==================================================


3
这正是我搜寻的东西。 - Mahesh
虽然被接受的答案回答了原始问题,但这是一个更强大的总体通用答案。我必须问一下为什么要使用return(str)而不是return str? - Michael Hobbs
我正在为字符串类创建一个新的方法,类似于 String.prototype.toJadeCase()。而这个答案帮助了我实现它。 - Sunny Prakash

12
多年以来(以及ES6之后)...我们有了一种新的选择来完成这件事:

Object.defineProperty( String.prototype, 'distance', {
 value: function ( param )
 {
  // your code …
  return 'counting distance between ' + this + ' and ' + param;
 }
} );

// ... and use it like this:
const result = "a".distance( "b" );
console.log(result);


这只是为所有字符串定义一个通用属性。如果我想为每个字符串实例添加不同的函数实例,该怎么办? - Michael
@Michael 是的,这个例子只是为 String() 添加属性。但是可以通过使用 Window.prototype 而不是 String.prototype,将属性添加到所有对象中。 - undefined

8
你可以这样做:
String.prototype.distance = function (){ 
    //your code 
}

2
那是一个语法错误(你注释掉了闭合的大括号):D。 - Will

4
使用原型来添加你自己的函数到字符串中被称为原型。我创建了一小段JavaScript代码,可以选择元素并更改其innerHTML。
var dom; //you can replce this to be $ just like jQuery
dom = function(elm) {
if(typeof elm === "object") {
   // already done example 
   //typeof document.getElementById('id') will be object
   return [elm];
 } else {
    return document.querySelectorAll(elm);
 }
} // Returns elements by all css selector eg
// .class #id id p id > p id ~ p in short any css selectors 
 Object.prototype.text = function(txt) {  //object prototype as NodeList returned would be object or maybe displayed as [Object NodeList]
     var i = 0; //loop through the elements 
     for(i; i < this.length; i++) {
        this[i].innerHTML = txt;
      }
 // in this function this refers to object that this function is passed on
 };
 dom('.classh').text('Changed for elements with classh');
 dom('#heading').text('Changed for elements with id heading'); //examples

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接