[英]JavaScript: Adding a Namespace to Prototype Methods
我有一个商业应用程序,该应用程序具有使用原型链的现有JavaScript对象结构。 通过在对象原型中添加更多方法,我成功扩展了此API。 但是,我意识到最好是在我的方法前添加一个名称空间,以防应用程序供应商决定命名一个新方法,使其与将来版本中的一个方法相同。
如果我有一个名为State的现有对象,则可以添加一个名为getPop的方法,如下所示:
State.prototype.getPop = function(){return this.pop;};
var Washington = new State('Washington',7000000);
Washington.getPop(); //returns 7000000
我想做的是在自定义方法之前添加一个名为“ cjl”的命名空间,以避免名称冲突,这样我就可以这样调用它:
Washington.cjl.getPop();
我试过了:
State.prototype.cjl = {};
State.prototype.cjl.getPop = function(){return this.pop;};
. 问题是 。 它不指向实例,而是指向'cjl'对象。
我尝试了各种方法,包括使用.bind(),但似乎都没有用。 我终于在这里找到答案: 是否可以将对象原型上的方法组织到名称空间中? 使用Object.defineProperty()方法可以工作。 问题在于商业应用程序仅在IE中的兼容模式下工作,该模式不支持非DOM元素的Object.defineProperty()方法。
还有另一种方法可以做到这一点吗? 我不想调用多个函数,这是某些技术的结果,例如:
Washington.cjl().getPop();
您可以通过以下方式命名空间,阅读您的评论,我看到您无法更改原始构造函数,因此必须将其替换为自己的原始构造函数并将其保存在闭包中。
每个状态实例都有其自己的cjl实例,但仅具有对当前State实例的引用,所有cjl函数均被共享,因为它们仅存在一次:
[更新]忘记在myState的原型链中获取State.prototype。
//the original constructor
function State(name, pop){
this.name=name;this.pop=pop;
}
State.org="original constructor";
//original constructor is available through
// closure and window.State is replaced with
// your constructor having the cjl namespace
(function(State){
//cjl namespace
function cjl(stateInstance){
this.stateInstance=stateInstance;
};
//cjl functions
cjl.prototype.getPopInThousands=function(){
//do not use this, instead use this.stateInstance
return this.stateInstance.pop/1000;
}
function myState(){
//apply State constructor
State.apply(this,arguments);
//create a clj instance, all methods
// are on cjl.prototype so they're shared
this.cjl = new cjl(this);
}
//inherit from State (use polyfil for older browsers)
myState.prototype = Object.create(State.prototype);
//replace window.State with your constructor
window.State=myState;
}(State))
var s = new State("Wasington", 7000000);
console.log(s.cjl.getPopInThousands());
//non standard, name
console.log("constructor name",s.constructor.name);
console.log("constructor tostring",s.constructor.toString());
有关构造函数和原型的更多信息,请参见: https : //stackoverflow.com/a/16063711/1641941
我必须同意朋友和Cookie的观点,即预先确定函数名称可能是更好的解决方案,但是如果您想对名为Country的对象使用相同的方法,那么您可能会考虑使用前面的代码,因为可以重新使用cjl对象。
与其在函数外定义State.prototype.cjl
, cjl
在构造函数内设置cjl
“命名空间”。
function State(){
var thisObject = this;
this.cjl = {
getPop: function(){
return thisObject.pop;
}
};
}
然后,您可以执行Washington.cjl.getPop();
。
尝试:
var State = function(name, pop) {
this.name = name;
this.pop = pop;
};
State.prototype.cjl = function(method) {
return this.cjlDefs[method].apply(this, Array.prototype.slice.call(arguments, 1) );
};
State.prototype.cjlDefs = {
getPop: function() {return this.pop;}
};
var Washington = new State('Washington', 80000);
console.log( Washington.cjl('getPop') );
https://jsfiddle.net/ghbjhxyh/
或其他形状,如果您喜欢:
var State = function(name, pop) {
this.name = name;
this.pop = pop;
};
State.prototype.cjl = function(method) {
this.cjlDefs.obj = this;
return this.cjlDefs;
};
State.prototype.cjlDefs = {
assertObj: function() { /* Make sensible assertion */ },
getPop: function() { this.assertObj(); return this.obj.pop; }
};
var Washington = new State('Washington', 75000);
console.log( Washington.cjl().getPop() ); // 75000
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.