ECMAScript 新特性1

文章说明:本文章为拉钩大前端训练营所做笔记和心得,若有不当之处,还望各位指出与教导,谢谢 

一、ECMAScript概述

ECMAScript也是一门脚本语言,一般缩写为ES,通常把他看做JavaScript的标准化规范,实际上JavaScript是ECMAScript的扩展语言。ECMAScript当中只提供了最基本的语法。JavaScript实现了ECMAScript语言标准,并且在这个基础之上做了扩展:

web环境下:

Node环境下: 

JavaScript语言本身指的就是ECMAScript,2015年开始ES保持每年一个版本的迭代。

二、ES2015概述

ES2015也称ES6。ECMAScript标准规范:http://www.ecma-international.org/ecma-262/6.0/  相比于ES5.1的变化比较大

  • 解决了与原有语法上的一些问题或者不足
  • 对原有语法进项增强
  • 全新的对象、全新的方法、全新的功能
  • 全新的数据类型和数据结构

三、ES2015 let与块级作用域

  • 全局作用域
  • 函数作用域
  • 块级作用域:{}所包裹起来的范围成为块

yarn add nodemon -dev  该命令安装了nodemon ,yarn nodemon 文件名   该命令在文件修改保存后自动执行

if(true){
    var foo = 'zce'
}
console.log(foo)// zec 这种情况当代码复杂时是不利的
//=======================================
if(true){
    let foo = 'zce'
}
console.log(foo) //foo is not defined
// let let声明后其作用域在大括号内,外部无法访问

循环的情况:

for(var i = 0; i< 3; i++){
    for(var i = 0; i< 3; i++){
        console.log(i)
    }
    console.log('内层结束 i=' +i)// 内层结束 i = 3
}

// 0 1 2
//外层声明了i过后,内层再次声明这个变量,都是使用var声明,并不是一个块级作用域内的成员,而是全局成员,内层所声明的i会覆盖掉外层声明的i,等内层循环完之后,内层的i为3,对于外层仍然是3,所以不会继续循环了

//===============================================================
for(let i = 0; i< 3; i++){
    for(let i = 0; i< 3; i++){
        console.log(i)
    }
    console.log('内层结束 i=' +i)
}
// i为内部的块级作用域的局部成员,内层循环的let 把i关进了一个盒子当中,并不影响外部成员,即便把外部的let改为var也是可以的
var elements = [{},{},{}]
for(var i = 0;i<elements.length;i++){
    elements[i].onclick = function(){
        console.log(i)
    }
}
elements[0].onclick()// 这里的i无论是几,结果都是3
//打印的i始终是全局作用域的i,循环完成之后i被累加到了3,最后结果都是3
//====================================
//建立闭包机制避免上述问题
var elements = [{},{},{}]
for(var i = 0;i<elements.length;i++){
    elements[i].onclick = (function(i){
        return function(){
            console.log(i)
        }
    })(i)
}//闭包利用函数作用域去摆脱全局作用域产生的影响
elements[0].onclick()
//闭包机制较为复杂, 将var改为let就解决了
for(let i=0;i<3;i++){
    let i = 'foo'
    console.log(i)//foo foo foo
    //两个i不在同一个作用域当中
}
//拆解如下:
let i = 0;

if(i<3){
    let i = 'foo'// i为if语句内部的独立的局部作用域,外部循环的计数器是外部循环产生的作用域,所以是互不影响的
    console.log(i)
}

i++

if(i<3){
    let i = 'foo'
    console.log(i)
}

i++

if(i<3){
    let i = 'foo'
    console.log(i)
}

i++

// ============================
console.log(foo)//undefined 说明打印的时候,此时的foo已经声明了,只是还没有赋值而已,这种现象叫做变量声明的提升
var foo = 'zec'
//================
console.log(foo)//Cannot access 'foo' before initialization(引用异常的错误)
let foo = 'zec'
  • 其它详情请阅读《JavaScript高级程序设计·第四版》中的第三章第三节。

四、ES2015const

  • const声明一个只读的恒量或者常量,比let基础上多了个只读特性,声明过后不允许被修改
const name = 'zec'
name = 'jack' //Assignment to constant variable,不能改变name
  • 声明和赋值不能放到两个语句当中

const name
name = 'zec'//声明和赋值不能放到两个语句当中
  • 当定义对象时,不能修改指向的堆内存地址
const obj = {}
obj.name = 'zec'//并没有修改指向的内存地址,只是修改了这块内存当中的数据,是被允许的

