一.定义变量
(1).let块级作用域的使用
代码块: { }包起来的代码 ,形成了一个作用域,简称块级作用域
比如:if for while
特点:只能在代码块里面使用
{
let a=12;
console.log(a);//打印出 12
}
console.log(a);//undefined
总结:
var与let的区别
①let具备块级作用域,var只有函数作用域
②let不允许重复声明
(2).const 常量
const声明一个只读的常量。一旦声明,常量的值就不能改变;声明后 const必须有值。
const a=12;
a=15;
console.log(a)//报错 ,定义了不能修改
const a;
a=15;
console.log(a)//报错 声明后const a必须有值
注意:
1.const的作用域与let命令相同:只在声明所在的块级作用域内有效。
2.const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
3.const不可重复声明常量。
具体参考:es6 let 和 const 命令
二.字符串拼接
之前定义字符串是:var str=""; 或是var str=''; 字符串的拼接:‘abc'+变量名+'ef'
现在 使用的是反单引号 : var str=``;这是模板字符串 字符串的拼接:`abc${变量名}ef`
//之前
var a='老师';
var b='不忘初心';
var str=a+'说:“'+b+'、继续前进!”';
document.write(str);//老师说:不忘初心、继续前进!”
//现在
var a='老师';
var b='不忘初心';
var str=`${a}说:${b}、继续前进!”`;
document.write(str);//老师说:不忘初心、继续前进!”
三.解构赋值
1.基本用法
var [a,b,c]=[12,5,101];
console.log(a);//12
var {a,b,c}={b:5,a:12,c:101};
alert(a);//12
模式匹配:左侧的样子=右侧的样子
如下面
var [a,b,d]=[12,[1,2],5];
console.log(b);//[1,2]
var [a,[b,c],d]=[12,[1,2],5];
console.log(b);//1
var [{a,e},[b,c],d]=[{e:'eeee', a:'aaaa'},[1,2],5];
console.log(a)//aaaa
2.默认值
var {time=12,id=0}={};//给变量time设置默认值12
console.log(time);//12
3.返回值
function getPos(){
return {left:100, stop:1000};
}
var {left,stop}=getPos();
console.log(left);//100
3.用处:
交互---数据解析
var arr={
"brxm00": "陈步卜",
"brxb00": "男",
"zyhghh": "0987654321",
"sqysxm":"吴聊聊",
"sqrqsj": "2018-01-17 10:36:17",
};
var {brxm00,brxb00,zyhghh,sqysxm,sqrqsj}=arr;
console.log(sqysxm);//吴聊聊
var json={"statuses": [{"name": "小高","id": "0001"}],"ad": [{"id": "0002","mark": "AB21321XDFJJK"}]};
var {s,a}=json;console.log(a);//undefined
var {statuses,ad}=json;console.log(ad);// [{"id": "0002","mark": "AB21321XDFJJK"}]
在赋值的时候 变量不能更换(statuses 不能随意定义,要跟json数据字段名一样)
具体参考:变量的解构赋值
四.数组扩展
1. 扩展运算符(...
)
该运算符主要用于函数调用.
function show(...args){
args.push(5);
console.log(args);//[1,2,3,4,5]
}
show(1,2,3,4);
(1).复制数组
a)循环
var arr=[1,2,3];
var arr2=[];
for(var i=0; i<arr.length; i++){
arr2[i]=arr[i];
}
arr2.pop();
console.log(arr2);//[1,2]
b)Array.from(arr)复制
var arr=[1,2,3];
var arr2=Array.from(arr);
arr2.pop();
console.log(arr, arr2);//[1,2,3],[1,2]
c)var arr2=[...arr] 扩展运算符(...
)
var arr=[1,2,3];
var arr2=[...arr];
arr2.pop();
console.log(arr, arr2);//[1,2,3],[1,2]
五.遍历(迭代或是循环)for of
整个对象 表现类似 for in(输出的索引) for of输出的是值
var arr=['apple','banana','orange','pear'];
for(var i in arr){ // 0 1 2 3 索引
console.log(i);
}
for(var i of arr){ // apple banana orange pear 值
console.log(i);
}
注意:for of 可以循环数组 但是不能循环json对象 ,其实真正循环的是map对象
具体可以参考:ES6 Iterator 和 for...of 循环
六.map对象
和json相识,也是一种key-value形式。Map对象为了和for of循环配合而生的。
a.设置 :map.set(name,value);
b.获取:map.get(name)
c.删除:map.delete(name)
var map=new Map();
map.set('a','apple');//设置
map.set('b','banana');
map.set('c','orange');
map.set('d','pear');
for(var name of map){
console.log(name);//a,apple b,banana c,orange d,pear
}
console.log(map.get('b'))//获取b的值
map.delete('a');
console.log(map)// {"b" => "banana", "c" => "orange", "d" => "pear"}
d.循环map对象
①循环键值对
var map=new Map();
map.set('a','apple');//设置
map.set('b','banana');
map.set('c','orange');
for(var name of map){
console.log(name);//a,apple b,banana c,orange
}
for(var [key,value] of map){
console.log(key, value);//a,apple b,banana c,orange
}
for(var [a,b] of map.entries()){
console.log(a,b);//a,apple b,banana c,orange
}
②循环 key
for(var key of map.keys()){
console.log(key);// a b c
}
③循环val
for(var val of map.values()){
console.log(val);//apple banana orange
}
注意:遍历map对象不能使用for in
具体可以参考:es6 javascript的map数据类型
七.函数扩展
(1).函数参数的默认值
ES6为参数提供了默认值。在定义函数时便初始化了这个参数,以便在参数没有被传递进去时使用。
function log(x, y) {
y = y || 'World';
console.log(x, y);
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello World
(2).箭头函数
ES6之前是这样使用的
function show(){alert(1);}
show();
----------------------
//传参数
function show(a){return a;}
show(12);
----------------------
//传多个参数
function show(a,b){return a+b;}
show(12,5);
现在有了,ES6后,就更加简洁 推出箭头函数
1.基本用法
var f = v => v;
上面的箭头函数等同于:
var f = function(v) {
return v;
};
箭头函数最直观的三个特点。
a.不需要 function 关键字来创建函数
b.省略 return 关键字
c.继承当前上下文的 this 关键字。
具体参考:箭头函数
八.对象
对象简洁化:属性 ,方法
(1).属性简写
function f(x, y) {
return {x, y};
}
f(1, 2) // Object {x: 1, y: 2}
(2).方法简写
const o = {
method() {
return "Hello!";
}
};
// 等同于
const o = {
method: function() {
return "Hello!";
}
如下面的例子 单体模式:
var name='abb';
var age=101;
var preson={
name,
age,
showName(){
console.log(this.name);
},
showAge(){
return this.age;
}
};
preson.showName();//abb
九.面对对象
ES6之前的面对对象
人类 工人类
function Person(name,age){ //类、构造函数
this.name=name;
this.age=age;
}
Person.prototype.showName=function(){
return this.name;
};
Person.prototype.showAge=function(){
return this.age;
};
(1).ES6的面对对象:类 class
构造函数 constructor 生成完实例以后,自己就执行的
class Person{ //类
constructor(name,age){//构造函数
this.name=name;
this.age=age;
}
showName(){//定义在类中的方法不需要添加function
return this.name;
}
showAge(){
return this.age;
}
}
// 使用方式跟构造函数一样,对类使用new命令,跟构造函数的用法完全一致
var p1=new Person('aaa',10);
var p2=new Person('bbb',20);
console.log(p1.showName());//aaa
console.log(p2.showName==p1.showName);//true
console.log(p1.constructor==Person);//true
(2).继承
es6之前的继承 :原型继承 子类.prototype=new 父类();
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.showName=function(){
return this.name;
};
Person.prototype.showAge=function(){
return this.age;
};
//Worker
function Worker(name,age){
Person.apply(this,arguments);
}
//原型继承
Worker.prototype=new Person();
var p1=new Person('abc',10);
var w1=new Person('ddd',20);
console.log(w1.showName());//ddd
es6的继承 :class Worker extends Person{}
class Person{ //类
constructor(name='default',age=0){
this.name=name;
this.age=age;
}
showName(){
return this.name;
}
showAge(){
return this.age;
}
}
//继承
class Worker extends Person{
showJob(){
return '您的工作暂无的';
}
}
var p1=new Person();
var w1=new Worker('mmm',56);
console.log(w1.showJob());//您的工作暂无的
注意:不能在覆盖父级的constructor,如果要重新设置constructor,就在constructor里面调用父级的构造super(name,age);。
class Person{ //类
constructor(name='default',age=0){
this.name=name;
this.age=age;
}
showName(){
return this.name;
}
showAge(){
return this.age;
}
}
//继承
class Worker extends Person{
constructor(name,age,job='扫地的'){
super(name,age);
this.job=job;
}
showJob(){
return this.job;
}
}
var p1=new Person();
var w1=new Worker('mmm',56);
console.log(w1.showName());//mmm
console.log(w1.showJob());//扫地的
具体参考:ES6中class的使用+继承
十.模块化
ES6中模块的设计思想:尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入输出的变量。
(1).导入模块
a.js const a=12; const b=12; export default {a ,b};
(2).引入模块
import model from './a.js';
小demo
//a.js
const a=12; const b=12; export default {a ,b};
//sum.js
import {a,b } from '../a.js '
export default function sum() {
return a+b;
}
//使用中
import sum from '../sum'
console.log(sum)//24
具体参考:ES6 Module的语法
十一.Promise对象的理解
Promise:就是一个对象,用来传递异步操作的数据/信息(异步: 多个操作可以同时进行)。它有三种状态,分别是pending-进行中、resolved-已完成、rejected-已失败。比传统的解决方案(回调函数和事件)更合理更强大。
pending(等待、处理中)―> Resolve(完成,成功)
―> Rejected(失败)
使用:
// 方法1
let p1 = new Promise ( (resolve, reject) => {
if ( success ) {
resolve(a) // pending ——> resolved 参数将传递给对应的回调方法 成功
} else {
reject(err) // pending ——> rejectd 失败
}
})
p1.then(function(value){
alert('成功了:'+value);
return value+1;
},function(value){
alert('失败了');
})
1.promise的API
(1).then()
这个Promises对象有一个then方法,非常靠谱的方法。允许指定回调函数,在异步任务完成后调用。
var p1=new Promise(function(resolve,reject){
resolve(1);//成功
});
p1.then(function(value){
alert('成功了:'+value);//弹出 成功了 1
},function(){
alert('失败了');
});
(2).catch――用来捕获错误
var p1=new Promise(function(resolve,reject){
resolve('成功了');
});
p1.then(function(value){
console.log(value);
throw '发生错误了';
}).catch(function(e){
console.log(e);//发生错误了
});
(3).Promise.all―― 全部,用于将多个promise对象,组合,包装成一个全新的promise实例Promise.all([p1,p2,p3...]);所有的promise对象,都正确,才走成功;否则,只要有一个错误,是失败了。
var p1=Promise.resolve(3);//成功
var p2=Promise.reject(5);//失败
Promise.all([p1,p2]).then(function(value){
console.log('成功了,'+value);
},function(value){
console.log('错误了,'+ value);//错误了 5
});
(4).Promise.race―― 返回也是一个promise对象;最先能执行的promise结果,哪个最快,用哪个
var p1=new Promise(function(resolve,reject){
setTimeout(resolve,100,'one');
});
var p2=new Promise(function(resolve,reject){
setTimeout(resolve,50,'two');
});
Promise.race([p1,p2]).then(function(value){
console.log(value);//最快的是50 所以输出two
});
(5).Promise.reject() ――生成错误的一个promise
Promise.reject('这是错误的信息').then(function(){
},function(res){
console.log(res);//输出 这是错误的信息
});
(6).Promise.resolve() ――生成一个成功的promise对象语法:Promise.resolve(value) Promise.resolve(promise)
Promise.resolve('Success').then(function(value){
console.log(value);//输出 Success
},function(res){
console.log(res);
});
var p1=Promise.resolve(3);
var p2=Promise.resolve(p1);
p2.then(function(value){
console.log(value);//输出 3
});
具体参考:Promise对象的理解
十二.Generrator――>生成器
是一个函数,执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
1.形式上:
a). 函数名字前面有 *
b). 函数内部使用 yield语句
2.基本使用:
function* g() {
yield 'a';//yield 是产生 产生a
yield 'b';
return 'ending';
}
var gen = g();
console.log(gen.next());
gen.next()返回一个非常非常简单的对象{value: "a", done: false},'a'就是g函数执行到第一个yield语句之后得到的值,false表示g函数还没有执行完,只是在这暂停。
function* show(){
yield 'Hello';
yield 'World';
yield 'Es6';
}
var res=show();
console.log(res.next()); //{value:'Hello', done:false}
console.log(res.next()); //{value:'World', done:false}
console.log(res.next()); //{value:'Es5', done:false}
console.log(res.next()); //{value:'undefined', done:true} //因为函数没有返回值,所以是undefined
next()会一直执行,执行到最后一个yield 的下一步,也就是return 这步,如果存在return的时候,最后一个yield输出的就是 return 的值。
总结: 每次返回一个value和done结果(value是每次yield后面值;done是一个布尔值,代表是否遍历结束)
3.注意的问题
a.yield是否有返回值?
yield语句本身没有返回值,或者每次返回undefined
b.next可以带参数?
一句话说,next方法参数的作用,是覆盖掉上一个yield语句的值。
function* fn(){
for(var i=0; true; i++){
var a= yield i;
if(a){i=-1}
}
}
var d=fn();
console.log(d.next());
console.log(d.next());
console.log('参数');
console.log(d.next(11));
console.log('--------');
console.log(d.next());
从上面可以看出来,加了参数(不管加什么参数),输出的就是前一个yield语句的值
4.与for of 一起使用 :循环generator函数
function* fn(){
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
return 6;
}
for(let v of fn()){
document.write(v);//1 2 3 4 5
}
为什么不输出6 ,因为done 为true 遍历结束
5.generator函数放到对象里面
var json={
*show(){
yield 'a';
yield 'b';
return 'c';
}
};
var res=json.show();
console.log(res.next());
console.log(res.next());
console.log(res.next());
二.列子
sum(5,"",9);//total:14
function sum(x,y,z) {
let total =0;
if(x) total +=x;
if(y) total +=y;
if(z) total +=z;
console.log( `total:${total}` )
}
//es6
const sum2 = (...m) =>{
let total = 0;
for(var i of m){
total += i;
}
console.log( `total:${total}` )
}
sum2(4,8,9,10);
/*
*数组的扩展: ... 加上数组 console.log(...[4,8])
*/
//1.数组的合并
let arr1=[1,3];let arr2 =[2,8];
//js
console.log(arr1.concat(arr2));//[1, 3, 2, 8]
//es6
console.log([...arr1,...arr2])//[1, 3, 2, 8]
var [s1,...s2]=[4,8,10,30];//左右俩边一一对应
console.log(s2)// [8, 10, 30]
//字符串
var [a,b,c]="es6";
console.log(a)//e
let xy =[...'es6'];
console.log(xy)//["e", "s", "6"]