es6——之初体验

前言:ECMAScript和JavaScript是什么关系?

  JavaScript由ECMAScript,BOM,DOM组成,前者是后者的规范,后者是前者的实现

一.let和const命令

 1)let用于声明变量,声明的变量是块级作用域


var
a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6
 

 2)var声明的变量有变量提升的现象,let声明的变量没有

console.log(foo); //输出undifined
var foo = 2;

console.log(bar); //报错RefrenceError
let bar = 2;

3)暂时性死区

var tmp = 123;
if(true){
  tmp = '123'; //referenceError
  let tmp;
}

4)不允许重复声明

5)允许在块级作用域中声明函数,声明的行为类似let,在块级作用域之外不可应用

6)do表达式,使得块级作用域可以有返回值

let x = do {
   let t = f();
   t = t * t + 1;      
}
//x的返回值为(t*t+1)

const命令

const声明一个常量,一旦声明,常量的值不能改变

const实际上保证的不是变量的值不能改动,而是变量指向的那个内存地址不得改动

二、变量的解构赋值

  

1)数组的解构复制
 let [a,b,c] = [1,2,3]; //匹配模式
let [head, ...tail] = [1,2,3,4,5]; //head=1,...tail=[2,3,4,5];
//解构不成功,变量的值会等于undefined
//解构赋值允许指定默认值
  let [x=1,y=x] = []; //x=1,y=1
  let [x=1,y=x] = [2] //x=1,y=2

2)对象的解构赋值
let {foo,bar} = {foo: "aaaa",bar:"bbb"};
foo //"aaaa"
bar //"bbb"
let { foo:baz } = {foo: "aaa",bar: "bbb"}
baz //aaa
对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量,真正被赋值的是后者,而不是前者

//如果将一个已经申明的变量用于解构赋值,需要将整个解构赋值语句放在一个圆括号里面
let x;
({x} = {x:1} );

3)字符串的解构赋值
const [a,b,c,d,e] = 'hello';
let {length: len} = 'hello'
len //5

 

三、函数的扩展

1)指定参数默认值,参数变量默认是申明的,所以不能用let或const再次申明
function log(x,y='world'){
  console.log(x,y)
}
console.log(log.length); //1 length指必须传入的参数的个数
log('hello) // hello world
log('hello','china') //hello china
log('hello','') //hello

2)rest参数运算符...,用于获取多余的参数
//arguments变量的写法
function soortNumbers(){
  return Array.prototype.slice.call(arguments).sort();
//arguments是一个类似数组多的对象,Array.prototype.slice.call先将其转化为数组
}
//rest参数的写法
const sortNumbers = (...numbers) => numbers.sort();

3)对象扩展运算符...
//数组操作的应用
let arr1 = [1,2,3];
let arr2 = [...arr1]; 用扩展运算符只会复制数据
arr2.push(4);
console.log(arr2); [1,2,3,4]
console.log(arr1); [1,2,3]

let arr1 = [1,2,3];
let arr2 = arr1;
arr2.push(4);
console.log(arr2); [1,2,3,4]
console.log(arr1); [1,2,3,4]


3)箭头函数
var sum = (num1,num2) => num11 + num2;
var sum = (num1,num2) =>{
    return num1+ num2;
}
箭头函数中this指向定义时所在的对象

四、Promise是实现异步编程的一种解决方案,有pending,fulfilled,rejected三种状态

Promise对象的状态只能从pending——>fulfilled( resolved )或从pending——>rejected

const promise = new Promise(function(resolve,reject){
  if(/异步操作成功/){
    resolve(value);
  }else{
    reject(error);
  }
})
//Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
promise.then(function(value){
  console.log(value); //异步操作成功的回调函数
},function(err){
  console.log(err); //异步操作失败的回调函数
})

let state = 1;
function step1(resolve,reject){
  console.log('开始第一步');
  if(state == 1){
    resolve('第一步完成了');
  }else{
    reject('第一步完成失败')
  }
}
function step2(resolve,reject){
  console.log('开始第二步');

  if(state == 1){
    resolve('第二步完成了');
  }else{
    reject('第二步完成失败')
  }
}
function step3(resolve,reject){
  console.log('开始第三步');  if(state == 1){    resolve('第三步完成了');
  }else{
    reject('第三步完成失败')
  }
}

new Promise(step1)
.then(function(val){
  console.log(val);
  return new Promise(step2)
})
.then(function(val){
  console.log(val);
  return new Promise(step3))
})

.then(function(val){
  console.log(val);
})
 
 

五、class类和继承//定义类

//定义类
class People{   constructor(name,type){
    this.name = name;
    this.type = type;
  }
  toString(){
    return `${this.name} + ${this.type}`;
  }  
}

