问题 如何在Ember.Object中创建私有方法/属性?


我们可以像这样创建Em.Object:

var foo = Em.Object.create({
   somevar : '123'
});

然后使用它:

foo.get('somevar');

但是如何在Em.Object中创建一个私有属性或方法,可以从对象访问但不是我们的?


5147
2017-08-27 12:23


起源



答案:


这是不可能的,因为Ember.js不提供任何封装机制。

但是,您可以简单地为私有成员使用某些约定。例如,用它们作为前缀 _ 标志。


6
2017-08-27 13:14



得到它,thanx!有趣的是,ember的作者在提交这类功能方面很有趣 - Iliya Garakh
对于五年后来这里的游客,请注意这个(接受的)答案是错误的。


答案:


这是不可能的,因为Ember.js不提供任何封装机制。

但是,您可以简单地为私有成员使用某些约定。例如,用它们作为前缀 _ 标志。


6
2017-08-27 13:14



得到它,thanx!有趣的是,ember的作者在提交这类功能方面很有趣 - Iliya Garakh
对于五年后来这里的游客,请注意这个(接受的)答案是错误的。


确实有一种在Ember对象中拥有私有变量的方法,如下所示:

MyObject = Ember.Object.extend({
  init: function() {
    // private variable
    var a = 1;

    // methods to get, set, or otherwise accesss the private variables
    this.getA = function() {return a;};
    this.setA = function(val) {a = val;}

    // don't forget this!
    this._super(...arguments);
  }
});

现在试试

o1 = MyObject.create()
o2 = MyObject.create()
o1.setA(42);
o2.getA(); //1

换句话说,你必须声明私有变量,以及任何想要使用它们的getter,setter或其他例程。 init 钩。当然,这意味着那些getter / setter将出现在类的每个实例上,而不是它的原型中。这样效率稍低,但对于JavaScript中的类的私有变量的任何方法都是如此。

可以想象,Ember可以推出一款新产品 private: {} 在对象上散列,但是然后Ember需要很多机制来处理查找和控制跨类层次结构的私有变量的访问。这相当于重新设计或扩展语言本身,这不是Ember任务的一部分。

同时,如果私有实例变量的数量有限并且需要访问它们的例程的数量很少,则上述方法可以正常工作。因此,接受的答案是不可能的,这是错误的。


7
2018-04-12 03:47



这应该被投票,因为它是正确答案,并且仍然与Ember 2.0相关 - Vassi


你可以使用一个闭包:

(function() {
    var somePrivateProperty = 'xyz';

    MyObject = Em.Object.extend({
        someComputedProperty: function() {
            return 'somePrivateProperty = ' + somePrivateProperty;
        }).property()
    })
})();

0
2017-08-27 21:31



是的,但MyObject.get('someComputedProperty')几乎可以在任何地方使用 - Iliya Garakh
这是行不通的,因为 somePrivateProperty 将在所有实例之间共享。


可以通过一个小技巧:

var obj = Em.Em.Object.create(
    new function(){
        var privateVar = "this is private";
        this.getPrivateVar = function(){
            return privateVar ;
        }
    },
    {
        emberVar: "Ember var",
        emberMethod : function(){
            return this.getPrivateVar();
        },
        emberMethod1 : function(){
            return privateVar ;
        },
        emberBinding : 'emberVar'
    }
)

现在,如果你试图得到 private VAR

obj.privateVar 
> unknown

obj.getPrivateVar()
> "this is private"

obj.emberMethod()
> "this is private"

唯一的问题是:

obj.emberMethod1()
> unknown

0
2017-09-14 09:08



这不起作用,因为 privateVar 将在所有实例之间共享。