JavaScript - 私人会员解释?

时间:2016-02-03 10:30:42

标签: javascript encapsulation data-hiding

我正在阅读Crockford的这篇文章: http://www.crockford.com/javascript/private.html

在他谈到私人的部分,他说:

  

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

现在,如果我在我的剧本中这样做:

"use strict"
function car(brand) {
    this.brand = brand;
    var year = 2012;
    var color = "Red";
}

var bmw = new car("BMW");
console.log(bmw.brand); // BMW -> VISIBLE ?!?

我可以轻松访问通过构造函数传递的属性! 有人可以更好地解释这一点,不应该通过构造函数传递这些变量是私有的吗?

谢谢!

4 个答案:

答案 0 :(得分:1)

我认为您错误地解释了这一点信息。它并没有说私人方法是那些通过"通过"构造函数,它表示那些"由"构造函数。

要清楚,请看一下:

function car(brand) {
    var year = 2012;
    var color = "Red";
}

3 私有变量。 brandyearcolor。通过添加此行

this.brand = brand

您正在创建公共属性并为其分配私有变量中的值。你已经将公共财产和私有变量命名为同一个东西既不是在这里也不是在那里,如果它更清楚地将其视为

this.publicBrand = brand

答案 1 :(得分:0)

并不是说您可以访问传递给构造函数的值。您所做的是将this.brand设置为等于构造函数中传递的值。因此,公开的brand现在具有与传入的值相同的值。构造函数brand中的本地!= this.brand,直到您设置它为止。

答案 2 :(得分:0)

您分配给上下文的所有内容(内部函数)都是公共可用的。请注意,如果您在没有 new

的情况下调用该函数,则上下文是窗口对象
"use strict"
function car(brand) {
    this.brand = brand; //Public (can be accessed from outside because it is attached to the context/this)
    var year = 2012; //Private (inside function only)
    var color = "Red"; //Private (inside function only)
}

var bmw = new car("BMW");
console.log(bmw.brand); // BMW -> VISIBLE -> this.brand = brans

答案 3 :(得分:0)

解决方案:使用闭包创建一个无法访问的“私有”范围。

"use strict";

(function (parent) {
    (function (parent) {
        var instances = {};

        parent.getPrivateInstance = function (c) {
            return instances[c];
        };

        parent.setPrivateInstance = function (c, value) {
            instances[c] = value;
        };
    } (this));

    parent.Class = function (name) {
        setPrivateInstance(this, {
            name: name
        });
    };

    parent.Class.prototype.logName = function () {
        console.log(getPrivateInstance(this).name);
    };
})(window);

var c = new Class("test");

c.logName(); // "test"

console.log(c.name); // undefined

警告:内存泄漏

这将创建一种情况,其中垃圾收集器将不再清除与Class实例关联的内存,因为它们将始终被引用,这会导致内存泄漏。

要解决此问题,我们必须手动删除对Class实例的引用。这可以通过在parent.setPrivateInstance部分之后添加一段代码并在parent.Class.prototype.logName部分之后添加一段代码来完成。这些代码片段看起来像这样:

parent.deleteFromMemory = function (c) {
    delete instances[c];
};
parent.Class.prototype.deleteFromMemory = function () {
    deleteFromMemory(c);
};

用法

c = c.deleteFromMemory();

有关所有作品的示例:https://jsfiddle.net/gjtc7ea3/

声明

由于此解决方案导致内存泄漏,我个人建议不要使用它,除非您知道自己在做什么,因为这里很容易出错。