繁体   English   中英

JavaScript:将命名空间添加到原型方法

[英]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.cjlcjl在构造函数内设置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

https://jsfiddle.net/7vjrz2mn/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM