类中的私有原型

private prototype from within a class

本文关键字:原型      更新时间:2023-09-26

假设我定义了一个类Template(),在其中我需要用一些prototype来扩展String,以便为其添加功能:

function Template() {
    String.prototype.replaceAll = function(find, replace) {
        return this.replace(new RegExp(find.replace(/([.*+?^=!:${}()|'[']'/''])/g, "''$1"), 'g'), replace);
    }
    this.test = function (){
        return "hello".replaceAll("h", "y");
    }
}

现在,如果我声明一个new Template(),那么String.prototype是公共的:

var myTemplate = new Template();
console.log(myTemplate.test()); // outputs "yello", this is desired
console.log("hello".replaceAll("h", "y")); // outputs "yello", this should not work

而我希望StringTemplate()类之外保持不变,同时仍然从内部进行扩展。

如何在javascript中从类中声明私有原型?

general中,执行相反的操作;您创建了一个新函数,它的原型是您想要扩展的"类",然后将新方法添加到该函数中;

function MyString() {
}
MyString.prototype = new String();
MyString.prototype.replaceAll = function (find, replace) {
    return this.replace(new RegExp(find.replace(/([.*+?^=!:${}()|'[']'/''])/g, "''$1"), 'g'), replace);
};

您可以在任何范围内创建MyString,这样它就可以是您想要的私有或公共。然后,在您的范围内创建MyString而不是String的实例。这为您提供了所需的额外("私人")原型。

但是,字符串是基元,基元不像普通对象那样工作;特别是,当您调用对象上的方法时,它们会自动装箱/向上转换为对象。这意味着以上内容在您的情况下不可用;因为"abc".replaceAll()将总是自动装箱到String而不是MyString;你不能告诉JavaScript做其他事情。

相反应该做的事情(因为你无论如何都不应该修改你不拥有的东西)是创建一个助手函数,你可以将字符串传递到该函数中来完成你的脏工作;

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(find.replace(/([.*+?^=!:${}()|'[']'/''])/g, "''$1"), 'g'), replace);
}
这是不可能的,因为String是全局对象。无论你在哪里更改它或它的原型,它都会受到影响。

在您的情况下,您应该在类中声明一个helper函数。

function Template() {
    function stringReplaceAll(str, search, replace) {}
}

这个只有你们班才有。