obj = {}//obj赋值新的空对象会报错,因为这种赋值改变了obj的内存指向

最佳用法:不用var ,主用 const,配合let;默认全部使用const,对于一定会需要修改的值用let声明.

五、ES2015 数组的解构

  • 使用解构的方式快速获取数组内指定的成员
const [foo,bar,baz] = arr
console.log(foo,bar,baz)//100 200 300
  • 获取某个位置对应的成员
const [, , baz] = arr// 获取某个位置对应的成员
console.log(baz)//300
  • 解构位置的变量名之前添加三个点表示提取从当前位置往后的所有成员,三个点用法只能在解构成员的最后一个位置上使用
const [foo,...rest] = arr
console.log(rest)// [200,300]
  • 解构位置的成员个数小于被解构的数组长度,就会按照从前到后的位置去提取,多出来的成员不会被提取

const [foo] = arr
console.log(foo)//100
  • 若解构位置的成员大于数组长度,跟访问数组不存在的下标是一样的,无法访问

const[foo,bar,baz,more] = arr
console.log(more)//undefined
  • 若给提取到的成员设置默认值,在解构位置的变量名后面等号赋值,如果没有提取到数组成员,则变为默认值

const[foo,bar,baz = 123,more = 'default value'] = arr
console.log(baz,more)// 300 default value

六、对象的解构

使用与对象匹配的结构来实现对象属性赋值

const obj = {name :'zce',age:18}
const { name } = obj 
console.log(name)//zce
  • 解构对象的其它特点跟解构数组是完全一致的

  • 当前作用域当中若有同名的成员会产生冲突,为了解决这个冲突,使用重命名的方式

const name = 'tom'
const {name} = obj //会产生同名的冲突
console.log(name)

//为了解决这个冲突,使用重命名的方式
const name = 'tom'
const { name:objName} = obj ///会产生同名的冲突,obj的name属性必须要用name提取出来,为了解决这个冲突,使用重命名的方式:{name : objName},objName是重命名的变量名
 console.log(objName)//zce
  • 若还要添加默认值,则直接等号赋值即可

const name = 'tom'
const {name:objName = 'jack'} = obj
console.log(objName)//jack

七、ES2015 模板字符串

使用模板字面量定义字符串。

  • 字符串外加入反引号,若字符串里面要单引号则加反斜杠转义
const str = `hello es2015,this is a \`string\``
console.log(str)// hello es2015,this is a `string`
  • 字符串内换行即可,同时保留换行字符/n

const str = `hello es2015,

this is a \`string\``
console.log(str)
/* 
hello es2015,

this is a \`string\`
*/
  • 模板字符串当中支持通过插值表达式的方式在字符串当中嵌入对应的数值

const name = 'tom'
const msg = `hey,${name} ----- ${1 + 2} ----${Math.random()}`//差值表达式内,还可以嵌入任何标准的JavaScript语句,语句的返回值最后会返回
console.log(msg)//hey,tom -----3 ----0.41110767462165887

 八、带标签的模板字符串

const str = console.log`hello world`//console.log作为模板字符串标签,控制台打印了['hello world']
const name = 'tom'
const gender = true

function myTagFunc(strings){
    console.log(strings)
}
const result = myTagFunc`hey,${name} is a ${gender}` /*['hey,','is a','.'] 是模板字符串中内容分割过后的结果,在模板字符串当中可能会有嵌入的表达式,所以结果数组是按照表达式分割后静态的内容,除了这个数组以外*/

这个函数还可以接收到所有在我们这个模板字符串当中出现的表达式的返回值

function myTagFunc(strings,name,gender){
    console.log(strings,name,gender)
}

const result = myTagFunc`hey,${name} is a ${gender}` //['hey,','is a','.'] tom true
function myTagFunc(strings,name,gender){
    return '123'
}

const result = myTagFunc`hey,${name} is a ${gender}` //123
function myTagFunc(strings,name,gender){
    return strings[0] +name +strings[1] +gender + strings[2]
}

const result = myTagFunc`hey,${name} is a ${gender}`// hey,tom is a true

标签函数的作用就是对模板字符串进行加工

function myTagFunc(strings,name,gender){
    const sex = gender ?'man' : 'woman'
    return strings[0] +name +strings[1] +gender + strings[2]
}

其它剩余特性见下一篇文章

猜你喜欢

转载自blog.csdn.net/weixin_41962912/article/details/109670441
今日推荐