JavaScript 中的封装
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3597087/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Encapsulation in JavaScript
提问by nickb
A long time ago, I saw someone encapsulate their entire JavaScript block with code something like the code below:
很久以前,我看到有人用类似下面的代码封装了他们的整个 JavaScript 块:
(function() {
// ...
})(this);
Questions:
问题:
- Is the code above correct?
- What benefit is there to encapsulating the entire JavaScript block like denoted above?
- 上面的代码正确吗?
- 像上面提到的那样封装整个 JavaScript 块有什么好处?
回答by Daniel Vassallo
Yes, that's correct. It's called a self invoking anonymous function expression.
对,那是正确的。它被称为自调用匿名函数表达式。
JavaScript variables have either function scope, or global scope. There is no block scope. Enclosing your code in a self invoking function like the one in your example creates a temporary local scope for single-use, immediately-run code, without polluting the global namespace.
JavaScript 变量具有函数作用域或全局作用域。没有块作用域。将您的代码包含在一个自调用函数中,就像您的示例中的那样,为一次性使用、立即运行的代码创建一个临时本地范围,而不会污染全局命名空间。
Consider the following:
考虑以下:
<html>
<body>
...
<script>
(function() {
var x = '';
function myFunction () {
alert('Hello: ' + x);
}
x = 'Bob';
myFunction();
alert(typeof x); // string
alert(typeof myFunction); // function
})();
alert(typeof x); // undefined
alert(typeof myFunction); // undefined
</script>
<script src="other-javascript.js"></script>
</body>
</html>
Whatever you declare in that self invoking function is held in a separate scope. The variable xand the function myFunction()cannot be accessed from anywhere else. The code in other-javascript.jswon't see them, for example, and it would be free to declare another function myFunction()without conflicts.
您在该自调用函数中声明的任何内容都保存在单独的作用域中。不能从其他任何地方访问变量x和函数myFunction()。other-javascript.js例如,中的代码不会看到它们,并且可以自由地声明另一个函数myFunction()而不会发生冲突。
回答by CMS
Also addition to the @Daniel's answer, passing thisto the function is a common pattern to have a reference to the global object, for example:
此外,除了@Daniel 的回答之外,传递this给函数是引用全局对象的常见模式,例如:
(function(window){
})(this);
In browser scripting the global object has a property named windowwhich refers to the global object itself, in other environments there is no windowproperty.
在浏览器脚本中,全局对象有一个名为的属性window,它指的是全局对象本身,在其他环境中没有window属性。
Also, another thing that can be done is to specify an argument named undefined, because the undefinedproperty is not described on the ECMAScript 3rd. Edition Standard (there is no guarantee that exist or not), and in some implementations the property is mutable, for example:
此外,可以做的另一件事是指定一个名为 的参数undefined,因为ECMAScript 3rd 中undefined没有描述该属性。Edition Standard(不保证存在与否),并且在某些实现中该属性是可变的,例如:
(function(window, undefined){
})(this);
In the above example, we have two local identifiers(which are a bit faster to resolve), windowand undefined, only the first one is passed (this, which always refers to the global object in Global code(code that is outside of any function)), and the second, will contain the primitive undefinedvalue, because we are not passing any value to it.
在上面的例子中,我们有两个本地标识符(解析起来要快一些),window并且undefined,只有第一个被传递(this,它总是指全局代码中的全局对象(任何函数之外的代码)) ,第二个,将包含原始undefined值,因为我们没有向它传递任何值。
That pattern is used by some libraries like jQuery.
这种模式被一些库使用,比如jQuery。
回答by talhature
Just for the record, ECMA TC39 had proposed a private syntax. According to the proposal, in order to make a javascript class field private you need to prefix it with a hash '#'. This is to provide some sort of runtime encapsulation.
只是为了记录,ECMA TC39 提出了一种私有语法。根据提案,为了使 javascript 类字段私有,您需要在它前面加上一个哈希“#”。这是为了提供某种运行时封装。
Example:
例子:
class B {
#hidden = 0;
m() {
return this.#hidden;
}
}
Chrome supports this since Chrome v74. If this private-syntax becomes a standart we will be able to benefit from runtime encapsulation in javascript and assumingly in typescript since it's transpilation will be updated that way.
Chrome 从 Chrome v74 开始支持这一点。如果这种私有语法成为标准,我们将能够从 javascript 中的运行时封装中受益,并且假设在 typescript 中,因为它的转换将以这种方式更新。

