本文介绍了什么是块范围函数ECMAScript 6与ECMAScript 5比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ECMAScript 6中的块作用域功能是什么?

What is block scope function in ECMAScript 6?

任何人都可以帮助我理解块作用域功能与ECMAScript 5相比的主要区别吗?

Can anyone help me understand the main difference in the block scope function compared to ECMAScript 5?

推荐答案

新的让和 const 在ES2015(又名ES6)中,与古老的 var 相比有四个主要差异:

The new let and const in ES2015 (aka "ES6") have four major differences compared with the venerable var:


  1. 他们有块范围

  1. They have block scope

他们没有被吊起(好吧,他们有点悬挂,但是以一种有用的方式)

They aren't hoisted (well, they're sort of hoisted, but in a useful way)

重复声明是错误

当用于全局范围,他们不创建全局对象的属性(尽管创建全局变量;这是ES2015的新概念)

When used at global scope, they don't create properties of the global object (despite creating global variables; this is a new concept as of ES2015)



块范围



var 变量存在于它们声明的函数中(或全局,如果全局声明),它们并不局限于它们所处的块。所以这个代码我有效:

Block scope

var variables exist throughout the function they're declared in (or globally, if declared globally), they aren't confined to the block they're in. So this code is valid:

function foo(flag) {
    a = 10;
    if (flag) {
        var a = 20;
    }
    return a;
}
console.log(foo(false)); // 10
console.log(foo(true));  // 20

a 是否为真,都定义了c $ c>,并且它存在于 if 块之外;上面的所有三个 a 都是相同的变量。

a is defined regardless of whether flag is true and it exists outside the if block; all three as above are the same variable.

不允许(或 const ):

function foo(flag) {
    if (flag) {
        let a = 10;
    }
    return a;           // ReferenceError: a is not defined
}
console.log(foo(true));

a 仅存在于其声明的块中。(对于 for 语句,其中包含一个声明 的()实际上被认为是该块的一部分。)所以在之外如果, a 不存在。

a only exists inside the block it's declared in. (For for statements, a declaration within the () of the for is effectively considered part of the block.) So outside the if, a doesn't exist.

let 和 const 声明可以在封闭范围内进行影子声明,例如:

let and const declarations can shadow declarations in an enclosing scope, e.g.:

function foo() {
    let a = "outer";

    for (let a = 0; a < 3; ++a) {
        console.log(a);
    }
    console.log(a);
}
foo();

那个输出

0
1
2
outer

...因为 循环之外的 a isn'同样的 a 作为里面的 循环。

...because the a outside the for loop isn't the same a as the one inside the for loop.

这是有效代码:

function foo() {
    a = 5;
    var a = a * 2;
    return a;
}

看起来很奇怪但有效(它返回10),因为 var 在函数完成任何其他操作之前完成,所以这是真的:

Bizarre-looking, but valid (it returns 10), because var is done before anything else is done in the function, so that's really:

function foo() {
    var a;             // <== Hoisted

    a = 5;
    a = a * 2;         // <== Left where it is
    return a;
}

这不是让或 const :

function foo() {
    a = 5;            // <== ReferenceError: a is not defined
    let a = a * 2;
    return a;
}

在声明之前不能使用变量。声明不是悬挂(好吧,部分悬挂,继续阅读)。

You can't use the variable until its declaration. The declaration isn't "hoisted" (well, it's partially hoisted, keep reading).

早些时候我说过


  1. 他们没有被悬挂(好吧,他们有点悬挂,但是以一种有用的方式)

  1. They aren't hoisted (well, they're sort of hoisted, but in a useful way)


排序?是。一个让或 const 声明在整个出现的块中隐藏一个标识符,即使它只在实际生效的地方生效它发生了。示例帮助:

"Sort of"? Yes. A let or const declaration shadows an identifier throughout the block in which it appears, even though it only actually takes effect where it occurs. Examples help:

function foo() {
    let a = "outer";

    for (let x = 0; x < 3; ++x) {
        console.log(a);            // ReferenceError: a is not defined
        let a = 27;
    }

}

