0

在 JavaScript 中,我试图实现私有变量(就像在其他 OOP 语言中一样)。

是否只能通过闭包或者是否有任何其他方式可以实现私有变量?

任何例子都会很有帮助。

4

3 回答 3

0

对于一个类(函数),它只是使用“var”与“this”:

function myObject() {
  var myPrivateVariable = 10;
  this.myPublicVariable = 20;
}
于 2013-02-21T17:48:42.990 回答
0

私有成员由构造函数创建。构造函数的普通变量和参数成为私有成员。

function Container(param) {
    this.member = param;
    var secret = 3;
    var that = this;
}

此构造函数生成三个私有实例变量:param、secret 和 that。它们附加到对象上,但外部无法访问它们,对象自己的公共方法也无法访问它们。私有方法可以访问它们。私有方法是构造函数的内部函数。

function Container(param) {

    function dec() {
        if (secret > 0) {
            secret -= 1;
            return true;
        } else {
            return false;
        }
    }

    this.member = param;
    var secret = 3;
    var that = this;
}

私有方法 dec 检查秘密实例变量。如果它大于零,它会递减 secret 并返回 true。否则返回false。它可用于使此对象仅限于三种用途。

按照惯例,我们创建一个私有this变量 ( that)。这用于使对象可用于私有方法。这是 ECMAScript 语言规范中错误的解决方法,该错误导致this内部函数设置不正确。

私有方法不能被公共方法调用。为了使私有方法有用,我们需要引入一个特权方法。

作为参考,你可以看到这个http://javascript.crockford.com/private.html

于 2013-02-21T17:51:23.617 回答
0

任何变量仅在定义它的函数内是已知的。因此,Sahil Grover接受的答案几乎涵盖了基础知识,除了最近添加到 JavaScript 规范:let声明。

Node.js和现代浏览器中,您现在也可以这样做:

function loop(arr) {
    // i IS NOT known here
    // j IS NOT known here

    for( var i = 0; i < arr.length; i++ ) {
        // i IS known here
    };

    // i IS known here
    // j IS NOT known here

    for( let j = 0; j < arr.length; j++ ) {
        // j IS known here
    };

    // i IS known here
    // j IS NOT known here
}

let varName = ...只有它所在的才知道。所以,在这种情况下,我们的变量j只在第一个 for 循环中是已知的,而不是之前和之后。如果var varName = ...改为使用 a,则从定义它的那一刻起,它在整个函数中都是已知的。


现在,让我们超越基础。

JavaScript 的一个优点是它给你很大的自由来定义你的对象。然而,这也是一个弱点,因为今天几乎每个人都有自己的方式在 JavaScript 中进行 OOP。

我自己编写的大多数 JavaScript 代码通常使用以下模式:

var keyValueStore = (function() {
    // Private "static" properties go here
    var count = 0; 

    var kvs = function() {
        // Here, you can define private instance properties as "var property = ..."
        // You can also define public instance properties as "this.property = ..."
        count++; 
    };

    kvs.prototype = {
        // Public instance properties can also go here
        ‘data’ : {},
        ‘get’ : function(key) {
            return this.data[key];
        },
        ‘set’ : function(key, value) {
            this.data[key] = value;
        },
        ‘delete’ : function(key) {
            delete this.data[key];
        },
        ‘getLength’ : function() {
            var l = 0;
            for (p in this.data) l++;
            return l;
        }
    };

    return {
        // Public "static" properties go here
        ‘create’ : function() { return new kvs(); },
        ‘count’ : function() { return count; }
    };
})();

正如我在代码中添加的注释所示,此模式允许您定义“静态”属性(“类”级别的属性)和实例属性,两者都可以是私有的或公共的。与我见过的其他一些模式不同,它这样做不会使您的代码非常难以理解。

用法 :

kvs = keyValueStore.create();
kvs.set(‘Tom’, “Baker”);
kvs.set(‘Daisy’, “Hostess”);
var profession_of_daisy = kvs.get(‘Daisy’);
kvs.delete(‘Daisy’);
console.log(keyValueStore.count());
于 2016-02-23T17:18:05.147 回答