Ale*_*lex 1508 javascript keyword ecmascript-5
注意:从ECMAScript版本3或5的角度提出了这个问题.在ECMAScript 6发布中引入新功能后,答案可能会过时.
var
JavaScript中关键字的功能到底是什么,有什么区别
var someNumber = 2;
var someFunction = function() { doSomething; }
var someObject = { }
var someObject.someProperty = 5;
Run Code Online (Sandbox Code Playgroud)
和
someNumber = 2;
someFunction = function() { doSomething; }
someObject = { }
someObject.someProperty = 5;
Run Code Online (Sandbox Code Playgroud)
?
你什么时候使用其中任何一个,为什么/它做什么?
Gre*_*reg 1332
如果你在全球范围内,则没有太大区别.阅读Kangax的答案进行解释
如果你在函数中,那么var
将创建一个局部变量,"no var"将查找作用域链,直到它找到变量或命中全局作用域(此时它将创建它):
// These are both globals
var foo = 1;
bar = 2;
function()
{
var foo = 1; // Local
bar = 2; // Global
// Execute an anonymous function
(function()
{
var wibble = 1; // Local
foo = 2; // Inherits from scope above (creating a closure)
moo = 3; // Global
}())
}
Run Code Online (Sandbox Code Playgroud)
如果你没有做任务,那么你需要使用var
:
var x; // Declare x
Run Code Online (Sandbox Code Playgroud)
kan*_*gax 733
有区别.
var x = 1
声明 x
当前作用域中的变量(也称为执行上下文).如果声明出现在函数中 - 声明了局部变量; 如果它在全局范围内 - 声明了一个全局变量.
x = 1
另一方面,仅仅是财产分配.它首先尝试解决x
范围链.如果它在该范围链中的任何位置找到它,它将执行赋值; 如果它没有找到x
,那么它x
才会在全局对象(它是作用域链中的顶级对象)上创建属性.
现在,请注意它没有声明全局变量,它会创建一个全局属性.
两者之间的区别是微妙的,可能会令人困惑,除非您了解变量声明也创建属性(仅在变量对象上),并且Javascript中的每个属性(即,ECMAScript)都有某些描述其属性的标志 - ReadOnly,DontEnum和DontDelete.
由于变量声明使用DontDelete标志创建属性,因此var x = 1
和x = 1
(在全局范围内执行时)之间的区别在于前者 - 变量声明 - 创建DontDelete'able属性,后者不创建.因此,可以从全局对象中删除通过此隐式赋值创建的属性,并且不能删除前一个 - 通过变量声明创建的属性.
但这当然只是理论,实际上由于实现中的各种错误(例如来自IE的错误),两者之间存在更多差异.
希望这一切都有道理:)
[更新2010/12/16]
在ES5(ECMAScript 5;最近标准化,第5版语言)中,有一种所谓的"严格模式" - 一种选择加入语言模式,它稍微改变了未声明的作业的行为.在严格模式下,对未声明标识符的赋值是ReferenceError.其基本原理是捕获意外分配,防止产生不希望的全局属性.一些较新的浏览器已经开始支持严格模式.例如,请参阅我的compat表.
Jon*_*ski 136
说它是" 本地和全球 " 之间的区别并不完全准确.
将它视为" 本地和最近 " 之间的区别可能更好.最近的肯定是全球性的,但情况并非总是如此.
/* global scope */
var local = true;
var global = true;
function outer() {
/* local scope */
var local = true;
var global = false;
/* nearest scope = outer */
local = !global;
function inner() {
/* nearest scope = outer */
local = false;
global = false;
/* nearest scope = undefined */
/* defaults to defining a global */
public = global;
}
}
Run Code Online (Sandbox Code Playgroud)
ken*_*ura 81
当Javascript在浏览器中执行时,所有代码都被with语句包围,如下所示:
with (window) {
//Your code
}
Run Code Online (Sandbox Code Playgroud)
有关更多信息with
- MDN
由于在当前作用域中var
声明了一个变量,因此在声明内部窗口和根本不声明它之间没有区别.var
当你不直接进入窗口时,例如在函数内部或块内部,就会产生差异.
使用var
可以隐藏具有相同名称的外部变量.通过这种方式,您可以模拟"私有"变量,但这是另一个主题.
经验法则是始终使用var
,否则您将面临引入细微错误的风险.
编辑:在收到批评后,我想强调以下内容:
var
声明当前范围中的变量window
var
隐式声明var
var
与省略它相同.var
是不一样的东西作为声明的变量,而不var
var
明确声明,因为这是一个好习惯Ste*_*son 42
您应该始终使用var
关键字来声明变量.为什么?良好的编码实践本身就足够了,但是在没有var
关键字的情况下声明变量意味着它在全局范围内声明(像这样的变量称为"隐含"全局).Douglas Crockford 建议不要使用隐含的全局变量,并根据Apple JavaScript编码指南:
在没有
var
关键字的情况下创建的任何变量都是在全局范围内创建的,并且在函数返回时不会被垃圾收集(因为它不会超出范围),从而导致内存泄漏的机会.
因此,简而言之,始终使用var
关键字声明变量.
Chr*_*s S 30
这里有一个很好的例子,说明如何通过以下方式来解决局部变量var
:
<script>
one();
function one()
{
for (i = 0;i < 10;i++)
{
two();
alert(i);
}
}
function two()
{
i = 1;
}
</script>
Run Code Online (Sandbox Code Playgroud)
(i
在循环的每次迭代中重置,因为它不是在for
循环中本地声明但是全局声明)最终导致无限循环
Bil*_*lly 13
我想说var
在大多数情况下使用它会更好.
局部变量总是比全局范围内的变量快.
如果不使用var
声明变量,则变量将在全局范围内.
有关详细信息,您可以在Google中搜索"范围链JavaScript".
Gib*_*olt 10
var
!var
是ES6之前声明变量的方法.我们现在在将来,你应该这样编码.
const
和let
const
应该用于95%的病例.它使得变量引用无法更改,因此数组,对象和DOM节点属性可以更改并且应该可能更改const
.
let
应该用于任何期望被重新分配的变量.这包括在for循环中.如果您varName =
在初始化之后编写,请使用let
.
两者都具有块级别范围,正如大多数其他语言所预期的那样.
没有var
- 全局变量.
强烈建议总是使用var
语句,因为在本地环境中的init全局变量 - 是邪恶的.但是,如果你需要这个肮脏的技巧,你应该在页面的开头写评论:
/* global: varname1, varname2... */
Run Code Online (Sandbox Code Playgroud)
小智 9
另一个区别,例如
var a = a || [] ; // works
Run Code Online (Sandbox Code Playgroud)
而
a = a || [] ; // a is undefined error.
Run Code Online (Sandbox Code Playgroud)
这是我为您编写的示例代码来理解这个概念:
var foo = 5;
bar = 2;
fooba = 3;
// Execute an anonymous function
(function() {
bar = 100; //overwrites global scope bar
var foo = 4; //a new foo variable is created in this' function's scope
var fooba = 900; //same as above
document.write(foo); //prints 4
document.write(bar); //prints 100
document.write(fooba); //prints 900
})();
document.write('<br/>');
document.write('<br/>');
document.write(foo); //prints 5
document.write(bar); //prints 100
document.write(fooba); //prints 3
Run Code Online (Sandbox Code Playgroud)
@Chris S 给出了一个很好的例子,展示了var
和 no之间的实际区别(和危险)var
。这是另一个,我发现这个特别危险,因为差异仅在异步环境中可见,因此它很容易在测试期间溜走。
正如您所期望的,以下代码片段输出["text"]
:
function var_fun() {
let array = []
array.push('text')
return array
}
console.log(var_fun())
Run Code Online (Sandbox Code Playgroud)
以下代码段也是如此(注意let
之前的缺失array
):
function var_fun() {
array = []
array.push('text')
return array
}
console.log(var_fun())
Run Code Online (Sandbox Code Playgroud)
异步执行数据操作仍然会产生与单个执行器相同的结果:
function var_fun() {
array = [];
return new Promise(resolve => resolve()).then(() => {
array.push('text')
return array
})
}
var_fun().then(result => {console.log(result)})
Run Code Online (Sandbox Code Playgroud)
但是对于多个行为不同:
function var_fun() {
array = [];
return new Promise(resolve => resolve()).then(() => {
array.push('text')
return array
})
}
[1,2,3].forEach(i => {
var_fun().then(result => {console.log(result)})
})
Run Code Online (Sandbox Code Playgroud)
然而使用 let :
function var_fun() {
let array = [];
return new Promise(resolve => resolve()).then(() => {
array.push('text')
return array
})
}
[1,2,3].forEach(i => {
var_fun().then(result => {console.log(result)})
})
Run Code Online (Sandbox Code Playgroud)
作为试图学习这一点的人,这就是我的看法。上面的例子对于初学者来说可能有点过于复杂。
如果您运行此代码:
var local = true;
var global = true;
function test(){
var local = false;
var global = false;
console.log(local)
console.log(global)
}
test();
console.log(local);
console.log(global);
Run Code Online (Sandbox Code Playgroud)
输出将读取为:false、false、true、true
因为它将函数中的变量与其外部的变量分开,因此称为局部变量,这是因为我们在赋值中使用了 var。如果你去掉函数中的 var,它现在是这样的:
var local = true;
var global = true;
function test(){
local = false;
global = false;
console.log(local)
console.log(global)
}
test();
console.log(local);
console.log(global);
Run Code Online (Sandbox Code Playgroud)
输出为假,假,假,假
这是因为它不是在局部作用域或函数中创建新变量,而是简单地使用全局变量并将它们重新分配为 false。
我看到人们在声明带有或不带有var以及函数内部或外部的变量时感到困惑。这是一个深入的示例,将引导您完成这些步骤:
a = 1;// Defined outside the function without var
var b = 1;// Defined outside the function with var
alert("Starting outside of all functions... \n \n a, b defined but c, d not defined yet: \n a:" + a + "\n b:" + b + "\n \n (If I try to show the value of the undefined c or d, console.log would throw 'Uncaught ReferenceError: c is not defined' error and script would stop running!)");
function testVar1(){
c = 1;// Defined inside the function without var
var d = 1;// Defined inside the function with var
alert("Now inside the 1. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
a = a + 5;
b = b + 5;
c = c + 5;
d = d + 5;
alert("After added values inside the 1. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
};
testVar1();
alert("Run the 1. function again...");
testVar1();
function testVar2(){
var d = 1;// Defined inside the function with var
alert("Now inside the 2. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
a = a + 5;
b = b + 5;
c = c + 5;
d = d + 5;
alert("After added values inside the 2. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
};
testVar2();
alert("Now outside of all functions... \n \n Final Values: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n You will not be able to see d here because then the value is requested, console.log would throw error 'Uncaught ReferenceError: d is not defined' and script would stop. \n ");
alert("**************\n Conclusion \n ************** \n \n 1. No matter declared with or without var (like a, b) if they get their value outside the function, they will preserve their value and also any other values that are added inside various functions through the script are preserved.\n 2. If the variable is declared without var inside a function (like c), it will act like the previous rule, it will preserve its value across all functions from now on. Either it got its first value in function testVar1() it still preserves the value and get additional value in function testVar2() \n 3. If the variable is declared with var inside a function only (like d in testVar1 or testVar2) it will will be undefined whenever the function ends. So it will be temporary variable in a function.");
alert("Now check console.log for the error when value d is requested next:");
alert(d);
Run Code Online (Sandbox Code Playgroud)
结论
- 无论是否使用 var 声明(如 a、b),如果它们在函数之外获取它们的值,它们都会保留它们的值,并且通过脚本在各种函数中添加的任何其他值也将被保留。
- 如果在函数内声明变量时没有 var(如 c),它将像之前的规则一样工作,从现在开始,它将在所有函数中保留其值。它要么在函数 testVar1() 中获得它的第一个值,它仍然保留该值并在函数 testVar2() 中获得附加值
- 如果变量仅在函数内部使用 var 声明(如 testVar1 或 testVar2 中的 d ),则无论何时函数结束,它都将是未定义的。所以它将是函数中的临时变量。
归档时间: |
|
查看次数: |
295630 次 |
最近记录: |