0

我从 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

4 回答 4

1

我认为你误解了那一点信息。它并没有说私有方法是那些“通过”构造函数的方法,它说的是那些“由”构造函数“制造”的方法。

为了清楚起见,看看这个:

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

那有3个私有变量。brand,yearcolor. 通过添加这一行

this.brand = brand

您正在创建一个公共属性并为其分配私有变量中的值。您将公共属性和私有变量命名为相同的东西既不存在也不存在,如果它更清楚地认为它是

this.publicBrand = brand
于 2016-02-03T10:35:36.123 回答
0

您分配给上下文的所有内容(this内部函数)都是公开的。请注意,如果您在没有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
于 2016-02-03T10:39:26.573 回答
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/

免责声明

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

于 2017-05-01T11:27:37.993 回答
0

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

于 2016-02-03T10:35:33.627 回答