ecomfe / oo

Base library for OO style programming
MIT License
5 stars 5 forks source link

定义私有成员 #23

Closed Exodia closed 8 years ago

Exodia commented 9 years ago
var exports = {};
exports.$privae = {};
exports.$private.privateMethod = function () {};
exports.$private.privateMember = 'private';
exports.publicMethod = function () {
    this.privateMethod();
};

var MyClass = oo.Class(exports);

var instance = new MyClass();
instance.publishMethod();

instance.privateMethod() // throw error;
instance.privateMember() // throw error

实现上:

会借助Object.defineProperty的 getter/setter 和 callerowner 来做限制,ie8下不做支持,毕竟我们的开发调试流程是在支持es5的环境下下进行的,仅仅是定义了开发模型,不会对 ie8造成功能影响。

otakustay commented 9 years ago
exports.$private.privateMethod = function (anotherInstance) {
    if (anotherInstance) {
        anotherInstance.privateMethod();
    }
};

能做到不?

Exodia commented 9 years ago

@otakustay 可以做到, 不过目前想到的方案还是读 caller;但 es6下,是默认 strcit mode 的,所以我想想是否有不通过 caller 的方案。

Justineo commented 9 years ago

我们后面可能会把这个 lib 用到 IE6 环境里,能不能给下哪些 feature 是不兼容 IE6 的?

Exodia commented 9 years ago

我们后面可能会把这个 lib 用到 IE6 环境里,能不能给下哪些 feature 是不兼容 IE6 的?

目前的 feature 都是可以用到 ie6的; 未来新增加的 private和 protect 特性会保证 ie6运行时兼容。

Justineo commented 9 years ago

好的,privateprotected 只是开发环境限制是吧。

otakustay commented 9 years ago

我比较倾向于为es6再做一个版本

  1. getter/setter可以基于Symbol实现
  2. 使用defineProperty等功能来实现更标准的属性定义

理论上在有Object.getPrototypeOf追溯原型链的情况下,privateprotected都能做的,可以做成开发期有限制,生产环境去掉影响性能的追溯限制?

otakustay commented 9 years ago

另外从API上来说我觉得可以提供definePrivateMethod(s)definePrivateProperty(ies)方法直接声明,不一定要把整个完整的exports给出来再Class.create

Exodia commented 9 years ago

我也考虑给es6单独再做一套方案;

api 上,计划差不多,也是打算提供相关的 api,配置部分只是简化的语法糖

otakustay commented 9 years ago

还有,从我对strong mode的解读来看,在strong mode下class定义的类的prototype是不能扩展的,到那个时候eoo应该就没用了,各方写ES6的也可以参考下这一点

Exodia commented 9 years ago

api 我打算这样提供:

oo.definePrivateMembers(['prop1', 'prop2']);

配置上的写法: $private: ['prop1', 'prop2'];

不提供赋值功能,仅提供声明某个属性(自然包括了方法属性)为私有; 主要考虑的是加了赋值功能会使得职责会变得复杂,赋值这些功能应该交给 defineProperty 去做;

Exodia commented 9 years ago

初步实现完毕,见分支: https://github.com/ecomfe/oo/tree/feature/private

api接口:

/**
   * @param {Function} Class  Class 类 
   * @param {string[]} privateMembers 私有成员列表
*/
oo.definePrivateMembers(Class, privateMembers);

配置写法通过$private对象提供:

Super = Class.create({
                publicProp: 10,
                $private: {
                    privateFromListMethod: function () {
                        return 'privateFromListMethod';
                    },
                    privateMethodInSuper: function () {
                        return '';
                    }
                }
});

ie8下的兼容用例后面补充,目前先做实验性使用