创建一个不是参考的IIFE类? [英] Create a class with IIFE that isn't a reference?

查看:112
本文介绍了创建一个不是参考的IIFE类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是JavaScript的新手,我试着用创建私有数据和公共函数的类。我已经被告知立即调用函数表达式(IIFE)完成这一点,但是当我从类实例化新对象,他们引用私人数据,而不是自己持有。

I'm new to JavaScript and I'm trying to wrap my head around creating "classes" with private data and public functions. I've been told Immediately Invoked Function Expressions (IIFE) accomplish this but when I "instantiate" new objects from the class they reference the private data instead of holding their own.

其中一些是借用自创建JS类:IIFE与返回原型

例如,一个简单的汽车类:

For example, a simple Car "class":

var Car = (function() {

    var body = { color: 'red' };
    Car.prototype.newColor = function(color) {
            body.color = color;
        };
    Car.prototype.getColor = function() {
            return body.color;
        };

    return Car;
})();

var car1 = new Car();
var car2 = new Car();

car2的颜色也变成紫色。

car2's color also gets changed to purple.

car1.newColor('purple');
car2.getColor(); // 'purple'



我希望Car类的每个对象都拥有自己的私有数据。

I want each object of the Car class to hold its own private data. How can this be accomplished with IFFE, or is there another way?

推荐答案

模拟私有实例变量的唯一方法是声明

The only way to simulate private instance variables it to declare them as var myprivate in the constructor function.

任何特权方法(=可访问私有成员的方法)必须在构造函数的主体中声明,所以不能在原型上(将花费你额外的CPU和内存,也许不会在一些JS引擎中优化)。

Any privileged method (=method that can access the private member) has to be declared within the constructor function's body as well so can't be on the prototype (will cost you extra cpu and memory and maybe doesn't optimize as well in some JS engines).

我从来没有一个需要这样做的情况,因为在我看来,成本是不值得的收益。通常通过广泛使用的命名约定(名称以下划线开头)向我的未来自我和其他程序员指示成员是私有的 _myPrivate

I never had a situation where it was needed to do this since in my opinion the cost is not worth the gain. Usually indicate to my future self and other programmers that a member is private by a widely used naming convention (name starts with underscore) _myPrivate

公开覆盖的答案激励我创建以下代码。私人实例成员可以通过 ben._data.set 公开访问,或者您可以重新实现规则和/或getter / setter,以便有人仍然可以滥用它。它仍然可以清理你的对象的公开访问成员,并使它更容易使用getters和setter。

"Public override"'s answer inspired me to create the following code. Private instance members can be accessed publicly by ben._data.set or you could re implement rules and or getters/setters so someone could still abuse it. It can still clean up you're object's publicly accessible members and making it easier to use the getters and setters.

//Namespacing DataStore to limit scope of the closures
var tools = {
  DataStore : function(){
    var store = [];
    this.get = function(key){
      return store[key];
    };
    this.set = function(key,value){
      store[key] = value;
      return value;
    };
  }
};
//Person constructor
var Person = function(name){
  //you can access this member directly
  // bob.name = "Lucy";
  this.name=name;
  //if having _data as not accesable by defining
  //  with var _data we whould have to define
  //  get and set here as this.get and this.set
  this._data=new tools.DataStore();
};
//constant value used to get or set, for example:
//ben.get(ben.AGE);
//Could add this and rules to Person instead of Person.prototype
//then you'll need a helper function to set up inheritance
//to make sure the static's on Person are copied to it's children
Person.prototype.AGE=0;
//rules for getters and setters
//Will be a problem with inheritance if on prototype 
//function Employee(name){Person.call(this,name);};
//Employee.prototype=Object.create(Person.prototype);
//Employee.prototype.rules["0set"]=..overwrites Person.prototype.rules["0set"]
//When inheriting you need to have a helper function set the rules for a child
//object
Person.rules = {}
//rule for AGE set
Person.rules[Person.prototype.AGE+"set"] = function(val){
  var tmp;
  tmp = parseInt(val);
  if(isNaN(tmp)){
    throw new Error("Cannot set the age of the person "+
      "to non number value, value of age:"+val);
  }
  if(tmp>150){
    throw new Error("Are you sure this is a person and "+
      "not a turtule? Trying to set age to:"+val);
  }
  return this._data.set(this.AGE,tmp);
};
//rule for age get
Person.rules[Person.prototype.AGE+"get"] = function(){
  return this._data.get(this.AGE);
};
Person.prototype.get = function(key){
  return Person.rules[key+"get"].call(this);
};
Person.prototype.set  = function(key,value){
  return Person.rules[key+"set"].call(this,value);
};

var ben = new Person("Ben");
ben.set(ben.AGE,22);
console.log(ben.get(ben.AGE));
try{
  ben.set(ben.AGE,151);
}catch(e){
  console.log("error",e);
}
try{
  ben.set(ben.AGE,"HELLO WORLD!");
}catch(e){
  console.log("error",e);
}

注意事项: Person.rules

Note of caution: Person.rules needs to be copied to Child instances when you want to inherit from Person.

有关原型,继承,覆盖,调用超级,多重继承(mix in)的更多信息, )和的值: http://stackoverflow.com/a / 16063711/1641941

More about prototype, inheritance, overriding, calling super, multiple inheritance(mix in) and the value of this here: http://stackoverflow.com/a/16063711/1641941

这篇关于创建一个不是参考的IIFE类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