ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ES6新特性(上)——let及const、解构赋值、模板字符串、Symbol

2021-12-09 23:03:01  阅读:131  来源: 互联网

标签:ES6 const log age console let obj 解构 name


这里写目录标题

一、let及const

let和const是ES6新增的两种新的声明格式,用于补全ES5标准中var声明变量的不足:在JavaScript中用’var’来声明变量会出现变量提升的情况,即通过"var"声明的变量,系统都会把声明隐式的升至顶部,这样的特性往往会让刚接触JavaScript及习惯其他语言的开发人员不适应,导致程序出现问题。

1、ES6的作用域

ES5中定义作用域有两种:全局作用域和函数作用域,ES6中新增了块级作用域,用"{}"表示。块级作用域用于声明作用域之外无法访问的变量,主要有两种:
(1)函数内部块级作用域:

function test(){
	let a = 20
}
test()
console.log(a)

(2)在{ }字符之间的区域:

{
	let a = 10
}
console.log(a)

for(let i=0;i<100;i++){
	let sum = 0;
	sum = sum+i
}

2、const命令

使用const声明的是常量,常量的值不能通过重新赋值来改变,并且不能重新声明,所以每次通过const来声明的常量必须进行初始化。
(1)与其他语言不同,const在使用过程中如果声明的是对象,需要注意是可以修改对象的属性值,但不允许修改已经声明的对象

const obj = {
	name:'张三',
	age:20
}
//属性值时可以直接修改的
obj.name = '李四'
console.log(obj)

//对象直接修改会报错
obj = {}

(2)如果想让对象属性不能修改,可以借助Object.freeze函数来冻结对象

const obj = {
	name:'张三',
	age:20
}
Object.freeze(obj);//冻结对象
obj.name = "李四";//修改属性
console.log(obj);//结果任然是{name:'张三',age:20}}

(3)通过Object.freeze冻结对象需要注意的是:不能冻结多层对象

const obj = {
	name:'张三',
	age:20,
	family:{
		father:{
			name:'张安',
			age:48
		}
	}
}
object.freeze(obj);//冻结对象
obj.family.father.age=58;//family对象李的属性不能被冻结
console.log(obj);//对象age的值被改变

在这里插入图片描述
(4)解决多层冻结问题可以通过封装一个deepFreeze函数来实现:

function deepFreeze(obj){
	object.freeze(obj);
	for{let key in obj){
		if(obj.hasOwnProperty(key) && typeof obj[key] === 'object'){
			deepFreeze(obj[key])
		}
	}
}

deepFreeze(obj);//冻结对象
obj.family.father.age = 50;//修改对象属性的值
console.log(obj);//对象age的值未被改变

在这里插入图片描述

3、临时死区

let和const都是块级标识符,所以let和const都是在当前代码块内有效,常量不存在变量提升的情况。但是通过let和const声明的常量,会放在临时死区(temporal dead zone),通过下面代码可以看出:

{
	console.log(typeof a);
	let a = 10
}

在这里插入图片描述
即使通过安全的typeof操作符也会报错,原因是JavaScript引擎在扫描代码变量时,要么会把变量提升至顶部,要么会把变量放在临时死区。这里通过let声明的’a’变量会被放在临时死区,所以在声明之前打印就会报错.

4、循环中let和const的使用

(1)在ES5标准中,for循环中的循环变量都是通过var来声明的,由于var没有独立的作用域,导致在循环中创建函数时会出现结果和思路不一致的情况,如下:

let funArr = [];//该数组中存放的是函数
for(var i=0;i<5;i++){
	funArr.push(function(){
		console.log(i)
	})
}
funArr.forEach(item=>{
	item();
})

在这里插入图片描述

(2)循环结果不是预想的0,1,2,3,4,而是5个5,这是因为var声明在循环中作用域共用,并且会把i保存在全局作用域中。要解决循环中保存函数的问题,可以利用闭包创建独立的作用域,代码如下:

let funArr = [];
for(var i=0;i<5;i++){
	(
		function(i){
			funArr.push(function(){
				console.log(i)
			})
		}
	)(i)
}
funArr.forEach(item=>{
	item()
})

在这里插入图片描述
(3)这样通过自执行函数就可以解决循环中创建函数的问题。但利用ES6中let和const提供的块级作用域可以让代码更简洁:

let funArr = [];
for(let i=0;i<5;i++){
	funArr.push(function(){
		console.log(i)
	})
}
funArr.foeEach(item=>{
	item()
})

在这里插入图片描述
(4)在for-in或for-of循环中使用const时,方法与let一致:

let obj = {
    name:'张三',
    age:20
}
for(const i in obj){
    console.log(i)  //输出name、age
}

let arr = ['张三','李四','王五']
for(const value of arr){
    console.log(value)  //输出张三、李四、王五
}

在这里插入图片描述

二、解构赋值

1、Spread / Rest 操作符

Spread / Rest 操作符指的是’…’,具体是Spread 还是Rest 需要看上下文语境。
(1)当被用于迭代器(Iterator)是按一定的顺序对一个或多个容器中的元素进行遍历的一种机制

