javascript中的公共和特权方法:为什么这样称呼?

时间:2012-09-15 17:15:09

标签: javascript oop encapsulation

如果我理解正确,根据Douglas Crockford http://javascript.crockford.com/private.html,“特权”方法与我们所谓的“公共”方法类似。和“公共”方法有点不同。

以下是我的理解:

  1. “Privileged”方法可以访问私有变量,因为它是在定义其余私有变量时在闭包内定义的。

    var C = function(){
      var private;
      this.privilegedMethod = function(){
           /* blah blah */
      };
    }
    var cObj = new C();
    
  2. “公共”方法是通过原型添加到对象本身之外的对象的方法。

    var C = function(){
       /* blah blah */
    }
    C.prototype.publicMethod = function(){
        /* blah blah */
    };
    var cObj = new C();
    
  3. 我发现这些“特权”和“公共”的定义非常令人困惑。我认为“特权”方法只不过是实际上是一种公共方法,正如我们从面向对象编程中所知道的那样。我认为“公共”方法应该被命名为其他方法。如果您考虑它,它是一种奇怪的函数类型,它是对象的成员但它不能访问任何其他私有变量,这意味着它不会对封装有所贡献。它几乎就像是对象的独立辅助方法。

    所以我想知道道格拉斯·克罗克福德为什么会提出这些令人困惑的条款?为什么javascript社区采用这些术语?或者,如果我对某事有误,请纠正我。

5 个答案:

答案 0 :(得分:10)

由于JavaScript中没有像public / private / protected这样的范围修饰符,为了接近OOP世界,Douglas Crockford正在使用这样的名字,不要混淆任何来自的人,比如说Java

特权方法可以看到函数内部定义的变量(这里重要的一点 - 在JavaScript中,唯一的范围是函数范围。没有块范围)所以它们是“特权”。是的,它们可以从一个对象实例调用,但重要的是,它们看到所有的东西,用var声明(真正的私有东西)

另一方面,附加到对象原型的公共方法有一个更重要的事情 - 它们被评估一次并且可以看到给定对象的所有实例。

如果在原型方法中使用this关键字,它将指向Object的当前实例,但您将只能看到this中定义的内容。

我不知道它是否清楚,但主要的是JavaScript是基于原型的语言,并且原型链是在语言中引入的,以便使继承成为可能。

答案 1 :(得分:3)

弗拉德,我同意你的观点:我也很困惑! 看这里(来自http://javascript.crockford.com/private.html):

function Container(param) {
    // methode privee
    function dec() {
    console.log('private method is looking for private member secret : ' + secret);
        if (secret > 0) {
            secret -= 1;
            return true;
        } else {
            return false;
        }
    }
    // membres privées
    var secret = 3;
    var that = this;
    // méthode privilégiée
    this.service = function () {
    console.log('priviligied method is looking for private member secret : ' + secret);
        return dec() ? that.member : null;
    };
    // membres publiques
    this.member = param;

}
var myContainer = new Container('abc');

Container.prototype.stamp = function (string) {
    console.log('public method is looking for private member secret : ' + this.secret);
    return this.member + string;
}

console.log(myContainer.stamp('def'));
//for (i=0;i<4;i++)
console.log(myContainer.service());

priviliged vs public

这个jsfiddle样本将显示:

public method is looking for private member secret : undefined
abcdef
priviligied method is looking for private member secret : 3
private method is looking for private member secret : 3
abc

所以,答案是:公共方法&lt; =&gt;特权方法不是吗?

答案 2 :(得分:1)

在传统的OOP语言中,类的所有成员都可以访问类的所有其他成员。

在Javascript中不是这种情况。公共方法可以访问私有数据,该类的其他成员(即构造函数)都不知道。同样,该类的其他成员可能拥有该方法无法看到的数据。

请考虑以下事项:

function TheirTrait() {
  var privateData = "foo";
  this.privilegedMethod = function() {
    return privateData;
  }
}

function MyClass() {
  var privateData = undefined;
  this.publicMethod = function() {
    return privateData;
  }
  TheirTrait.apply(this, arguments);
}

var myObject = new MyClass();
myObject.privilegedMethod() // returns "foo"
myObject.publicMethod() // returns undefined

正如您所看到的,publicMethodprivilegedMethod都是 public ,因为它们都可以在外部访问,但privilegedMethod可以访问其他内容数据

答案 3 :(得分:0)

两种方法之间的主要区别在于特权方法可以使用,这意味着子类可以直接访问它们,但是公共方法不适用于子类,当然还有经典的继承方法。

希望这很有用。

答案 4 :(得分:0)

  1. 使用“ this”关键字创建特权方法,并使用构造函数的prototype属性创建公共方法。

  2. 特权方法可以访问私有变量和方法。公共方法可以调用特权方法,但不能调用私有方法。

  3. 对象内部和外部都可以使用特权方法和公共方法。