Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
747 views
in Technique[技术] by (71.8m points)

javascript - Javascript中的变量声明语法(包括全局变量)之间的区别?(Difference between variable declaration syntaxes in Javascript (including global variables)?)

Is there any difference between declaring a variable:(声明变量之间有什么区别:)

var a=0; //1 ...this way:(...这条路:) a=0; //2 ...or:(...要么:) window.a=0; //3 in global scope?(在全球范围内?)   ask by Dan translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Yes, there are a couple of differences, though in practical terms they're not usually big ones.(是的,有一些差异,尽管实际上它们通常并不大。)

There's a fourth way, and as of ES2015 (ES6) there's two more.(还有第四种方法,从ES2015(ES6)开始,还有另外两种方法。) I've added the fourth way at the end, but inserted the ES2015 ways after #1 (you'll see why), so we have:(我在末尾添加了第四种方式,但是在#1之后插入了ES2015方式(您会看到原因),因此我们有:) var a = 0; // 1 let a = 0; // 1.1 (new with ES2015) const a = 0; // 1.2 (new with ES2015) a = 0; // 2 window.a = 0; // 3 this.a = 0; // 4 Those statements explained(这些陈述解释了) #1 var a = 0;(#1 var a = 0;) This creates a global variable which is also a property of the global object , which we access as window on browsers (or via this a global scope, in non-strict code).(这将创建一个全局变量,该变量也是全局对象的属性,我们可以在浏览器中以window访问该变量(或通过this window在非严格代码中通过全局范围访问)。) Unlike some other properties, the property cannot be removed via delete .(与某些其他属性不同,该属性无法通过delete 。) In specification terms, it creates an identifier binding on the object Environment Record for the global environment .(用规范的术语来说,它在全局环境对象环境记录上创建一个标识符绑定 。) That makes it a property of the global object because the global object is where identifier bindings for the global environment's object Environment Record are held.(这使它成为全局对象的属性,因为全局对象是全局环境对象环境记录的标识符绑定所在的位置。) This is why the property is non-deletable: It's not just a simple property, it's an identifier binding.(这就是为什么该属性不可删除的原因:它不仅是一个简单的属性,还是一个标识符绑定。) The binding (variable) is defined before the first line of code runs (see "When var happens" below).(绑定(变量)是在代码的第一行运行之前定义的(请参见下面的“何时发生var ”)。) Note that on IE8 and earlier, the property created on window is not enumerable (doesn't show up in for..in statements).(请注意,在IE8和更早版本上,在window上创建的属性不可枚举 (不会显示在for..in语句中)。) In IE9, Chrome, Firefox, and Opera, it's enumerable.(在IE9,Chrome,Firefox和Opera中,它是枚举的。) #1.1 let a = 0;(#1.1 let a = 0;) This creates a global variable which is not a property of the global object.(这将创建一个全局变量,该变量不是全局对象的属性。) This is a new thing as of ES2015.(从ES2015开始这是新事物。) In specification terms, it creates an identifier binding on the declarative Environment Record for the global environment rather than the object Environment Record.(用规范术语来说,它在声明性环境记录上为全局环境而不是在对象环境记录上创建标识符绑定。) The global environment is unique in having a split Environment Record, one for all the old stuff that goes on the global object (the object Environment Record) and another for all the new stuff ( let , const , and the functions created by class ) that don't go on the global object.(全局环境的独特之处在于它具有分开的环境记录,一个环境记录适用于全局对象上所有的旧内容( 对象环境记录),另一个适用于所有新的内容( letconst和由class创建的函数),不要继续使用全局对象。) The binding is created before any step-by-step code in its enclosing block is executed (in this case, before any global code runs), but it's not accessible in any way until the step-by-step execution reaches the let statement.(绑定是执行其封闭块中的任何分步代码之前创建的 (在这种情况下,在任何全局代码运行之前),但是在分步执行到达let语句之前,它无法以任何方式访问 。) Once execution reaches the let statement, the variable is accessible.(一旦执行到达let语句,就可以访问该变量。) (See "When let and const happen" below.)((请参见下面的“当letconst发生时”。)) #1.2 const a = 0;(#1.2 const a = 0;) Creates a global constant, which is not a property of the global object.(创建一个全局常量,它不是全局对象的属性。) const is exactly like let except that you must provide an initializer (the = value part), and you cannot change the value of the constant once it's created.(const就像let一样,除了必须提供一个初始化程序( = value部分),并且一旦创建常量就无法更改其值。) Under the covers, it's exactly like let but with a flag on the identifier binding saying its value cannot be changed.(在幕后,它就像let一样,但是在标识符绑定上带有一个标志,表明其值不能更改。) Using const does three things for you:(使用const可以为您做三件事:) Makes it a parse-time error if you try to assign to the constant.(如果您尝试分配给常量,则使其成为解析时错误。) Documents its unchanging nature for other programmers.(记录其对于其他程序员的不变性。) Lets the JavaScript engine optimize on the basis that it won't change.(让JavaScript引擎在不改变的基础上进行优化。) #2 a = 0;(#2 a = 0;) This creates a property on the global object implicitly .(这将在全局对象上隐式创建一个属性。) As it's a normal property, you can delete it.(由于它是普通属性,因此可以将其删除。) I'd recommend not doing this, it can be unclear to anyone reading your code later.(我建议您要这样做,以后再阅读您的代码的人可能会不清楚。) If you use ES5's strict mode, doing this (assigning to a non-existent variable) is an error.(如果您使用ES5的严格模式,则执行此操作(将其分配给不存在的变量)是错误的。) It's one of several reasons to use strict mode.(使用严格模式是多种原因之一。) And interestingly, again on IE8 and earlier, the property created not enumerable (doesn't show up in for..in statements).(有趣的是,再次在IE8和更早版本上,创建的属性不可枚举 (不会出现在for..in语句中)。) That's odd, particularly given #3 below.(这很奇怪,特别是在下面的#3中。) #3 window.a = 0;(#3 window.a = 0;) This creates a property on the global object explicitly, using the window global that refers to the global object (on browsers; some non-browser environments have an equivalent global variable, such as global on NodeJS).(这创建全局对象上的属性明确,使用window ,指的全局对象全局(在浏览器上;一些非浏览器环境具有等同的全局变量,诸如global上的NodeJS)。) As it's a normal property, you can delete it.(由于它是普通属性,因此可以将其删除。) This property is enumerable, on IE8 and earlier, and on every other browser I've tried.(在IE8和更早版本以及我尝试过的所有其他浏览器上,此属性都是可枚举的。) #4 this.a = 0;(#4 this.a = 0;) Exactly like #3, except we're referencing the global object through this instead of the global window .(就像#3一样,除了我们通过this而不是global window引用全局对象。) This won't work in strict mode, though, because in strict mode global code, this doesn't have a reference to the global object (it has the value undefined instead).(这在严格模式是行不通的,但是,因为在严格模式全局代码, this不具有全局对象(它的价值的参考undefined代替)。) Deleting properties(删除属性) What do I mean by "deleting" or "removing" a ?(“删除”或“删除” a是什么意思?) Exactly that: Removing the property (entirely) via the delete keyword:(正是这样:通过delete关键字完全删除该属性:) window.a = 0; display("'a' in window? " + ('a' in window)); // displays "true" delete window.a; display("'a' in window? " + ('a' in window)); // displays "false" delete completely removes a property from an object.(delete完全删除对象的属性。) You can't do that with properties added to window indirectly via var , the delete is either silently ignored or throws an exception (depending on the JavaScript implementation and whether you're in strict mode).(通过var间接将属性添加到window ,您将无法做到这一点, delete会被静默忽略或引发异常(取决于JavaScript实现以及您是否处于严格模式)。) Warning : IE8 again (and presumably earlier, and IE9-IE11 in the broken "compatibility" mode): It won't let you delete properties of the window object, even when you should be allowed to.(警告 :IE8再次出现(可能是更早的版本,而IE9-IE11处于损坏的“兼容性”模式):即使允许,也不允许您删除window对象的属性。) Worse, it throws an exception when you try ( try this experiment in IE8 and in other browsers).(更糟糕的是,尝试时会引发异常 (在IE8和其他浏览器中尝试此实验 )。) So when deleting from the window object, you have to be defensive:(因此,从window对象中删除时,您必须采取防御措施:) try { delete window.prop; } catch (e) { window.prop = undefined; } That tries to delete the property, and if an exception is thrown it does the next best thing and sets the property to undefined .(尝试删除该属性,如果抛出异常,它将做第二件事,并将属性设置为undefined 。) This only applies to the window object, and only (as far as I know) to IE8 and earlier (or IE9-IE11 in the broken "compatibility" mode).(这适用于window对象,并且仅(据我所知)适用于IE8和更早的版本(或处于“兼容”模式的IE9-IE11)。) Other browsers are fine with deleting window properties, subject to the rules above.(其他浏览器可以删除window属性,但要遵守上述规则。) <h

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...