ES6
Es6(ECMASCRIPT 6)是继ES5的新一代web前端开发的一个标准语法,JavaScript 和 ECMAScript 是什么关系呢?
我只记得阮一峰老师的ES6标准入门的一句话 前者是后者的一种实现,后者是前者的一种规范
一、用let定义变量 在es5中我们使用的用var定义变量这样带来的不好的问题有一下几点。
用var定义的变量提升
window .onload = function ( ) { console .log(a); var a = 5 ; console .log(b); let b = 6 ; }
按照我们普通的逻辑来说应该是报错的,但是却出现undefined显然不和我们的逻辑。如果是es6显然不会出现这种问题。所以变量在没有申明之前是不可以被使用的,术语称之为 ”暂时性死区“
用let定义变量不能重复定义
window .onload = function ( ) { let a = 5 ; var a = 5 ; }
用let定义的变量,不能够允许第二次定义。用其他的定义变量的方式也是不行的。
块级作用域的引入({})
window .onload = function ( ) { for (var i=1 ; i<2 ;i++){ let j = 3 ; console .log(i); } console .log(j); console .log(i); }
二、对象的简洁写法 let name = "xm" ,age = 13 ; let obj = { name : name; age: age; sayhello : function ( ) { console .log("nihao" ); } } console .log(obj.name);console .log(obj.age);console .log(obj.sayhello());
像上面这样的变量名相同的情况下,完全可以另一种写法这种得到的结果是和上面的一样,是不是代码精简很多?上面的obj.name可以替换成obj[“name”]注意双引号不能省略。注意此时的左边name是属性名,如果替换为[name]: “zh”;此时用的正是用let定义的变量name。这是es6的新属性。
let obj = { name, age, sayhello(){ console .log("nihao" ); } }
let name = "zh" ;let obj = { [name]: "cc" ; ["he" +"llo" ]:"hi" ; } console .log(obj.name);console .log(obj.hello);
三、rest参数 window .onload = function ( ) { function fn (a,b,c,...arr ) { console .log(fn.length); console .log(arguments .length); } fn(2 ,4 ,24 ,34 ,13 ); }
why?为什么是3和5呢?这里的rest参数搭配一个变量名使用,参数一个获取函数多余的参数生成一个数组。这里我也不是太清楚,至于arguments则是获取实参的长度。rest参数不能放在其他的位置,只能作为最后一个参数。
四、函数默认参数值
在es5中我们的写法是这个样子的
function cn (a,b ) { a = a || 0 ; b = b || 0 ; console .log(a+b); } cn(4 );
如果没有那两句代码,则运行结果是NaN 那让我们看看在es6中是
function fn (a,b=0 ) { console .log(a+b); } fn(3 ); fn(3 ,4 );
五、箭头函数 function fn (value,key ) { console .log(value,key); } fn(3 ,4 ); var fn = (value,key )=> { console .log(value,key); } fn(3 ,3 );
恩?Excuse me??还可以这样玩吗?这是针对有两个参数的必须用括号包裹起来,如果没有参数,或者只有一个参数我们还可以这样.
甚至还可以这样只有一个参数,省略括号 或者返回值是一个表达式
value => { statement } value => expression
如果加入返回值,what? 还可以这样????妈耶真是intresting。
var fn = value => value*2 ; console .log(fn(3 )); function fn (value ) { return value*2 ; } console .log(fn(3 ));
ok,到这里你已经差不多会用箭头函数了吧。是不是语法更加的简洁,emmm 真香!
箭头函数不会绑定this(以上如果打印this则都会指向Window对象)箭头函数内部没有this!使用的父级作用域的this不能和new一起使用,不能作为构造函数,没有arguments,那怎么办,我们可以使用rest参数。
箭头函数在定义时执行器上下文的this的指向(不具有块级作用域),即会取当前的函数的作用域链上的this,忽略块级作用域中的this
六、解构赋值
ES5中我们是不是这个样子赋值的,恩,当然还有es6的
let a = 5 ,b = 3 ,c = 2 ;console .log(a);console .log(b);console .log(c);let [a,b,c] = [2 ,3 ,5 ];console .log(a);console .log(b);console .log(c);let [a,[b],c] = [2 ,4 ,5 ]let {a :a,b :b,c :c} = {a :3 ,b :44 ,c :5 }; console .log(a); console .log(b); console .log(c); let {a,b,c} = {a :3 ,b :44 ,c :5 };let {a :w,b :s,c :x} = {a :3 ,b :44 ,c :5 }; console .log(w); console .log(s); console .log(x);
七、扩展运算符 这里所说的扩展运算符是三个点…,不要小看这三个点。它可是用处的。
let newDiv = document .getElementsByTagName("div" ); console .log([...newDiv]); let newDiv = [...document.getElementsByTagName("div" )]; newDiv[0 ].innerHTML = "你好啊,这个世界!" ; let arr = [1 ,3 ,4 ]; let arr2 = [...arr,34 ,35 ,535 ]; console .log(arr2);
扩展运算符实现拷贝继承
八、字符串扩展
includes()查看字符串中是否包含该参数
startsWith()字符串是否以该参数开头
endsWith()同理
repeat()指定字符串重复多少次
padStart(参数1,参数2);参数1必须大于字符串的个数,则用参数2补开头多少个是参数1
padEnd()同理
字符串模板(也是挺main) 要遵循它的规则,反引号和${}它会解析
let name = "木木" ;console .log("我的名字叫" +name);let name = "二人" ;let str = `我的名字是${name} ` ;console .log(str);
当然还有标签模板 ,这个啊,我可能要不是太了解,只知道它会把反引号解析成函数的单引号,从而生成一个数组。像这样
let name ="nn" ;let age = 13 ;console .log`我的名字${name} 我今年${age} 岁` Array (3 )0 : "我的名字" 1 : "我今年" 2 : "岁" length: 3 "nn" 13
九、新增数据类型Set和Map set集合主要是去重,没有重复的值,类似于数组key和value的值是相等的。
let set = new Set (["张三" ,"李四" ,"王二" ]); console .log(set); console .log(set.size); set.add("麻子" ); console .log(set); set.delete("麻子" ); console .log(set); set.has("麻子" ); set.clear(); console .log(set); Set (3 ) {"张三" , "李四" , "王二" } 3 Set (4 ) {"张三" , "李四" , "王二" , "麻子" } Set (3 ) {"张三" , "李四" , "王二" } Set (0 ) {}
下面我们重点介绍下Map这个令人头疼的集合。个人觉得有点乱啊!
let obj1 = {a :1 },obj2={b :2 }; let map = new Map ([ ['name' ,'zs' ], ['age' ,13 ], [obj1,'今天气很好' ], [obj2,'适合睡觉' ], [[1 ,2 ],'hh' ], ]); console .log(map); console .log(map.size); map.set('friends' ,['赵六' ,'力气' ]).set(['dog' ],'夏鸥' ); console .log(map.get('name' )); console .log(map.keys()); console .log(map.values()); console .log(map.entries()); map.forEach(function (value,index ) { console .log(index+value); }); map.set({},"hhh" ); map.set({},"666" ); console .log({}==={}); }
十、Symbol() Symbol()解决命名冲突,独一无二的 不会与其他属性起冲突,在开发中经常作为规范!
let str1=Symbol (); let str2 = Symbol (); console .log((str1 === str2)); let obj = {}; obj.name = "xz" ; obj.name ="yo" ; obj[Symbol ('name' )] = 'zs' ; obj[Symbol ('name' )] = 'xx' ; console .log(obj);
十一、Class JavaScript是没有类这个概念的,但是我们es6新增加了类。个人感觉和Java有点类似
class Person { constructor (name,age){ this .name = name; this .age = age; } print(){ console .log("打印" ); } } let person = new Person('张三' ,10 );console .log(person);person.print();
十二、promise
promise是承诺的意思,它是一种解决异步编程的一种方案,比传统的传统的解决方案(回掉函数和事件)更加的合理,所以我们使用fetch是建立再promise的基础之上。
基本用法: promise是一个构造函数,用来生成promise实例,promise 接受一个参数作为函数,这个函数提供了两个参数分别是resolve和reject他们是两个函数,分别由JavaScript引擎提供,用户自己不用部署。then方法提供了两个回调函数,一个是由promise对象的状态变为resolved,另一个是把promise对象的状态变为rejected传出的值作为参数。
new Promise ((resolve,reject ) => { resolve(); reject(); }).then(() => { console .log("成功之后执行的结果" ) },()=>{ console .log("失败之后的结果" ) })
十三、async 和await 其实async和await是promise封装的一个语法糖,内部还是用promise实现的,await代表的是异步的操作。其中await必须在async的函数内部。
基本用法
<script> function fn ( ) { return new Promise ((resolve,reject ) => { console .log("第一步" ); resolve(); }) } (async function ( ) { await fn(); console .log("第二步" ); })(); </script>
处理await返回值
function fn ( ) { return new Promise ((resolve,reject ) => { setTimeout(() => { resolve("你好" ); },1000 ) }) } (async function ( ) { let res1 = await fn(); console .log("第一步" +res1); let res2 = await fn(); console .log("第二步" +res2); })();
错误处理
function fn ( ) { return new Promise ((resolve, reject ) => { console .log("开始执行" ); resolve("正确执行" ); }); } (async () => { try { let res = await fn(); console .log(res); }catch (e){ console .log(e); } })();