Javascript OOP公共和私有变量范围 [英] Javascript OOP public and private variable scope

查看:55
本文介绍了Javascript OOP公共和私有变量范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Javascript对象中有一个关于公共和私有变量的问题。以下是我一直在玩的简单代码,以了解可变范围以及私有和公共属性。

I've got a question regarding public and private variables in a Javascript object. Here's the simple code I've been playing with to get my head around variable scope as well as private and public properties.

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被视为私有(显然,因为它们在一个功能块中),而一个这个版本是公共的。但我注意到一个与 this.xxx 同名的变量似乎被视为一个不同的变量。因此,在上面的示例中,我的对象 fred 将报告与 this.myName 不同的东西与我的拉函数相比较我的 var myName

The funny thing I've observed so far is within my objects, a plain var is treated as private (obviously, since they are in a function block), and a this version is public. But I've noticed that the a variable with the same name with this.xxx seems to be considered a different variable. So, in the example above, my object fred will report something different for this.myName compared with my function to pull my var myName.

但是我创建的子对象的这种行为并不相同。对于 var sub vs this.sub 以上都使用 new subObject 调用假设生成两个子对象。但似乎 this.sub var sub 返回下水道! version。

But this same behavior isn't the same for a sub-object I create. In the case of var sub vs this.sub both above use a new subObject call to supposedly make two subObjects. But it seems both this.sub and var sub return the Sewer! version.

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

Som I'm a bit confused about why if I use Strings for this.myName and var myName I get two different results, but my attempt to do the same with another object doesn't produce a similar result? I guess it could be that I'm using them wrong, or not understanding the differences between a this and var version.

推荐答案

这里你最大的问题实际上并不是这个 -based对象属性和 var -declared变量。

Your biggest problem here isn't actually the difference between this-based object properties and var-declared variables.

你的问题是你正在尝试制作原型充当包装器,它将为您提供子类可用的受保护类属性,更不用说主类的实例了。

Your problem is that you're trying to make prototype act as a wrapper that will give you protected class properties which are available to sub-classes, let alone instances of your main class.

prototype 可以private上完成一个类的成员(这是在范围内定义的变量)构造函数,而不是添加到您正在返回的构造对象的属性。

prototype can not work on "private" members of a class at all (that being the variables defined within the scope of the constructor function, rather than being properties added to the constructed object you're returning).

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!"

原型字符串的要点是提供对对象的公共可访问属性进行操作的方法(例如,如果您想要更改 this.name 的值,但是您将永远失去隐藏的 scoped_name reference)...

The point of the prototype string is either to provide methods which operate on the publicly-accessible properties of your objects (like if you wanted to change the value of this.name, but you'd forever lose the hidden scoped_name reference)...

...或者如果你想让所有相同类型的对象都有权访问相同的值。

...or if you want ALL of the same kind of object to have access to the SAME value.

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

prototype 学校定义了一个默认值,学生是谁没有给自己的。
prototype 还提供了可以在对象之间共享的函数,因为函数使用这个来访问实际的对象的属性。

prototype has defined a default value for school, for Students who aren't given their own. prototype also provided functions which can be shared between objects, because the functions use this to access the actual properties of the object.

函数的任何内部变量都可以通过属性或方法访问 ONLY 定义了函数的 INSIDE

Any internal variables of the function can ONLY be accessed by properties or methods which are defined INSIDE of the function.

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

So in this case, the prototype methods can NEVER access id, except through this.showID, because this.showID is a reference to the showIDCard function, which is created for each and every single student, who has their own unique id, and their own copy of that function has a reference to their own unique copy of that argument.

我对JS应用大规模类方法的建议是采用有利于对象组合的风格。
如果您要使用子类,请将每个子类作为一个模块,使用自己的面向公众的接口,以及它自己的私有范围变量,然后使该模块成为您尝试的任何属性制作,而不是试图让继承链工作。

My suggestion for applying large-scale "class" methodology to JS is to go with a style which favours composition of objects. If you're going to sub-class, make each sub-class a module, with its own public-facing interface, and its own privately-scoped vars, and then make that module the property of whatever you were trying to make, rather than trying to get chains of inheritance working.

这就是JS中的太多工作,如果你期待做一些像继承基类,然后延伸8或10代。
它会以泪水结束,并抱怨JS不是OOP(以你喜欢的风格)。

That is way, way too much work in JS, if you're anticipating doing something like inheriting from a base-class, and then extending it 8 or 10 generations. It will just end in tears, and complaints that JS isn't "OOP" (in the style you'd like it to be).

这篇关于Javascript OOP公共和私有变量范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