'这个'在js类方法中是不正确的

时间:2016-06-17 05:08:42

标签: javascript

我在js中像func一样写'class'。对于那些私有方法,我想隐藏它,而不是前缀'_'并且位于func原型内。

所以我所做的就是在类/ func定义之外编写那些私有函数。

现在唯一的问题是如何调用该方法。

  1. this.somePrivateMethods将无法使用,因为那些不在类定义中
  2. somePrivateMethods.call(this, arg1, arg2)按预期工作。但它似乎太hacky?
  3. 不知道为什么简单地在另一个类方法中调用somePrivateMethods()会在上下文中有window

    你们对此有何看法?

    window.name = 'window name';
    
    var A = function(){
      this.name = 'A name';
    }
    
    A.prototype.publicMethod = function(){
      
      //this is working, but the method is attach to the prototype, and outsider can invoke that method accidentally
      this._privateMethod();
      
      //this is not working
      _privateMethod2();
      
      //this works, outsider cannot call the private method, but the syntax doesn't look good.
      _privateMethod2.call(this);
      
      
      function _privateMethod2() {
        console.log(this.name);
      }
      
    }
    
    A.prototype._privateMethod = function() {
      console.log(this.name);
    }
    
    
    var a = new A();
    a.publicMethod();

1 个答案:

答案 0 :(得分:0)

您可以在构造函数中使用var,或者只是在其中定义函数,而不将其作为属性。

var fakeStaticVar = 'Everything below can inherit';
function YourConstructor(){
  var privateVar = 'Notice the first bunch of console.log()s';
  this.publicProp = 'This will be public';
  this.setPrivateVar = function(str){
    privateVar = str;
  }
  this.getPrivateVar = function(){
    return privateVar;
  }
  this.setPublicProp = function(str){
    this.publicProp = str;
  }
  this.getPublicProp = function(){
    return this.publicProp;
  }
  function privateFunc(str){
    privateVar = str;
  }
  this.executePrivateFunc = function(str){
    privateFunc(str);
    return privateVar; // returns as well - for testing
  }
  this.setFakeStaticVar = function(str){
    fakeStaticVar = str;
  }
  this.getFakeStaticVar = function(){
    return fakeStaticVar;
  }
}
var privateVar = 'Not the same as the privateVar in YourConstructor';
function privateFunc(){
  return 'Not the same as the one in privateFunc in YourConstructor';
}
var yc = new YourConstructor; console.log(yc.privateVar);
console.log(privateVar); yc.setPrivateVar('cool');
console.log(privateVar); console.log(yc.privateVar);
console.log(yc.getPrivateVar()); yc.publicProp = 'now';
console.log(yc.getPublicProp()); console.log(yc.publicProp);
yc.setPublicProp("you're learning"); console.log(yc.getPublicProp());
console.log(privateFunc()); console.log(yc.privateFunc);
yc.executePrivateFunc('neat'); console.log(yc.getPrivateVar());
yc.setFakeStaticVar('Awesome'); 
var nc = new YourConstructor; console.log(nc.getFakeStaticVar());

希望这会有所帮助。注意YourConstrutor没有参数,因此在创建()实例时可以不使用new

虽然JavaScript中没有静态属性,但这种行为也可以使用prototype模仿:

function A(){
  this.test = 'rad';
}
var a = new A;
a.newProp = 'new prop value';
console.log(a.newProp);
var b = new A;
console.log(b.newProp); // undefined

现在试试这个:

function A(){
  this.test = 'rad';
}
var a = new A;
A.prototype.newProp = 'new prop value';
console.log(a.newProp);
var b = new A;
console.log(b.newProp);

对于内部静态属性,您可以在构造函数中使用this.constructor.prototype

function C(value){
  this.notStaticProp = value;
  this.setStaticProp = function(prop, val){
    this.constructor.prototype[prop] = val; // static
  }
}
var a = new C('any value here');
console.log(a.notStaticProp);
a.setStaticProp('wow', 'it works'); // sets static property
var b = new C('different value');
console.log(b.notStaticProp);
console.log(b.wow);

这是创建一种静态var的另一种方法:

var counter = (function(){
  var c = 0;
  return function(){
    return ++c;
  }
})();
console.log(counter()); console.log(counter());

一切都与范围有关。注意:使用var时,在定义函数或构造函数时,不能在其定义之上调用它。如果var未使用,您可以在任何地方致电或制作new个实例。