一个班级内的私人原型

时间:2014-09-09 15:39:08

标签: javascript prototype private

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

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中从类中声明私有原型?

2 个答案:

答案 0 :(得分:3)

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的实例。这为您提供了所需的额外(“私人”)原型。

然而,字符串是基元,基元不像普通对象那样工作;具体而言,they are autoboxed/ upcast to objects when you call methods on them。这意味着上述情况不适用于您的情况;由于"abc".replaceAll()将始终自动装箱到String,而不是MyString;并且你不能告诉JavaScript不这样做。

相反 ,你应该做什么(因为你不应该修改你不拥有的东西),正在创建一个帮助函数,你将字符串传入你的脏工作;

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

答案 1 :(得分:2)

由于String是一个全局对象,因此无法实现。无论你在哪里改变它或原型,它都会受到影响。

在你的情况下,你应该在你的班级中声明一个帮助函数。

function Template() {

    function stringReplaceAll(str, search, replace) {}

}

这个只会在你的课堂上出现。