美文网首页
19.ES6-let和cost

19.ES6-let和cost

作者: 静昕妈妈芦培培 | 来源:发表于2022-02-07 09:15 被阅读0次

在ES5中我们声明变量都是使用的var关键字,从ES6开始新增了两个关键字可以声明变量:letconst

  • let、const在其他编程语言中都是有的,所以也并不是新鲜的关键字;
  • 但是let、const确确实实给JavaScript带来一些不一样的东西;

let关键字:

  • 从直观的角度来说,let和var是没有太大的区别的,都是用于声明一个变量

const关键字:

  • const关键字是constant的单词的缩写,表示常量、衡量的意思;
  • 它表示保存的数据一旦被赋值,就不能被修改;
  • 但是如果赋值的是引用类型,那么可以通过引用找到对应的对象,修改对象的内容;

注意:另外let、const不允许重复声明变量;

es6新增了使用let/const声明变量

1.let 声明的变量可以被重新赋值,
let name = "why";
name = "koby";
console.log(name); // koby
2.const 声明的变量不可以重新被赋值,但是如果其值是引用类型的话,可以改变引用类型值的属性的值
const age = 18;
// age = 20  //TypeError: Assignment to constant variable.
const info = { name: "why", age: 18 };
info.name = "koby";
console.log(info); //{name: 'koby',age: 18}
3.const声明的变量,在声明时必须被赋值
 const height; //SyntaxError: Missing initializer in const declaration
4.let/const声明的变量是不可以重复被声明的
let name = "why";
const info = { name: "why", age: 18 };

let name = 'lily' // SyntaxError: Identifier 'name' has already been declared
const info = '你好' // SyntaxError: Identifier 'info' has already been declared

var和let的作用域提升

1.var声明的变量存在作用域提升,即在声明之前可以访问

console.log(foo) //undefined

var foo = 'abc'

2.let声明的变量不存在作用域提升

console.log(foo); //ReferenceError: Cannot access 'foo' before initialization

let foo = "abc";

let、const和var的另一个重要区别是作用域提升:

  • 我们知道var声明的变量是会进行作用域提升的;
  • 但是如果我们使用let声明的变量,在声明之前访问会报错;

那么是不是意味着foo变量只有在代码执行阶段才会创建的呢?

  • 事实上并不是这样的,我们可以看一下ECMA262对let和const的描述;
  • 这些变量会被创建在包含他们的词法环境被实例化时,但是是不可以访问它们的,直到词法绑定被求值
    • 也就是说: let/const声明的变量在声明前已被创建,但是不能被访问
      image.png

let/const有没有作用域提升呢?

从上面我们可以看出,在执行上下文的词法环境创建出来的时候,变量事实上已经被创建了,只是这个变量是不能被访问的

  • 那么变量已经有了,但是不能被访问,是不是一种作用域的提升呢?

事实上维基百科并没有对作用域提升有严格的概念解释,那么我们自己从字面量上理解;

  • 作用域提升:在声明变量的作用域中,如果这个变量可以在声明之前被访问,那么我们可以称之为作用域提升
  • 在这里,它虽然被创建出来了,但是不能被访问,我认为不能称之为作用域提升;

所以我的观点是let、const没有进行作用域提升,但是会在解析阶段被创建出来。

let和const和window之间的关系

我们知道,在全局通过var来声明一个变量,事实上会在window上添加一个属性:

  • 但是let、const是不会给window上添加任何属性的。
    那么我们可能会想这个变量是保存在哪里呢?
    我们先回顾一下最新的ECMA标准中对执行上下文的描述
    image.png
    也就是说我们声明的变量和环境记录是被添加到变量环境中的:
  • 但是标准有没有规定这个对象是window对象或者其他对象呢?
  • 其实并没有,那么JS引擎在解析的时候,其实会有自己的实现;
  • 比如v8中其实是通过VariableMap的一个hashmap来实现它们的存储的。
  • 那么window对象呢?而window对象是早期的GO对象,在最新的实现中其实是浏览器添加的全局对象,并且
    一直保持了window和var之间值的相等性;


    image.png
    image.png
let flag = 0;
var name = "why";
const info = {
  name: "koby",
  age: 40,
};

console.log(flag); // 0
console.log(window.flag); //undefined
console.log(window.name); // why

非常感谢王红元老师的深入JavaScript高级语法让我学习到很多 JavaScript 的知识

相关文章

网友评论

      本文标题:19.ES6-let和cost

      本文链接:https://www.haomeiwen.com/subject/pykkcrtx.html