let p1 = new People('wpy',‘nv');

//Object.assign方法可以很方便的一次向类添加多个方法
Object.assign(Point.prototype,{
  toString(){},
  toValue(){},
})

//类的继承
class Dog extends People{
  constructor(name,type,age){
    super(name,type); //调用父类的constructor(name,type);子类必须在constructor方法中调用super
    this.age = aage;
  }
  
  toString(){
    return this.age + '' + super.toString(); //调用父类的toString()
  }
}

六、for...of和for...in的区别

let arr = ['a','b','c'];
for (let val of arr){ //遍历的是属性值
  console.log(val); //输出a,b,c
}

for(let val in arr){ //for in 遍历的实际上是对象的属性名称
  console.log(val); //输出下标值0 1 2
}
arr,forEach(function(element,index,arr){
  console.log(element); //指向当前元素
  console.log(index); //当前元素的下标值
  console.log(arr); //当前数组
})

//in的用法
let obj={
  a: '1',
  b: '2'
}
console.log(a in obj); true
console.log(c in obj); false 判断对象中是否有某属性,返回true和false

七、模版字符串

`
 <ul>
   <li>${items}</li>
 </ul>
`
es6新增字符串方法
let jspang = "技术胖"
let blog = "很高兴认识你,技术胖"
console.log(blog.includes(jspang)); 判断blog中是否含有jspang所包含的字符串,返回true或false
console.log(blog.startWidth(jspang)); 判断开头是否包含...
console.log(blog.endWidth(jspang));判断结尾是否包含...
console.log(jspang.repeat(21));复制字符串

 

八、模块化

  es6实现了模块功能,完全可以取代ComminJS和AMD规范,成为浏览器和服务器通用多的模块解决方案

  es6模块不是对象,而是通过export命令显示指定输出的代码,再通过import命令输入

1)如果你希望外部能够读取模块内部的某个变量,就必须用export关键字输出该变量
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export {firstName, lastName, year}; //推荐使用这种写法,因为这样就可以在脚本尾部一眼看出输出了哪些变量
2)一般情况下,export输出的变量就是本来的名字,但是可以使用as关键字重命名
function v1(){...}
function v2(){...}
export {
  v1 as streamV1,
  v2 as streamV2
}
export命令规定的是对外的接口,必须与模块内部的变量建立 一一对应的关系
3)模块的整体加载
impoort {arear,circumference} from './circle';
console.log('圆面积:' + area(4));
console.log('圆周长'+ circumference(14));

整体加载
impoort *as circle from './circle';
console.log('圆面积:' + circle.area;
console.log('圆周长'+ circle.circumference(14));

4)export和export default的区别

export default function crc32(){ //export default输出,用于指定模块的默认输出,一个模块只能有一个默认输出,所以export default命令只能用一次

}
import crc32 from 'crc32';import输入语句不需要使用大括号

export function crc32(){ //export输出
}
import {crc32} from 'crc32'; //import输入语句需要使用大括号export default 42;//正确
export 42;//报错

export var a=1; //正确
export default var a = 1; //错误

4)模块的加载实现
//传统方法
<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>
默认情况下,浏览器是同步加载javascript脚本,加入defer或async属性,脚本就会异步加载,渲染引擎遇到这一行命令就会开始下载外部脚本,但不会等它下载和执行,而是执行后面的命令

async和defer的区别:
  defer是渲染完再执行,即DOM解构完全生成,以及其他脚本执行完成,如果有多个defer脚本,会按照它们再页面出现的顺序加载
  async是下载完再执行,即一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染

//es6的加载规则
<script tyope="module" src="./foo.js"></script>
//浏览器中对于带有type="module"的script,都是异步加载,不会造成堵塞浏览器,等同于打开了浏览器的defer属性
5)es6模块的转码
//命令行傻瓜模式
npm init -y 生成package.json文件
npm install -g babel-cli 全局安装babel命令行
cnpm install --save-dev babel-preset-es2015 babel-cli xi
新建.babelrc文件
{
  "presets":[
      "es2015"
  ],
  "plugins":[]
}
//改成命令行自动模式
  在package.json中配置
  "scripts":{
    "build": "babel src/index.js -o dist/index.js
  }


九.set和map数据结构

  1)Set类似于数组,但成员的值唯一,没有重复的值  

const s = new Set(); //只能放数组,不能放对象
[2,3,5,4,2,2].forEach(x = >s.add(x)); // [].forEach(function(value,index,array){})
for(let i of s){ //of结构遍历数组
  console.log(i);
}
for(let key in object){ //遍历对象
   console.log(key);
   console.log(object[key]);
}
//数组去重
[...new Set(array)]

//Set实例的属性和方法
操作方法:
  add(value) 添加某个值,返回Set结构本身
  delete(value) 删除某个值,返回一个布尔值,表示删除是否成功
  has(value) 返回一个布尔值,表示该值是否为Set的成员
  clear() 清除所有成员,没有返回值

Array.from()方法可以将Set结构转为数组
function dedupe(array){
  return Array.from(new Set(array));
}
dedupe([1,2,3,3,4,4]);

遍历操作
  keys() 返回键名的遍历器
  values() 返回键值的遍历器
  entries() 返回键值对对的遍历器
  forEach() 使用回调函数遍历每个成员

2)WeakSet结构与Set类似,也是不重复的值的集合

