ES6语法学习(一)-let和const
1.let 和 const
变量提升:
在声明变量或者函数时,被声明的变量和函数会被提升到函数最顶部;
但是如果声明的变量或者函数被初始化了,则会失去变量提升;
示例代码:
param2 = "第二个参数"
console.log(param1); // undefined
console.log(param2); // 第二个参数
var param1 = "第一个参数";
var param2;
对于变量 "param1":
它被声明且初始化了,所以失去了变量提升,在 "console.log(param1);" 语句访问 "param1" 时则会得到 "undefined" 的结果无法得到初始化的结果,但是不会报错,在 "console.log(param1);" 之前对param1进行赋值,则会在后面 的console语句中打印出你新赋的值;
对于变量 "param2":
它只是被声明了,所以直接打印则会得到 "undefined" 的结果,因为它本身就没有值,同样在 "console.log(param2);" 语句之前对他初始化,则会在console语句中得到你初始化的值;与"param1" 相比,访问 "param1" 时无法获取到它的初始化的值,但是 "param1" 在访问它的语句之前进行赋值则可以访问它的新值;"param2" 可以在任何访问它之前的语句进行初始化,并且访问的结果就是 "param2" 初始化的值;
let 命令
使用let 声明变量只会在它所在的块级区域生效,并且生效的区域是从这一条声明语句向下延伸到这一个块级区域结束;let声明的变量也不会出现变量提升;
let命令不允许对同一变量的重复声明;
示例代码:
console.log(b); // undefined
{
console.log(a); // Cannot access 'a' before initialization
console.log(b); // undefined
c = 3;
console.log(c); //
let a = 1;
var b = "这是一条字符串";
var c;
console.log(a); //
console.log(b); // 这是一条字符串
console.log(c); //
}
console.log(a);// a is not defined
console.log(b); // 这是一条字符串
console.log(c); //
对于变量 "a":
两个花括号"{}"之间的区域是使用 "let" 声明的变量 "a" 所在的块级作用域,但是 "a" 能被调用生效的区域只是从 "let a = 1;" 这条声明语句一直向下直到结尾的花括号 "}" 处,在这个范围内,a才是可以被使用的;而从开头的花括号 "{" 一直到 "let a = 1;" 之间这个无法访问到 "a" 的区域叫做 "暂时性死区";
第一条"console.log(a);" 语句提示 “不能在a初始化之前访问”,
第二条 "console.log(a);" 语句打印 '1' ,
第三条 花括号外的 "console.log(a);" 语句打印 "a未定义";
对于变 "b":
它被声明并且初始化了,在console语句中访问得到的值是 "undefined",只有在访问 "b" 的语句之前对 "b" 进行重新赋值,才能拿到 "b" 中的值;并且在花括号之外的区域也能访问到它,同样,只能在花括号包裹的整个区域的 "下方" 才能访问到;
对于变量 "c":
它与 "b" 的区别则如 上方 "变量提升" 部分所讲的一样;
const 命令
const命令与let命令一样是块级作用域,具有暂时性死区,不能对同一变量进行重复声明;
const声明的变量必须初始化,该变量的值无法更改,const定义的变量时一个只读变量;
const的本质是控制变量指向的内存地址所保存的数据不得改动,对于简单变量("字符串","布尔值","数值"),其值就保存在变量指向的存贮地址,所以这类变量是无法重新赋值的,成为一个常量;而对于复杂变量(通常是指对象与数组)变量指向的内存地址保存的是一个指向了实际数据的指针,const能保证的是这个指针指向的地址不变,却不能保证这个数据的结构不发生改变;
示例代码:
{
const b; // Missing initializer in const declaration
const a = "变量a";
const obj = {};
const arr = [];
console.log(a); // 变量a
console.log(obj); // {}
console.log(arr); // []
obj = { age: 1 }; // Assignment to constant variable.
arr = ["数据"]; // Assignment to constant variable.
obj.name = "张三";
arr.push("一个数据");
console.log(obj); // {name:"张三"}
console.log(arr); // ["一个数据"]
a = "另一个变量"; // Assignment to constant variable.
}
对变量 "a":
const初始化后赋值为 "变量a" ,第5行console语句可以访问到初始化的值,第12行代码对简单变量进行赋值则抛出一个错误:"对const类型的变量赋值";
对于变量 "b":
const声明的变量必须初始化;
对于复杂变量 "arr","obj":
第11,12行是将整个变量的指针指向了另一个地址,所以会抛出错误,而14,15行代码则是对原对象(数组)进行数据结构上的改变,obj新增一个属性,arr新增一个数据,他们的指针依旧指向原本指向的地址,只是其中的数据的结构发生了变化所以可以在第16,17行代码中打印出结果;
冻结对象
使用Object.freeze(); 方法可以将一个对象冻结使它无法添加或者修改自己的属性,但是如果是对象数据中嵌套着一个对象属性,这个嵌套的对象是不受影响的,它任然可以对自己的属性进行增删改操作;
这时则需要考虑使用递归来将整个对象进行冻结,从而真正使这个对象变成一个常量;
在第一个代码块中,obj2.obj3是不受 Object.freeze(); 影响的,将第二个代码块中的 freezeAll 方法加入进来后,obj2的全部属性以及嵌套着的对象的属性也被冻结,从而将整个obj2变成了一个常量;
示例代码:
{
let obj1 = { name: "李四" };
Object.freeze(obj1);
console.log(obj1); // {name: "李四"}
obj1.name = "张三";
console.log(obj1); // {name: "李四"}
let obj2 = { age: 14, obj3: { name: "王五" } };
Object.freeze(obj2);
obj2.obj3.age = 23;
obj2.obj3.name = "张三";
console.log(obj2.obj3); // {name: "张三", age: 23}
}
{
function freezeAll(obj) {
Object.freeze(obj);
Object.keys(obj).forEach(attr => {
if (typeof obj[attr] === "object") {
freezeAll(obj[attr]);
}
})
}
freezeAll(obj2);
console.log(obj2.obj3); // {name: "张三", age: 23}
obj2.obj3.name = "新的名字";
console.log(obj2.obj3); // {name: "张三", age: 23}
}
ES6语法学习(一)-let和const的更多相关文章
- ES6语法:var、let、const的区别详解
今天来说说es6的语法,最基础的也就是var,let,const 的用法与区别了,我们来看看他们之间的恩怨情仇. 首先来说说var,这个只要是学过js的都知道,它是用来声明一个变量的,但是它在开发中也 ...
- ES6 语法学习(一)
1.let 和 const 关键字 let 与 var 的区别有: a.let 声明的变量只在当前的块级作用域内有效(块级作用域通俗的话就是被{}包裹起来的区域声明对象的{}例外). b.let 声明 ...
- ES6 语法学习总结
第一节:什么是ES6? ES6是什么?跟JavaScript有什么关系? JavaScrip由三部分组成:分别是ECMAScript,BOM和DOM. 1)由此看出,ECMAScript是Java ...
- ES6语法 学习
ECMAScript 6,也被称为ECMAScript 2015是ECMAScript标准的最新版本.6是语言的一个重要更新,并第一次更新语言由于ES5 2009标准.现在主要JavaScript引擎 ...
- ES6 语法学习(二)
1.类的建立与继承 constructor方法是类的构造函数是默认方法,通过new命令生成对象实例时,自动调用该方法.一个类必须有constructor方法,如果没有显式定义,一个默认的constru ...
- ES6学习笔记<一> let const class extends super
学习参考地址1 学习参考地址2 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015:也 ...
- Webpack4 学习笔记三 ES6+语法降级为ES5
前言 此内容是个人学习笔记,以便日后翻阅.非教程,如有错误还请指出 Webpack 将es6.es7语法降级为es5 需要通过 babel JavaScript编译器. 安装: npm i babel ...
- ES6语法的学习与实践
ES6是JavaScript语言的新一代标准,是ECMAScript的第六个版本,加入了很多新的功能和语法,在很多框架,如在使用Vue,React等框架的项目中一般都采用ES6语法来编写的,下面对经常 ...
- ES6学习之-let 和const命令
let 和const命令 let命令 用来声明变量,类似于var .let声明的变量 只在let命令所在的代码块内有效. 在for循环里也是如此 每次循环其实都是一个代码块 function fn() ...
随机推荐
- java 两个数组相减结果
public static void main(String[] args) { String[] a = new String[] { "1", "5", & ...
- Android 性能优化 ---- 内存优化
1.Android内存管理机制 1.1 Java内存分配模型 先上一张JVM将内存划分区域的图 程序计数器:存储当前线程执行目标方法执行到第几行. 栈内存:Java栈中存放的是一个个栈帧,每个栈帧对应 ...
- 【Docker】Redis 安装使用教程
1.安装 1.1 拉取镜像 docker pull redis redis:4.0 1.2 创建redis容器名"redistest1",并开启持久化 docker run -d ...
- 30个Linux Shell脚本经典案例(上)
编写Shell过程中注意事项: 开头加解释器:#!/bin/bash 语法缩进,使用四个空格:多加注释说明. 命名建议规则:变量名大写.局部变量小写,函数名小写,名字体现出实际作用. 默认变量是全局的 ...
- 怎么理解Python迭代器与生成器?
怎么理解Python迭代器与生成器?在Python中,使用for ... in ... 可以对list.tuple.set和dict数据类型进行迭代,可以把所有数据都过滤出来.如下: ...
- 目前解决移动端1px边框最好的方法
在移动端开发时,经常会遇到在视网膜屏幕中元素边框变粗的问题.本文将带你探讨边框变粗问题的产生原因及介绍目前市面上最好的解决方法. 1px 边框问题的由来 苹果 iPhone4 首次提出了 Retina ...
- LeetCode 86 | 链表基础,一次遍历处理链表中所有符合条件的元素
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第53篇文章,我们一起来看LeetCode第86题,Partition List(链表归并). 本题的官方难度是M ...
- React native项目后期调整UI总结
字体 fontSize: 14, marginLeft: 10, marginTop: 2, fontFamily: 'ABBvoiceCNSG-Regular', 布局 paddingHorizon ...
- 聊一聊Flutter的setState()
Flutter 里面包含两种widget 一种可变的,一种不可变的: 在可变的widget中可以使用 setstate(){} 函数. 官方也给出了例子: _onClick(){ setState() ...
- android获取各种系统路径的方法
链接https://blog.csdn.net/qq_26296197/article/details/51909423 通过Environment获取的 Environment.getDataDir ...