Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript中的公共和特权方法:为什么这样调用它们?_Javascript_Oop_Encapsulation - Fatal编程技术网

javascript中的公共和特权方法:为什么这样调用它们?

javascript中的公共和特权方法:为什么这样调用它们?,javascript,oop,encapsulation,Javascript,Oop,Encapsulation,如果我理解正确,根据道格拉斯·克罗克福德的说法,“特权”方法与我们所知的“公共”方法类似。而“公共”方法则有些不同 我是这样理解的: “特权”方法可以访问私有变量,因为它是在定义其余私有变量时在闭包内定义的 var C = function(){ var private; this.privilegedMethod = function(){ /* blah blah */ }; } var cObj = new C(); “Public”方法是通过原型添加到对象本

如果我理解正确,根据道格拉斯·克罗克福德的说法,“特权”方法与我们所知的“公共”方法类似。而“公共”方法则有些不同

我是这样理解的:

  • “特权”方法可以访问私有变量,因为它是在定义其余私有变量时在闭包内定义的

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

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


    所以我想知道,为什么道格拉斯·克罗克福德提出了这些令人困惑的术语?为什么javascript社区采用了这些术语?或者,如果我在某些方面错了,请纠正我。

    因为JavaScript中没有像public/private/protected这样的范围修饰符,为了接近OOP世界,Douglas Crockford使用了这样的名称,而不是混淆来自Java的任何人

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

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

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


    我不知道它是否变得清晰,但这里最主要的是JavaScript是基于原型的语言,在语言中引入原型链是为了使继承成为可能。

    弗拉德,我同意你的看法:我也很困惑! 看这里(从):


    因此,答案是:公共方法私有化方法不是吗?

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


    希望这有用。

    在传统的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
    
    如您所见,
    publicMethod
    privilegedMethod
    都是公共的,因为它们都可以从外部访问,但是
    privilegedMethod
    可以访问其他数据

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

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

  • 特权方法和公共方法在对象内外都可用


  • JavaScript不是OOP语言,而是基于原型继承。这些差异值得用不同的名称来命名:)@singpolyma:imo最好的做法是忽略所有“可见性”解决方案,按原样使用JavaScript。如果您有私有属性,则相应地记录它们。使用闭包模拟可见性仅此而已。这不是一个灵丹妙药,当事情变得更复杂时(例如继承),它可能是巨大的痛苦。@singpolyma据我所知,prototype是面向对象编程的实现,而大多数其他OOP语言使用的是经典实现。此外,我认为这些差异不值得用不同的名称来命名,因为术语“public”和“private”基本上是来自封装的概念,而封装又是来自面向对象编程的概念。我的问题是“是什么让javascript如此不同,以至于你不得不在让事情变得如此混乱的同时进行这些更改?”据我所知,“特权”只是Crockford发明的一个术语,在文献中似乎没有提到过其他任何地方?我同意这个问题的作者的观点,即这只是一种“公共”方法,在任何其他OO(或类似OO的)上下文中都可以理解。Crockford的“public”方法只是一种特殊类型的公共方法,它不会访问任何共享上下文——可能是因为它的实现方式无法访问。我认为没有必要重新定义“公共”一词的含义来涵盖这一点,在我看来,这是不必要的混淆。谢谢你花时间回答,但这并没有真正回答我的问题。您只是在重复Crockford给出的特权与公共的定义。我的问题是,他们为什么这样命名。为什么不保留“public”的概念——而不是将其重命名为“privileged”——并为Crockford所称的“public”发明一个新术语呢?好吧,我最好的猜测是不要把OOP世界中的人们与已经预定义的术语混淆,如public和private:)JavaScript真的是
    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
    
    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