请注意,不要获取outer在控制台中,我们收到错误。为什么?因为让中的为块隐藏 a 虽然我们还没有完成它,但在街区之外。块的开头和 let 之间的空格被规范称为时间死区。单词不是每个人的事情,所以这是一个图表:

Note that instead of getting "outer" in the console, we get an error. Why? Because the let a in the for block shadows the a outside the block even though we haven't gotten to it yet. The space between the beginning of the block and the let is called the "temporal dead zone" by the spec. Words aren't everybody's thing, so here's a diagram:

这是有效代码:

function foo() {
    var a;

    // ...many lines later...
    var a;
}

第二个 var 简单地忽略了。

不允许(或 const ):

function foo() {
    let a;

    // ...many lines later...
    let a;                     // <== SyntaxError: Identifier 'a' has already been declared
}



不是全局对象属性的全局



JavaScript具有全局对象的概念,它将各种全局事物作为属性保存。在松散模式下,全局范围内的此引用全局对象,并且在浏览器上有一个引用全局对象的全局: window 。 (其他一些环境在NodeJS上提供了不同的全局,例如全局。)

Globals that aren't properties of the global object

JavaScript has the concept of a "global object" which holds various global things as properties. In loose mode, this at global scope refers to the global object, and on browsers there's a global that refers to the global object: window. (Some other environments provide a different global, such as global on NodeJS.)

直到ES2015,所有全局变量在JavaScript中是全局对象的属性。从ES2015开始,使用 var 声明的声明仍然如此,但是使用声明的声明或常量。因此,在浏览器的全局范围内使用 var 的代码显示42:

Until ES2015, all global variables in JavaScript were properties of the global object. As of ES2015, that's still true of ones declared with var, but not ones declared with let or const. So this code using var at global scope, on a browser, displays 42:

"use strict";
var a = 42; // Global variable called "a"
console.log(window.a); // Shows 42, because a is a property of the global object

但是此代码显示属性的 undefined ,因为让和 const 在全局范围内不要在全局对象上创建属性:

But this code shows undefined for the properties, because let and const at global scope don't create properties on the global object:

"use strict";
let a = 42; // Global variable called "a"
console.log(a); // 42 (of course)
console.log(window.a); // undefined, there is no "a" property on the global object
const q = "Life, the Universe, and Everything"; // Global constant
console.log(q); // "Life, the Universe, and Everything" (of course)
console.log(window.q); // undefined, there is no "q" property on the global object

最后注意事项:如果你比较新的ES2015 类(它提供了一个新的,更干净的),上述大部分也是如此使用函数声明创建构造函数和与之关联的原型对象的语法(与函数表达式相对):

Final note: Much of the above also holds true if you compare the new ES2015 class (which provides a new, cleaner syntax for creating constructor functions and the prototype objects associated with them) with function declarations (as opposed to function expressions):


  • class 声明具有块范围。相反,在流控制块中使用函数声明无效。 (它应该是一个语法错误;相反,不同的JavaScript引擎以不同的方式处理它。有些将它重定位到流控制块之外,其他的就像你使用函数表达式一样。)

  • class 声明未被悬挂;函数声明是。

  • 在同一作用域中使用两个 class 声明的相同名称是语法错误;使用函数声明,第二个胜出,覆盖第一个。

  • class 全局范围内的声明不创建属性全球对象;函数声明。

  • class declarations have block scope. In contrast, using a function declaration within a flow-control block is invalid. (It should be a syntax error; instead, different JavaScript engines handle it differently. Some relocate it outside the flow-control block, others act as though you'd used a function expression instead.)
  • class declarations aren't hoisted; function declarations are.
  • Using the same name with two class declarations in the same scope is a syntax error; with a function declaration, the second one wins, overwriting the first.
  • class declarations at global scope don't create properties of the global object; function declarations do.

提醒一下,这是一个函数声明

Just as a reminder, this is a function declaration:

function Foo() {
}

这些都是函数表达式匿名):

var Foo = function() {
};
doSomething(function() { /* ... */ });

这些都是函数表达式名为其中):

These are both function expressions (named ones):

var Foo = function Foo() {
};
doSomething(function Foo() { /* ... */ });

这篇关于什么是块范围函数ECMAScript 6与ECMAScript 5比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 19:33