zoukankan      html  css  js  c++  java
  • 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());
  • 相关阅读:
    前端开发和网页设计的过去和未来
    Web开发人员vs网页设计师
    Linux最终将会领先于Windows、Mac OS!
    Linux 大爆炸:一个内核,无数发行版
    因PHP漏洞,超过4.5万个中国网站被攻击
    在 Linux 中自动配置 IPv6 地址
    echart-折线图,数据太多想变成鼠标拖动和滚动的效果?以及数据的默认圈圈如何自定义圆圈的样式
    用TweenMax.js动画让数字动起来
    zrender笔记----(数字Number组件)出现的问题和解决办法
    面试题常考&必考之--js中的数组去重和字符串去重
  • 原文地址:https://www.cnblogs.com/wangpeiyuan/p/8277176.html
Copyright © 2011-2022 走看看