Javascript OOP 公共(public)和私有(private)变量范围

标签 javascript oop scope

我有一个关于 Javascript 对象中的公共(public)变量和私有(private)变量的问题。这是我一直在研究的简单代码,用于了解变量范围以及私有(private)和公共(public)属性。

var fred = new Object01("Fred");
var global = "Spoon!";

function Object01(oName) {
    var myName = oName;
    this.myName = "I'm not telling!";
    var sub = new subObject("underWorld");
    this.sub = new subObject("Sewer!");

    Object01.prototype.revealName = function() {
        return "OK, OK, my name is: " + myName + ", oh and we say " + global;
    }

    Object01.prototype.revealSecretName = function() {
        console.log ("Private: ");
        sub.revealName();
        console.log("Public: ");
        this.sub.revealName();
    }
}

function subObject(oName) {
    var myName = oName;
    this.myName = "My Secret SubName!";

    subObject.prototype.revealName  = function() {
        console.info("My Property Name is: " + this.myName);
        console.info("OK, my real name is: " + myName + ", yeah and we also say: " + global);
    }
}

到目前为止我观察到的有趣的事情是在我的对象中,一个普通的 var 被视为私有(private)的(显然,因为它们在一个函数 block 中),而一个 this 版本是公共(public)的。但我注意到与 this.xxx 同名的变量似乎被认为是不同的变量。因此,在上面的示例中,与我拉取 var myName 的函数相比,我的对象 fred 将为 this.myName 报告一些不同的内容。

但对于我创建的子对象,这种相同的行为并不相同。在 var subthis.sub 的情况下,上面两个都使用 new subObject 调用来创建两个子对象。但似乎 this.subvar sub 都返回了 Sewer! 版本。

Som 我有点困惑,为什么如果我对 this.myNamevar myName 使用字符串,我会得到两个不同的结果,但我尝试做同样的事情与另一个对象不会产生类似的结果?我猜可能是我用错了它们,或者没有理解 thisvar 版本之间的区别。

最佳答案

这里最大的问题实际上不是 this 之间的区别基于对象属性和 var -声明的变量。

你的问题是你试图让原型(prototype)充当一个包装器,它会给你 protected 类属性,这些属性可供子类使用,更不用说你的主类的实例了。

prototype不能在 "private" 上工作一个类的成员(即在构造函数范围内定义的变量,而不是添加到您要返回的构造对象的属性)。

function Person (personName) {
    var scoped_name = personName;

    this.name = "Imposter " + scoped_name;
}


Person.prototype.greet = function () { console.log("Hi, I'm " + this.name + "!"); };


var bob = new Person("Bob");
bob.greet(); // "Hi, I'm Imposter Bob!"

prototype string 要么提供对对象的可公开访问属性进行操作的方法(例如,如果您想更改 this.name 的值,但您将永远丢失隐藏的 ​​scoped_name 引用)...

...或者如果您希望所有相同类型的对象都可以访问相同的值。

function Student (name, id) {
    function showIDCard () { return id; }
    function greet () { console.log("I'm " + name + ", and I attend " + this.school); }

    this.showID = showIDCard;
    this.greet = greet;
}


Student.prototype.school = "The JS Academy of Hard-Knocks";
Student.prototype.comment_on_school = function (feeling) {
    console.log("I " + feeling + " " + this.school);
}

var bob = new Student("Bob", 1);
var doug = new Student("Doug", 2);
var mary = new Student("Mary", 1);


mary.school = "The JS School of Closure";



bob.greet(); // I'm Bob and I attend The JS School of Hard-Knocks
mary.greet(); // I'm Mary and I attend the JS School of Closure
mary.comment_on_school("love"); // I love The JS School of Closure

prototypeschool 定义了默认值, 对于 Student没有给自己的人。 prototype还提供了可以在对象之间共享的功能,因为这些功能使用 this访问对象的实际属性。

函数的任何内部变量ONLY 可以被INSIDE定义的属性或方法访问函数。

所以在这种情况下,prototype方法可以NEVER 访问 id , 除了通过 this.showID ,因为 this.showID是对 showIDCard 的引用功能,这是为每个学生创建的,每个学生都有自己独特的id ,并且他们自己的该函数副本引用了他们自己的该参数的唯一副本。

我对 JS 应用大规模“类”方法的建议是采用一种有利于对象组合的风格。 如果你要子类化,让每个子类成为一个模块,有它自己的面向公众的接口(interface),和它自己的私有(private)范围的变量,然后让那个模块成为你试图制作的任何东西的属性,而不是而不是试图让继承链发挥作用。

就是说,如果您期望做一些事情,例如从基类继承,然后将其扩展 8 或 10 代,那么 JS 中的工作太多了。 它只会以泪水结束,并提示 JS 不是“OOP”(以您希望的风格)。

关于Javascript OOP 公共(public)和私有(private)变量范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12358440/

相关文章:

javascript - 仅在生产环境中使用 Gatsby 和 Material UI 时,首次访问页面时 HTML 消失

python - 将 self 变量作为参数传递给 mixin 父方法的正确方法

Java 通知设计模式

c - 在此范围内未声明错误

c++ - 自动对象销毁

JavaScript:如何在不向历史记录添加条目的情况下更改地址栏中的哈希值?

javascript - 在 Node JS 服务器端加载预编译的 Handlebar 模板

php - 在 Laravel 中使用范围解析运算符

javascript - 访问 mqtt 回调范围之外的类属性

javascript - MUI 自动完成自定义选项,不显示所选选项