Javascript-在对象中存储函数-不好的做法?[关闭]


73

将函数存储在对象中而不是仅仅定义它们(并因此在全局范围内)是否被认为是不好的编码习惯?

考虑:

1。

Foo = {
    bar: function() {
        alert("baz");
    }   
}

Foo.bar();

2。

function bar() {
    alert("baz");
}

bar();

当然,第二个示例的代码可能会少一些,但是当您开始获得许多功能时-它将变得混乱。我发现,例如,使用它Game.update()而不是使用updateGame(); 或类似。深入了解Game.notify.admin(id)等等后,它甚至可以提供更漂亮的代码。

通过将函数存储在对象中是否有任何弊端?


2
否。如果有的话,在全球拥有数百万用户的框架将无法做到这一点。
2012年

2
否。正如您已经指出的那样,这是避免全球污染的标准命名空间。为什么会不好?

Answers:


75

第一种方法是首选。这样,您可以显式定义函数的作用域,而不是污染全局作用域。使用第一种方法没有任何缺点。只有优点:-)

结论:始终使用第一种方法定义函数。第二个就像90年代的javascript,让我们将其放回过去,并使用适当的作用域。


3
主动嵌套有一些弊端。例如,将函数放在“因为更好”的对象上是愚蠢的。(将函数放在全局作用域中也是愚蠢的,但是假设模块作用域不是在处理什么)。同样,将对象和功能嵌套超过4层深层也很愚蠢。理想情况下,您要为对象/方法链添加一层或两层foo.bar.baz()
Raynos 2012年

2
这真的是关于范围的吗?还是只是为了减少全局变量的数量以减少重复变量名的机会。“全球污染”还会其他不利影响吗?
RobG 2012年

@RobG的可维护性。有很多充分的理由试图将全局变量的数量减少到零。
雷诺斯(Raynos)2012年

1
@RobG不是关于冲突,而是关于确保代码不会通过破坏全局状态意外破坏不变式。在大型项目中,您只是不想要全局状态,而是依赖于不破坏全局状态的约定。
雷诺斯2012年

2
@PhilOlson-仅将值存储在对象中就没有使用变量的好处。如果需要模块化(并且模块化是一个好主意),则存在模块模式,该模式仅公开那些需要公开的属性,并将其余属性隐藏在单独的执行上下文中。
RobG 2014年

4

在这种情况下,请选择第一个。但是,如果Foo对象变得非常复杂,则可能需要使用另一种方法,这将使您有机会使用构造函数。而且,就功能范围而言,第一种方法有时也不是最佳方法:

function Foo(appName){
    this.name = appName;      
}

Foo.prototype.Bar = function(){
   alert(this.name)
}

var a = new Foo("baz");
a.Bar();

检测到反模式。请使用原型,谢谢。
雷诺斯2012年

您说得对@Raynos,在函数内部声明函数的问题是,每次您启动类时都会重新创建它。
Karl Mendes 2012年

4

命名空间对象没有魔术,如果使用大量全局变量,也就不会有任何问题。使用“命名空间”对象的主要原因是为了减少重复的全局变量名称的可能性。第二个原因是为了方便起见将相似的功能分组在一起,例如:

// Object example (suggested best practice):
// DOM functions are under myLib.dom
myLib.dom.someDOMFunction0;
myLib.dom.someDOMFunction1;

// Utility functions are under myLib.util
myLib.util.someUtilityFunction0;
myLib.util.someUtilityFunction1;

请注意,以上代码实际上具有与类似的全局变量相同的重复机会:

// Global variable example:
myLib_dom_someDOMFunction0;
myLib_dom_someDOMFunction1;

myLib_util_someUtilityFunction0;
myLib_util_someUtilityFunction1;

当然,前者通常是首选,因为它看起来更易于使用。我并不主张您采用第二种方法(我使用第一种方法),只是指出尽管创建许多全局变量存在问题,但所谓的“全局名称空间污染”却被高估了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.