JavaScript类和变量范围

Cmc*_*Cmc 13 javascript variables class

我是JS的新手,我遇到了正确模仿OOP原则的问题.

我想我有两个问题.问题首先是关于声明变量的许多方法.

说我有一节课:

function clazz(a)
{
    this.b = 2;
    var c = 3;
    this.prototype.d = 4; // or clazz.prototype.d = 4?
}

var myClazz = new clazz(1); 
Run Code Online (Sandbox Code Playgroud)

我在以下评估中是否正确:

a是一个特定于实例的私有变量(即clazz的不同实例将具有唯一且独立的变量'a').它可以从clazz中访问:'a'.

b是一个特定于实例的公共变量.它可以在clazz中作为'this.b'访问,也可以从外部clazz访问'myClazz.b'.

c是一个静态或类特定的私有变量(即clazz的不同实例将共享相同的'c'变量).它可以在任何clazz实例中以"c"的形式进行访问,并且clazz实例中的更改会反映在clazz的所有实例中.

d是一个静态/类特定的公共变量.它可以通过'clazz.prototype.d'或'myClazz.prototype.d'从任何地方访问.

我对变量方案的理解的总体问题是,没有办法声明非静态的私有变量(即每个类的实例的唯一版本).

第二个问题是关于不同类型的类声明.

我一直在用:

var MySingleton = new function() {...};
Run Code Online (Sandbox Code Playgroud)

创造单身人士.它是否正确?我也不确定在这种情况下"new"关键字的效果以及在声明结尾附加()函数括号如下:

var MySingleton = new function() {...}();
Run Code Online (Sandbox Code Playgroud)

我一直在使用这种模式声明一个类,然后实例化该类的实例:

function myClass() {...};
var classA = new myClass();
var classB = new myClass();
Run Code Online (Sandbox Code Playgroud)

这是正确的方法吗?

CMS*_*CMS 20

你是正确的ab:

a是一个参数,仅在构造函数的范围内可用.

b是一个公共实例变量,可在使用该构造函数创建的所有实例上使用.

c 是一个私有变量,只能在构造函数中访问.

d声明是无效的,因为prototype对象是指可以仅使用构造函数一样Clazz.prototype.d = 3;,如果你不喜欢这样,该变量将被共享的,但你可以在一个特定的实例分配一个值,默认值将是阴影(通过原型链).

对于"私有变量",您可以使用您声明的方式c,例如:

function Clazz(){
    var c = 3; // private variable

    this.privilegedMethod = function () {
      alert(c);
    };
}
Run Code Online (Sandbox Code Playgroud)

特权方法是公共的,但是它们可以访问构造函数内声明的"私有"变量.

对于创建单例,最简单的方法是使用对象文字,例如:

var myInstance = {
  method1: function () {
    // ...
  },
  method2: function () {
    // ...
  }
};
Run Code Online (Sandbox Code Playgroud)

如果您想在单例实例上使用私有成员,您可以:

var myInstance = (function() {
  var privateVar = '';

  function privateMethod () {
    // ...
  }

  return { // public interface
    publicMethod1: function () {
      // all private members are accesible here
    },
    publicMethod2: function () {
    }
  };
})();
Run Code Online (Sandbox Code Playgroud)

这被称为模块模式,它基本上允许您通过利用闭包来封装对象上的私有成员.

更多信息:

编辑:关于您发布的语法:

var mySingleton = new (function() {
  // ...
})();
Run Code Online (Sandbox Code Playgroud)

通过使用new运算符,您将在一步中声明并使用" 匿名构造函数 ",它将生成一个新的对象实例,它是有效的但我个人更喜欢"模块"模式方法,以创建我自己的对象实例(并避免new).

此外,阅读new function () {},我认为这不是非常直观,如果您不太了解new运营商的运作方式,可能会产生混淆.

关于括号,它们是可选的,new如果不添加它们,操作符将调用不带参数的函数构造函数(参见ECMA- 262,11.2.2).

  • +1.一个非常完整和翔实的答案. (2认同)