我想了解JavaScript中封装的概念,以及如何使我的属性和方法公开或私有。

我在玩这个例子:

    var person = function(newName, newAge) {

    // Private variables / properties
    var name = newName;
    var age = newAge;

    // Public methods
    this.getName = function() {
        return name;
    }

    // Private methods
    var getAge = function() {
        return age;
    }

    // Public method, has acces to private methods
    this.giveAge = function() {
        return getAge();
    }
}

var jack = new person("Jack", 30);

console.log(jack.name); // undefined
console.log(jack.getName); // Jack
console.log(jack.getAge()); // TypeError: jack.getAge is not a function
console.log(jack.getAge); // undefined
console.log(jack.giveAge()); // 30


因此,变量var namevar age是私有的。要访问它们,我通过使用.this引用使用公共方法。因此,函数内部的var都是私有的,而对象内部的.this则在外部可见。

我猜这是因为人是可见的,所以它公开了它的所有属性。

我在正确的轨道上吗?这是隐藏或公开属性/方法的正确方法吗?

还有一个问题,为什么console.log(jack.getAge());会引发错误?当引用我“存储”在变量中的函数时,是否应该将()放在该函数的末尾,它同时可以双向工作,所以我不知道该怎么用?

谢谢!

最佳答案

我猜这是因为人是可见的,所以它公开了它的所有属性。


正确。


  我在正确的轨道上吗?这是隐藏或公开属性/方法的正确方法吗?


如果您想这样做,那么可以,这是一种相当标准的方法。截至ES2015,至少还有另一种方式,但开销可能更大。


  还有一个问题,为什么console.log(jack.getAge());引发错误?


因为jack对象没有getAge属性,所以jack.getAge会产生undefined,这不是函数。上下文中有一个getAge变量,giveAge闭包可以访问(以及agename),但是jack没有getAge属性。


  当引用我“存储”在变量中的函数时,是否应该将()放在该函数的末尾,它同时可以双向工作,所以我不知道该怎么用?


不,这不是双向的。 jack.getName获取对该函数的引用。 jack.getName()调用该函数并获取其返回值。

我应该注意,getAge函数没有意义。只能使用person函数中定义的闭包来访问它,就像agename一样。因此,任何使用getAge的东西都只会使用age来避免函数调用。



为了完整起见,我会注意到许多人并不担心JavaScript中真正的私有属性,而是选择了``按约定私有''-例如,他们使用命名约定(例如以_开头的名称)来表示“不要碰这些,它们是私人的。”当然,这并不能阻止人们使用它们,这只是表明他们不应该这样做。拥护这种情况的人通常会指出,在许多具有“真实”私有属性/字段(Java,C#)的语言中,只需很少的努力就可以通过反射来访问那些属性/字段。因此,争论就这样了,仅使用命名约定就是“作为私有”。

我不同意(也不是特别不同意),它需要用Java或C#进行大量工作才能访问私有属性而不是公共属性。我只是在指出“按惯例私有”方法很普遍,并且经常“足够好”。

09-17 04:55