Javascript中的封装

Javascript中的封装,javascript,oop,encapsulation,Javascript,Oop,Encapsulation,我对Javascript非常陌生,我的SO档案将证明这一点 我刚刚阅读了一些教程,在使用Javascript应用时,遇到了一些关于面向对象和封装的东西,我并不完全理解 本教程指出,Javascript对象可以这样声明: var myCustomObject = new Object(); myCustomObject.myVariable = "some value"; myCustomObject.myOtherVariable = "deadbeef"; function CustomO

我对Javascript非常陌生,我的SO档案将证明这一点

我刚刚阅读了一些教程,在使用Javascript应用时,遇到了一些关于面向对象和封装的东西,我并不完全理解

本教程指出,Javascript对象可以这样声明:

var myCustomObject = new Object();
myCustomObject.myVariable = "some value";
myCustomObject.myOtherVariable = "deadbeef";
function CustomObject(myVariable, myOtherVariable)
{
    this.myVariable = myVariable;
    this.myOtherVariable = myOtherVariable;
}
您可以给它这样的实例变量:

var myCustomObject = new Object();
myCustomObject.myVariable = "some value";
myCustomObject.myOtherVariable = "deadbeef";
function CustomObject(myVariable, myOtherVariable)
{
    this.myVariable = myVariable;
    this.myOtherVariable = myOtherVariable;
}
最后,它声明您可以创建一个模板函数来创建新对象,如下所示:

var myCustomObject = new Object();
myCustomObject.myVariable = "some value";
myCustomObject.myOtherVariable = "deadbeef";
function CustomObject(myVariable, myOtherVariable)
{
    this.myVariable = myVariable;
    this.myOtherVariable = myOtherVariable;
}
我还知道,您可以创建并为尚未存在的变量赋值,结果是隐式声明的,如示例所示,
myCustomObject
没有
myVariable
,但现在有了

所以,我的问题是:有什么可以防止在代码的其他地方添加新变量。如果我试图了解一个对象是如何工作的,以及我可以/应该用它做什么,我可能永远看不到其他一些.js文件中可能添加的变量,因此无法完全理解该对象

另外,我怎么知道刚刚创建的某个对象不会突然在以后的代码中添加了60多个在创建时根本没有提到的变量


如果一个物体可以“随意地”添加更多的东西,你怎么能一眼就明白它能包含什么呢?

我不太相信我会引用蜘蛛侠的话,但是

权力大,责任大


JavaScript功能强大且灵活,给了程序员很多自由。它没有设计用来阻止程序员编写糟糕代码的功能。编写JavaScript时,您负责确保代码是好的,而不是语言。

简短回答:绝对没有

长答覆:

Javascript在很多方面都是一种动态语言,而不仅仅是类型系统。语言中每一个类似对象的东西基本上都是一个关联数组,可以随意添加到其中。变量(显然可以包含这些类似对象的东西)只存在于它们的函数范围内

您可以使用这一点来模拟私有成员,这可以在某种程度上缓和这种情况。我之前已经多次发布过这方面的示例,所以我只想让您参考关于这一主题的权威指南:

至于以您不希望的方式向对象添加新成员,实际上没有什么可以做的,这就是语言的方式

事后思考:


当接触javascript时,请记住它不是一种OOP语言,它是一些OOP思想与函数/原型的奇妙混合。不要被类似java的语法所愚弄,如果你发挥语言的优势,而不是模仿java,你会玩得更好

你不能,没有什么能阻止我对你的物品做任何我想做的事;)但是,您不必使用这些变量

您可以做的一件事是使用作用域,例如:

function myConstructor()
{
  var myState = {}; //Create new, empty object
  myState.text = "Hello World!";
  this.say = function() {
    alert(myState.text);
  };
}

在这个简单的示例中,您可以将内部变量存储在myState(或“var text=''”;等)中,它们不能从外部访问,因为它们不是对象的成员,它们只是函数中的私有变量。正如您所见,函数say仍然可以访问它。

Javascript对象是transformers(TM),它们可以从一种形式转换为另一种形式

在实践中,这只会使物体变得丰富,而不会造成伤害。例如,它允许一个人升级现有的“类”,而不是子类化,或者再次修饰实例,从而消除创建更多“类”的需要。以以下为例:

var Vehicle = function(){}

var factory = {
    create: function(name, props){
        var v = new Vehicle();
        v.type = name;
        for(var prop in props) {
            v[prop] = props[prop];
        }
    }
}

var bike = factory.create('Bike', {
    wheels: 2
});

var car = factory.create('Car', {
    wheels: 4,
    doors: 5,
    gear: 'automatic'
});

var plane = factory.create('Airplane', {
    wings: 2,
    engines: 4
});
想象一下,如果没有动态对象,上面的代码会发生什么,而您无法做到这一点:

// lets paint our car
car.color = 'candy red';
// bling!
car.racingStripes = true;
car.mirrorDice = true;
car.furryChairs = true;

您可以更轻松地丰富/个性化对象。

这里没有适合您的内容吗?我认为您不能阻止其他人添加成员。但是,如果你对你的对象能做什么以及它应该如何使用给出一个明确的定义,你就不必关心其他人做什么。对于你自己:不要这样做;)这里:@Felix,如果我试图理解其他人的代码,这些代码可能没有很好的文档记录,或者没有给出对象可以做什么或应该如何使用的明确定义?@mplungjan,我感谢您的输入,但是尽管这些链接在解释Javascript的面向对象和如何操作方面做得很好,它们都没有回答我的特定问题。请注意,这可能会导致一些意想不到的问题,以防以后要扩展类,因为不可能从外部访问这些内部变量;)但是如果没有非常好的文档,我可能永远也不会知道一辆车有毛茸茸的椅子(喜欢它),除非我偶然发现了一段声明它的代码。对吗?没错,这就是为什么一个人必须明智地编码;)装饰器在javascript中与在任何其他OO语言中一样有用。事实是,由于动态对象的存在,用JavaScript编写装饰程序更容易、更快。除非你让愚蠢或恶意的程序员靠近你的代码,否则你对动态对象的任何恐惧都是非理性的。当你写任何东西时,你都有责任确保代码是好的,而不是语言。(至少是IMHO)。这是真的,但有些语言采取措施试图保护程序员免受自己的伤害。