假设我定义了一个类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
我想要的是String
在Template()
课程之外保持不变,同时仍然从内部延伸。
如何在javascript中从类中声明私有原型?
答案 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) {}
}
这个只会在你的课堂上出现。