ES6 语法 ECMAScript 6.0(以下简称 ES6,ECMAScript 是一种由 Ecma 国际(前身为欧洲计算机制造商 协会,英文名称是 European Computer Manufacturers Association)通过 ECMA-262 标准化的脚本 程序设计语言)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了,并且 从 ECMAScript 6 开始,开始采用年号来做版本。即 ECMAScript 2015, 就是 ECMAScript6。 它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。 每年一个新版本。
什么是 ECMAScript 来看下前端的发展历程:
web1.0 时代: 最初的网页以 HTML 为主,是纯静态的网页。网页是只读的,信息流只能从服务的到客户端 单向流通。开发人员也只关心页面的样式和内容即可。
1995 年,网景工程师 Brendan Eich 花了 10 天时间设计了 JavaScript 语言。
web2.0 时代:
1996 年,微软发布了 JScript,其实是 JavaScript 的逆向工程实现。
1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组 织 ECMA,希望这种语言能够成为国际标准。
1997 年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的 标准, 并将这种语言称为 ECMAScript, 这个版本就是 1.0 版。 JavaScript 和 JScript 都是 ECMAScript的标准实现者,随后各大浏览器厂商纷纷实现了ECMAScript标准。
所以,ECMAScript 是浏览器脚本语言的规范 ,而各种我们熟知的 js 语言,如 JavaScript 则是规范的具体实现。
ES6新特性 1.let/var
let
var
let 声明的变量有严格局部作用域
var 声明的变量往往会越域
let 只能声明一次
var 可以声明多次
let 不存在变量提升
var 会变量提升
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // var 声明的变量往往会越域 // let 声明的变量有严格局部作用域 { var a = 1; let b = 2; } console.log(a); // 1 console.log(b); // ReferenceError: b is not defined // var 可以声明多次 // let 只能声明一次 var m = 1 var m = 2 let n = 3 // let n = 4 console.log(m) // 2 console.log(n)// Identifier 'n' has already been declared // var 会变量提升 // let 不存在变量提升 console.log(x); // undefined var x = 10; console.log(y); //ReferenceError: y is not defined let y = 20;
JS 中使用 var 来声明一个变量时, 变量的作用域主要是和函数的定义有关
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 <button > 按钮1</button > <button > 按钮2</button > <button > 按钮3</button > <script > var btns = document .getElementsByTagName ('button' ) for (var i = 0 ; i < btns.length ; i++) { btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) } i = 2 { btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) } { i = 1 btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) } { btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) } var btns = document .getElementsByTagName ('button' ) for (var i = 0 ; i < btns.length ; i++) { ;(function (i ) { btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) })(i) } i = 100000000 ( (function (i ) { btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) })(0 ) )( (function (i ) { btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) })(1 ) )( (function (i ) { btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) })(2 ) ) const btns = document .getElementsByTagName ('button' ) for (let i = 0 ; i < btns.length ; i++) { btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) } i = 10000000 { i = 0 btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) } { i = 1 btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) } { i = 2 btns[i].addEventListener ('click' , function ( ) { console .log ('第' + i + '个按钮被点击' ) }) } </script >
2.const 建议: 在 ES6 开发中,优先使用 const, 只有需要改变某一个标识符的时候才使用 let.
声明之后不允许改变
一但声明必须初始化,否则会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <script > const obj = { name : 'why' , age : 18 , height : 1.88 , } console .log (obj) obj.name = 'kobe' obj.age = 40 obj.height = 1.87 console .log (obj) </script >
3.对象增强写法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 <script > const name = 'why' const age = 18 const height = 1.88 const obj = { run ( ) {}, eat ( ) {}, } </script >
4.解构表达式 数组解构 1 2 3 4 let arr = [1,2,3]; //以前我们想获取其中的值,只能通过角标。ES6 可以这样: const [x,y,z] = arr;// x,y,z 将与 arr 中的每个位置对应来取值 // 然后打印 console.log(x,y,z);
对象解构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const person = { name: "jack", age: 21, language: [ 'java ', 'js ', 'css '] } // 解构表达式获取值,将 person 里面每一个属性和左边对应赋值 const { name, age, language } = person; // 等价于下面 // const name = person.name; // const age = person.age; // const language = person.language; // 可以分别打印 console.log(name); console.log(age); console.log(language); //扩展:如果想要将 name 的值赋值给其他变量,可以如下,nn 是新的变量名 const { name: nn, age, language } = person; console.log(nn); console.log(age); console.log(language);
5.字符串扩展 新的API ES6 为字符串扩展了几个新的 API:
includes() :返回布尔值,表示是否找到了参数字符串。
startsWith() :返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith() :返回布尔值,表示参数字符串是否在原字符串的尾部。
1 2 3 4 5 let str = "hello.vue" ;console .log (str.startsWith("hello" ));console .log (str.endsWith(".vue" ));console .log (str.includes ("e" ));console .log (str.includes ("hello" ));
6.函数优化 函数参数默认值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function add (a, b ) { b = b || 1 ;return a + b; }console .log (add(10 ));function add2 (a , b = 1 ) {return a + b; }console .log (add2(10 ));
不定参数 不定参数用来表示不确定参数个数,形如,…变量名, 由…加上一个具名参数标识符组成。 具名参数只能放在参数列表的最后,并且有且只有一个不定参数
1 2 3 4 5 function fun (...values) { console.log(values.length) }fun (1 , 2 ) fun (1 , 2 , 3 , 4 )
箭头函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <title > Title</title > </head > <body > <script > var sum = (num1, num2 ) => num1 + num2; var sum = function (num1, num2 ) { return num1 + num2; }; var f = v => v; var f = function (v ) { return v; }; var f = ( ) => 5 ; var f = function ( ) { return 5 }; var sum = (num1, num2 ) => { num1+=1 ; return num1 + num2; } let fn = ( ) => void doesNotReturn (); var sum = (num1, num2 ) => { num1+=1 ; num1 + num2; } let getTempItem = id => { id : id, name : "Temp" }; let getTempItem = id => ({ id : id, name : "Temp" }); const test = ( ) => { console .log ('Hello World' ); console .log ('Hello Vuejs' ); } const mul = (num1, num2 ) => num1 * num2 console .log (mul (20 , 30 )); const demo = ( ) => console .log ('Hello Demo' ) console .log (demo ()); </script > </body > </html >
7.对象优化 新增的API ES6 给 Object 拓展了许多新的方法,如:
keys(obj):获取对象的所有 key 形成的数组
values(obj):获取对象的所有 value 形成的数组
entries(obj):获取对象的所有 key 和 value 形成的二维数组。格式: [[k1,v1], [k2,v2],...]
assign(dest, ...src):将多个 src 对象的值 拷贝到 dest 中。 (第一层为深拷贝,第二层为浅 拷贝)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const person = {name : "jack", age: 21 ,language : [ 'java ' , 'js ' , 'css ' ] } console.log(Object .keys(person));//["name", "age", "language"] console.log(Object .values (person));//["jack", 21 , Array (3 )] console.log(Object .entries(person));//[Array (2 ), Array (2 ), Array (2 )] const target = { a: 1 }; const source1 = { b: 2 }; const source2 = { c: 3 }; //Object .assign 方法的第一个参数是目标对象,后面的参数都是源对象。Object .assign(target, source1, source2); console.log(target)//{a: 1 , b: 2 , c: 3 }
声明对象简写 1 2 3 4 5 6 7 8 9 10 const age = 23 const name = "张三" const person1 = { age: age, name: name } console.log (person1)const person2 = { age, name } console.log (person2)
对象的函数属性简写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 let person = { name : "jack" , eat : function (food ) { console .log (this .name + "在吃" + food); }, eat2 : food => console .log (person.name + "在吃" + food), eat3 (food ) { console .log (this .name + "在吃" + food); } } person.eat ("apple" );
对象拓展运算符 拓展运算符 ( … ) 用于取出参数对象所有可遍历属性然后拷贝到当前对象。
1 2 3 4 5 6 7 8 9 10 let person1 = { name: "Amy" , age: 15 }let someone = { ... person1 } console.log (someone) let age = { age: 15 }let name = { name: "Amy" }let person2 = { ... age, ... name } console.log (person2)
8.map map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
1 2 3 4 5 let arr = [ '1 ' , '20' , '-5 ' , '3 ' ];console .log (arr) arr = arr.map (s => parseInt(s));console .log (arr)
9.reduce 语法:arr.reduce(callback,[initialValue])
reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值 (或者上一次回调函数的返回值) ,当前元素值,当前索引,调 用 reduce 的数组。
callback (执行数组中每个值的函数,包含四个参数)
1 、previousValue (上一次调用回调返回的值,或者是提供的初始值 (initialValue) )
2 、currentValue (数组中当前被处理的元素)
3 、index (当前元素在数组中的索引)
4 、array (调用 reduce 的数组)
initialValue (作为第一次调用 callback 的第一个参数。)
1 2 3 4 5 6 7 const arr = [1,20,-5,3]; //没有初始值: console.log(arr.reduce((a,b)=>a+b));//19 console.log(arr.reduce((a,b)=>a*b));//-300 //指定初始值: console.log(arr.reduce((a,b)=>a+b,1));//20 console.log(arr.reduce((a,b)=>a*b,0));//-0
10.this 使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <title > Title</title > </head > <body > <script > const obj = { aaa ( ) { setTimeout (function ( ) { setTimeout (function ( ) { console .log (this ) }) setTimeout (() => { console .log (this ) }) }) setTimeout (() => { setTimeout (function ( ) { console .log (this ) }) setTimeout (() => { console .log (this ) }) }) }, } obj.aaa () </script > </body > </html >