标签:binding 引用 语句 外部 false 函数作用域 outside UNC error
一、let 声明的变量只在它所在的代码块有效 --(for循环的计数器)
1、for
循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
2、不存在变量提升 <==> var
命令会发生“变量提升”现象
3、暂时性死区,只要块级作用域内存在let
命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
4、不允许重复声明
5、块级作用域 { }
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6 疑问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。
二、块级作用域 { }
1、ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。
2、ES6 引入了块级作用域,明确允许在块级作用域之中声明函数,块级作用域之中,函数声明语句的行为类似于let
,在块级作用域之外不可引用。
// 浏览器的 ES6 环境 function f() { console.log(‘I am outside!‘); } (function () { if (false) { // 重复声明一次函数f function f() { console.log(‘I am inside!‘); } } f(); }()); // Uncaught TypeError: f is not a function ES6 在附录 B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。 1、允许在块级作用域内声明函数。 2、函数声明类似于var,即会提升到全局作用域或函数作用域的头部。 3、同时,函数声明还会提升到所在的块级作用域的头部。 实际运行代码如下: // 浏览器的 ES6 环境 function f() { console.log(‘I am outside!‘); } (function () { var f = undefined; if (false) { function f() { console.log(‘I am inside!‘); } } f(); }()); // Uncaught TypeError: f is not a function
三、const
1、const
声明一个只读的常量。一旦声明,常量的值就不能改变,所以一旦声明,就必须立即初始化。
2、不存在变量提升
3、块级作用域
4、暂时性死区
5、不可重复声明
***const
实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动,
对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。
但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const
只能保证这个指针是固定的(即总是指向另一个固定的地址),
至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心
const foo = {}; // 为 foo 添加一个属性,可以成功 foo.prop = 123; foo.prop // 123 // 将 foo 指向另一个对象,就会报错 foo = {}; // TypeError: "foo" is read-only
如果真的想将对象冻结,应该使用 Object.freeze
方法
const foo = Object.freeze({}); // 常规模式时,下面一行不起作用; // 严格模式时,该行会报错 foo.prop = 123;
四、六种声明方式
1、var
2、function
3、let
4、const
5、import
6、class
五、顶层对象的属性
1、浏览器 -- window
2、Node -- global
标签:binding 引用 语句 外部 false 函数作用域 outside UNC error
原文地址:https://www.cnblogs.com/slightFly/p/11867307.html