(显然我不确定这个标题应该是什么。)
我希望能够以最小的风险修改原生对象的原型(因为相信我;我一遍又一遍地听到它是如何成为一个致命的javascript罪。)
我的思路是这样的:如果我可以将自定义函数添加到原型上的单个对象而不是直接将它们添加到原型本身,我可以大大减少冲突的可能性。
如果我有代码,
String.prototype.foo = function() {
//do stuff
};
...显然关键字this
引用了调用它的字符串。但是,如果我这样做,
String.prototype.foo = {};
String.prototype.foo.bar = function() {
//do stuff
};
...关键字this
引用对象foo
。
如果有办法克服这个问题?
答案 0 :(得分:1)
克服这个问题的唯一方法是使用call
覆盖上下文:
String.prototype.foo.bar.call('hello'))
有效,但非常荒谬。
你最好(正如你已经听到的那样)避免修改原生原型,而是让你的方法接受字符串作为参数。
答案 1 :(得分:0)
嗯,有几种方法可以做到这一点,具体取决于你想要投入多少工作。 使用bind是最简单的方法,但是你必须将字符串定义为变量,这样你就可以将它的引用传递给bind:
String.prototype.foo = function() { console.log(this); }
String.prototype.foo.bar = function() { console.log(this); }
var g = "hi there";
g.foo() // Yields g
g.foo.bar() // Yields String.prototype.foo()
g.foo.bar.bind(g)() // Yields g again.
通过在String.prototype.foo上创建getter和setter来生成所需结果可能有另一种非常hackish的方法,以便String.prototype.foo.bar激活一个函数,该函数返回绑定到foo引用的实例的函数。 ???混乱。
减少冲突可能性的最佳解决方案是利用原型继承并创建自己的原生String子原型。
function MyString(string) {
this.foo = function() { //whatever };
this.foo.bar = (function() {}).bind(this);
this.toString = function() { return string; } // because toString is not generic.
}
MyString.prototype = new String();
在这里,您将创建自己的String原型的“子原型”。它继承了String原型的所有属性并添加了它自己的属性,而根本不需要改变本机字符串。奖励:this.foo和this.foo.bar都会引用你的实例。
var instance = new MyString("hi");
instance.foo(); // this == instance
instance.foo.bar(); // this == instance
instance.replace("i", "e"); // returns "he"
这可能不是你想要的答案,但希望它至少会有所帮助。