我已经玩ES6一段时间了,我注意到虽然声明的变量var按预期提升了......
console.log(typeof name); // undefined
var name = "John";
Run Code Online (Sandbox Code Playgroud)
... 用吊装声明let或const似乎有一些问题的变量:
console.log(typeof name); // ReferenceError
let name = "John";
Run Code Online (Sandbox Code Playgroud)
和
console.log(typeof name); // ReferenceError
const name = "John";
Run Code Online (Sandbox Code Playgroud)
这是否意味着变量声明let或未声明const?这是怎么回事?这个问题let和const这个问题有什么区别吗?
我试图通过阅读原始规范来围绕ES6中新的标准化块级功能.我的肤浅理解是:
然而,由于这些语义的一部分被指定为"可选的"并且仅对于Web浏览器是必需的(附件B),因此这进一步复杂化.所以我想填写下表:
| Visible outside of block? | Hoisted? Up to which point? | "TDZ"? |
------------------------------------------------------------------------------------------------------------------------
| Non-strict mode, no "web extensions" | | | |
| Strict mode, no "web extensions" | | | |
| Non strict mode, with "web extensions | | | |
| Strict mode, with "web extensions" | | | |
另外我不清楚在这种情况下"严格模式"是什么意思.这种区别似乎在附件B3.3中引入,作为函数声明的运行时执行的一些附加步骤的一部分:
1. If strict is false, then
...
Run Code Online (Sandbox Code Playgroud)
但是,据我所知,strict指[[Strict]]的是函数对象的内部插槽.这是否意味着:
// Non-strict …Run Code Online (Sandbox Code Playgroud) 在ES5中,编写此类代码被认为是一种很好的做法:
(function () {
//some magic
})();
Run Code Online (Sandbox Code Playgroud)
但是在使用let关键字创建的ES6变量中没有附加到window对象.
那么,现在是否需要在IIFE中编写我们的代码,或者它仍然有一些我没有听说过的目的?
尝试使用闭包和let来打印for循环中的一系列数字:
请考虑以下示例:
for(var i=1; i<10; i++){
setTimeout(function(){
document.write(i);
}, 1000);
}
Run Code Online (Sandbox Code Playgroud)
输出是:
101010101010101010
关闭:
for(var i=1; i<10; i++){
(function(x){
setTimeout(function(){
document.write(x);
}, 1000);
})(i);
}
Run Code Online (Sandbox Code Playgroud)
输出是:
123456789
没有关闭,只需使用ES6让:
for(let i=1; i<10; i++){
setTimeout(function(){
document.write(i);
}, 1000);
}
Run Code Online (Sandbox Code Playgroud)
输出是:
123456789
试图了解我们是否还需要使用IIFE块来关闭ES6?
如果我们真的需要使用ES6闭包,那还有什么好的例子吗?
假设我有以下对象数组:
var arr = [
{"name": "John", "score": "8.8"},
{"name": "John", "score": "8.6"},
{"name": "John", "score": "9.0"},
{"name": "John", "score": "8.3"},
{"name": "Tom", "score": "7.9"}
];
var count = 0;
var avgScore = arr.reduce(function (sum,person) {
if (person.name == "John") {
count+=1;
return sum + parseFloat(person.score);
}
return sum;
},0)/count);
Run Code Online (Sandbox Code Playgroud)
问题:有没有办法在不创建全局计数变量的情况下计算"John"的平均分数.理想情况下,计数将在arr.reduce中的匿名函数内部.
我听说使用全局变量在JavaScript中很糟糕.由于let是块作用域,我可以在包含所有其他函数的块中使用它,并以与全局变量类似的方式使用它吗?
{
var b = 10;
let c = 20;
function foo(){
return c;
}
}
Run Code Online (Sandbox Code Playgroud) 在《你不知道的 JS:作用域和闭包》一书中,Kyle simpson 指出块作用域变量有助于垃圾回收,具体示例如下:
function process(data) {
// do something interesting
}
{
let someReallyBigData = {};
process(someReallyBigData);
}
var btn = document.getElementById("my_button");
btn.addEventListener("click", function click(evt) {
console.log("Clicked!");
}, false);
Run Code Online (Sandbox Code Playgroud)
现在上面的示例应该有助于垃圾收集,因为someReallyBigData一旦块结束,变量就会从内存中删除,与此示例不同,它对垃圾收集没有帮助:
function process(data) {
// do something interesting
}
var someReallyBigData = {};
process(someReallyBigData);
var btn = document.getElementById("my_button");
btn.addEventListener("click", function click(evt) {
console.log("Clicked!");
}, false);
Run Code Online (Sandbox Code Playgroud)
现在我确信这个人对他提供的例子(第一个)是正确的;var但是,我想知道如果我们使用匿名 IIFE(立即调用函数表达式)以及普通的而不是{}花括号和变量,是否一切都会相同let。让我把它变成一个例子:
function process(data) {
// do something interesting
}
(function(){
var someReallyBigData = {};
process(someReallyBigData);
}()); …Run Code Online (Sandbox Code Playgroud) 我对这个概念的理解是,iife 允许您模拟“私有”范围,从而防止全局范围变得混乱。
既然 ECMAScript 6 已经得到了相当广泛的实现,并让我们可以通过 const 和 let 访问块级作用域,那么还有其他理由使用 iife 模式吗?(超出了提供向后兼容性的需要..)
将整个代码块包裹在两个大括号内有什么意义?例如在 .js 文件中:
{
const firstVar;
class firstClass {}
class secondClass {}
}
Run Code Online (Sandbox Code Playgroud)
这是为了创建块作用域并保持全局名称空间干净吗?例如,它是否可以与将整个 javascript 模块包装在自调用函数中相媲美?
例如,看一下这个 JS 文件;
https://github.com/codrops/PageFlipLayout/blob/master/js/demo.js
javascript ×9
ecmascript-6 ×7
let ×2
const ×1
hoisting ×1
iife ×1
reduce ×1
spidermonkey ×1
v8 ×1