//weakset的成员只能是对象,不能是其他类型的值
//weakset中的对象都是弱引用
//没有size属性
const ws = new WeakSet();
let obj = {a:'jspang',b:'技术胖'};
ws.add(obj); //需要通过add()添加元素,不能直接通过new WeakSet({});

方法:
  WeakSet.prototype.addd(value) 向WeakSet实例添加一个新成员
  WeakSet.prototype.delete(value) 清楚WeakSet实例对的指定成员
  WeakSet.prototype.has(value) 返回一个布尔值,表示某个值是否存在

3)Map

 

1)Map的实例和操作方法
//1.
size属性
const map = new Map();
map.set('foo',true);
map.set('bar',false);
map.size //2

//2.set(key,value) 设置键名key对应的键值为value
const m = new Map();
m.set('edition',6);
m.set(262,'standard');
m.set('wpy','dmn');

//3.get(key) 获取key对应的键值
//4.has(key) 返回一个布尔值,表示某个键是否在当前Map对象之中
//5.delete() 删除某个键值对,返回true,删除失败,返回false
//6.clear() 清楚所有成员,没有返回值
2)遍历方法
  keys() 返回键名的遍历器
  values() 返回键值的遍历器
  entries() 返回所有成员的遍历器
  forEach() 遍历map的所有成员
3)与其他数据结构的相互转换
  //map转为数组用扩展运算符...
  const myMap = new Map()
  .set(true,7)
  .set({foo: 3},['abc']);
  [...myMap]

  //数组转为Map,将数组传入Map构造函数
  

4)WeakMap

  WeakMap结构与Map结构类似,也是用于生成键值对的集合

  WeakMap只接受对象作为键名,不接受其他类型的值作为键名

十、es6数字操作

1).二进制声明
let binary = 0B010101;

2)八进制的声明
let octal = 0o666;
//es6中将所有的方法都放在了Number对象中
let a = 11/4;
Number.isFinite(a);判断a是否为数字,返回true或false
Number.isNaN(a); 判断a是否为NaN
Number.isInteger(a); 判断a是否为整数 //判断的范围在-(Math.pow(2,53)-1)到Math.pow(2,53)-1之间
Number.MAX_SAFE_INTEGER;integer的最大安全值
Number.MIN_SAFE_INTEGER;integer的最小安全值
Number.parseFloat(a); 将a转换成浮点型
Number.parseInt(a); 将a转换成整型


十一、es6新增的数组知识

//es6中将所有与数组有关的方法都放在了Array中
Array.from(json); 将json字符串转换成数组
Arraay.of('wpy','ai','lll'); 将字符串转换成数组
实例方法
  let arr = [1,3,4,5,56];
  1)arr.find(function(value,index,arr){
    return value>5 //查找数据
  })
  2)arr.fill('要替换进来的新数据',数组的起始位置,数组的结束位置);替换数组元素,左闭右开区间
  3)for of数组循环
  for(let item of arr){
    console.log(item);输出的是数组值
  }
  for(let item of arr.keys()){
    console.log(item);输出的是数组的下标
  }
  for(let [index,val] of arr.entries()){
     console.log(index,val);输出键值对
  }
  let arr = ['jspang','技术胖','大胖'];
  let list = arr.entries(); 生成数组条目
  console.log(list.next().value); //jspang
  console.log(list.next().value); //技术胖
  console.log(list.next().value); //大胖

 

 十二、es6新增的的对象知识

1)Object.is() 判断两个对象是否相等
let obj1={name: 'jspang'};
let obj2={name: 'jspang};
console.log(Object.is(obj1.name,obj2.name));true

===同值相等,is严格相等
console.log(+0 === -0); trye
console.log(NaN === NaN); false

console.log(Object.is(+0,-0)); false
console.log(Object.is(NaN,NaN)); true

2)Object.assign() 合并对象
let a = {a: 1};
let b = {b: 2};
let c = {c: 3};
let d = Object.assign(a,b,c);

十三、Symbol(fo循环的时候不输出)

let obj = {name: 'jspaang',skill:'web'};
let age = Symnbol();
obj[age] = 18;
console.log(obj); {name: 'jspang',skill:'web',age:18};
for(let item in obj){
  console.log(obj[item]); //jspang web 循环时不输出age
}
console.log(obj[age]); //可以通过这种方式输出

 

十.Proxy实例的方法  

//proxy预处理
new Proxy({目标对象},{预处理对象})
let pro = new Proxy({
  add:function(val){
    return val+100;
  },
  name: 'i am wpy'
},{
  get:function(target,key,property){ //打印pro.name之前执行的函数
    console.log('come in get');
    return target[key];
  },
  set:function(target,key,value,receiver){
    console.log(`setting ${key} = ${value}`);
    return target[key] = value;
  }
});
console.log(pro.name);
pro.name = '技术胖'; //setting name = 技术胖

let target = function(){
  return 'i am wpy';
}
let handler = {
  apply(target,ctx,args){
    console.log('ddo apply');
    return Reflect.apply(...arguments);
  }
}
let pro = new Proxy(target,handler);
console.log(pro());
posted @ 2018-01-12 18:15  动作大王  阅读(181)  评论(0编辑  收藏  举报