function foo(x,y,z){
    console.log(x,y,z);
}

let arr = [1,2,3];
foo(...arr);//1,2,3

(2)当被用于函数传参时,是一个Rest操作符:

function foo(...args){
    console.log(args);
}

foo(1,2,3,4,5);//[1,2,3,4,5]

2、数组的解构

(1)在ES5标准中赋值多个变量采用的方法是:

var a = 10;
var b = 20;
var c = 30;

ES6提供了更简洁 的解构赋值来实现 上述变量的定义:

let [a,b,c] = [10,20,30];
console.log(a);
console.log(b);
console.log(c);

等号右边的值会按照顺序 一次赋值给左边的变量。
(2)非一一对应关系的赋值

let [a,b] = [10,20,30]
console.log(a,b);   //输出10,20

let [a,b,c] = [10,20]
console.log(a); //10
console.log(b); //20
console.log(c); //undefined

(3)也可以通过“…”把 特定的元素 放在变量里:

let [a,...arr] = [10,20,30]
console.log(a); //10
console.log(arr);   //[20,30]

(4)在ES6中可以通过解构赋值来呼唤变量

let a = 10;
let b = 20;
[a,b] = [b,a];
console.log(a,b)    //20,10

3、对象的解构

(1)对象解构的写法与数组解构类似:

let obj = {
    name:'张三',
    age:20,
    height:'178cm'
}

let {name,age,height} = obj;    //变量的名称必须和对象的属性 名相同
console.log(name,age,height);   //张三 20 178cm

(2)也可以解构多层对象

let person = {
    name:'张三',
    age:20,family:{
        father:'张安',
        mother:'李艳'
    }
}
let {name,age,family:{father,mother}} = person
console.log(name,father)	//张三 张安

(3)在解构对象是也可以席定员变量名称:

let obj = {
    name:'张三',
    age:20
}
let {name:myname,age:myage} = obj;
console.log(myname,myage);  //张三 20

4、解构的默认值和参数的解构

(1)不管是数组的解构赋值,还是对象的解构赋值都可以添加默认参数 。如下:

let obj = {
    name:'张三',
    age:20
}
let {
    name,
    age,
    height = '178cm'
} = obj
console.log(height);    //178cm

(2)在函数参数中使用解构,参数解构也可以给默认参数:

function fun({
    name,
    age,
    height='178cm'} = {}){
        console.log(name,age);  //张三,20
}
let obj = {
    name:'张三',
    age:20
}
fun(obj)

三、模板字符串

ES5标准中一般输出模板是通过字符串拼接的方式进行的。在ES6中可以通过模板字符串简化字符串的拼接,模板字符串通过反引号来表示"``",如果要嵌入变量通过"${ 变量名 }"来实现:

let arr = [
    {
        name:'张三',
        age:20
    },
    {
        name:'李四',
        age:23
    },
    {
        name:'王五',
        age:25
    }
]
let str = '';
for(let i=0;i<arr.length;i++){
    str += `姓名是:${arr[i].name},年龄是:${arr[i].age}`;
}
console.log(str)

在这里插入图片描述

四、Symbol

ES5中提供了6种数据类型分别是:undefined、null、boolean、string、number、object。ES6中新增了一种数据类型Symbol来表示唯一的值,每个创建的Symbol都是唯一的,这样在实际运用中可以创建一些唯一的属性及定义私有变量。例如:

let s1 = Symbol;//直接创建
let s2 = Symbol(‘mySymbol’);//传入字符串创建
1、目前前端项目都会采用模块化构建,为了防止对象属性名被覆盖,可以通过symbol来定义属性名;例如:

//a.js
const NAME = Symbol('name')
let obj = {
    [NAME]:'张三',
    age:23
}
export default obj;
//b.js
import Obj from'./a.js'
const NAME = Symbol('name');
obj[NAME] = '李四';
console.log(obj);//{age:23,Symbol():'张三',Symbol():'李四'}

2、利用Symbol作为属性名,属性名不会被Object.keys()、Object.getOwnPropertyNames()、for…in循环返回。例如:

let obj = {
    [Symbol()]:'张三',
    age: 20,
    height:'178com'       
}
for(let key in obj){
    console.log(key);
}
let keys = Object.keys(obj);
console.log(keys); //输出:'age','height'
console.log(Object.getOwnPropertyNames(obj)); //输出:'age','height'

在这里插入图片描述
3、可以在类里利用Symbol来定义私有属性及方法。例如:

let People = (
    function(){
        let name = Symbol('name');
        class People {
            constructor(yourname){
                this[name] =  yourname; // name就是People的私有变量
            }
            sayName(){
                console.log(this[name])
            }
        }
        return People;
    }
)();

let zhangsan = new People('张三');
console.log(zhangsan[Symbol('name')]); //访问类的私有变量,输出undefined
zhangsan.sayName()//张三

标签:ES6,const,log,age,console,let,obj,解构,name
来源: https://blog.csdn.net/m0_46420078/article/details/121783117

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有