7-22 es学习

1.let命令

1-1. ++牢记重点++

let声明变量只在所在块级作用域起作用即{}

不存在变量提升即无声明提前

在let声明某个变量的前面,都属于这个变量的死区

let声明块状区域内不允许重复声明

1-2.++重点案列解释++

(1).{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1

  • es5 没有块级作用域所以var声明不报错而es6{}为块级作用域外面不能访问里面

(2).for (let i = 0; i < 10; i++) {
// ...
}
console.log(i);
// ReferenceError: i is not defined

  • for循环的计数器,就很合适使用let命令。计数器i只在for循环体内有效,在循环体外引用就会报错

(3).var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a6; // 10

  • 最终输出10因为i是全局变量 要等for循环全部执行完毕在执行函数a6而i的最终值为10

(4)var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a6; // 6

  • 变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。你可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。

(5).for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc

  • for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。这表明函数内部的变量i与循环变量i不在同一个作用域,有各自单独的作用域。

(6).// var 的情况
console.log(foo); // 输出undefined
var foo = 2;
// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

  • 不存在变量提升

if (true) {
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ结束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}

  • let前面都是死区

typeof x; // ReferenceError
let x;
typeof undeclared_variable // "undefined"

  • tyoeof 检验不安全会报错

// 报错
function () {
let a = 10;
var a = 1;
}
// 报错
function () {
let a = 10;
let a = 1;
}

function func(arg) {
let arg; // 报错
}
function func(arg) {
{
let arg; // 不报错
}
}

  • 不允许重复声明

2.块级作用域

++2-1.为什么需要块级作用域?++

  • 内层变量可能会覆盖外层变量

var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefinedvar tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined

  • 用来计数的循环变量泄露为全局变量

var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5

++2-2.es5模仿块级作用域++

(function () {
var tmp = ...;
...
}());

++2-3. es6块级作用域++

{
let tmp = ...;
...
}

++2-4.块级作用域的弊端---无法取到里面的值++

{
let t = f();
t = t * t + 1;
}

  • 块级作用域将两个语句封装在一起。但是,在块级作用域以外,没有办法得到t的值,因为块级作用域不返回值,除非t是全局变量

let x = do {
let t = f();
t * t + 1;
};

  • 使得块级作用域可以变为表达式,也就是说可以返回值,办法就是在块级作用域之前加上do,使它变为do表达式变量x会得到整个块级作用域的返回值

3.const命令

++const声明一个只读的常量。一旦声明,常量的值就不能改变。++

(1)const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.

  • const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值
  • 只声明不赋值,就会报错
  • const的作用域与let命令相同:只在声明所在的块级作用域内有效。
  • const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。

(2)var message = "Hello!";
let age = 25;
// 以下两行都会报错
const message = "Goodbye!";
const age = 30;

  • const声明的常量,也与let一样不可重复声明。

4.global对象

  • 浏览器里面,顶层对象是window,但 Node 和 Web Worker 没有window。
  • 浏览器和 Web Worker 里面,self也指向顶层对象,但是 Node 没有self。
  • Node 里面,顶层对象是global,但其他环境都不支持。

你可能感兴趣的:(7-22 es学习)