【问题标题】:OLOO how to access private variableOLOO如何访问私有变量
【发布时间】:2016-11-03 07:14:21
【问题描述】:

在以下示例中,我使用 Kyle Simpson 的“OLOO(链接到其他对象的对象)模式”来创建对象序列化的简单示例。

我需要将变量 _data 保持私有(我正在使用闭包)并仅使用在对象实例级别(在 init 中)创建的 getter 和 setter 公开其属性。

目前我在init 中定义了函数toJson,所以它可以访问_data,它可以工作,但是我想知道:

  • 如果可以将toJson 函数移到init 之外(将其置于fromJson 的同一级别),那么它可以通过原型链访问,但允许访问_data 变量(我怀疑这是不可能的因为_data 它在一个闭包中)。
  • 否则你能否提出一个更好的替代方案(即使使用 ES6),同时考虑到 _data 不应该是可枚举的,也不能使用 getter 和 setter 进行修改?

        // example of serialization and deserialization of an object
        (function (window) {
            var dataApi = '{"id":0,"top":10,"left":20,"width":100,"height":150}';
            var state = JSON.parse(dataApi);
            var base = {
                init: function (data) {
                    var _data = data; // private
                    // defined on object itself not on its protoype
                    Object.defineProperty(this, 'id', {
                        get: function () {
                            return _data.id;
                        },
                        set: function (value) {
                            _data.id = value;
                        }
                    });
                    Object.defineProperty(this, 'top', {
                        get: function () {
                            return _data.top;
                        },
                        set: function (value) {
                            _data.top = value;
                        }
                    });
                    Object.defineProperty(this, 'left', {
                        get: function () {
                            return _data.left;
                        },
                        set: function (value) {
                            _data.left = value;
                        }
                    });
                    Object.defineProperty(this, 'width', {
                        get: function () {
                            return _data.width;
                        },
                        set: function (value) {
                            _data.width = value;
                        }
                    });
                    Object.defineProperty(this, 'height', {
                        get: function () {
                            return _data.height;
                        },
                        set: function (value) {
                            _data.height = value;
                        }
                    });
                    this.toJson = function () {
                        // move this function to prototype
                        return JSON.stringify(_data);
                    }
                },
                // defined on protoype
                fromJson: function (json) {
                    var data = JSON.parse(json),
                        obj = Object.create(this);
                    obj.init(data);
                    return obj;
                }
            };

            // create object with linked prototype using deserialization
            var wdgA = base.fromJson(dataApi);
            // serialize object
            var str = wdgA.toJson();
            console.log(str);

            // create object with data injection
            var wdgB = Object.create(base);
            wdgB.init(state);
            var id = wdgB.id;
            console.log(id);
        })(window);

【问题讨论】:

  • 如果问题不清楚,请添加评论,我会尽力澄清。谢谢。
  • 使 _data 成为不可枚举的私有对象属性。 JS 没有安全性,没有理由热衷于封装。
  • @estus 他/她如何将其设为私有?
  • @Taurus 我不确定你的意思。 _ 前缀在 JS 中是常规的,用于标记在正常情况下不应被外部访问的私有属性。它们可以是不可枚举的,不会意外出现在属性列表中。
  • @estus 在您的情况下,他/她是否将 _foo 属性直接添加到对象中,例如:var obj = {_foo: "bar"};,然后将其设为 enumerable: false

标签: javascript ecmascript-6 ecmascript-5


【解决方案1】:

我需要保持变量 _data 私有(我正在使用闭包)。是否可以将toJson 函数移到init 之外?

没有。不能从外部访问私有变量。

【讨论】:

    猜你喜欢
    • 2011-03-02
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 2015-09-25
    相关资源
    最近更新 更多