• 关于ES6(ES2015)的知识点详细总结


    ECMAScript6

    ECMAScript简称就是ES,你可以把它看成是一套标准,JavaScript就是实施了这套标准的一门语言,现在主流浏览器使用的是ECMAScript5。

    http://babeljs.io/repl

    1. 作用域变量

    作用域就是一个变量的作用范围。也就是你声明一个变量以后,这个变量可以在什么场合下使用 以前的JavaScript只有全局作用域,还有一个函数作用域

    1.1 var的问题

    1. var没有块级作用域,定义后在当前闭包中都可以访问,如果变量名重复,就会覆盖前面定义的变量,并且也有可能被其他人更改。

      if (true) {
           var name = "高佳睿"; // 期望a是某一个值
       }
      console.log(name); //高佳睿
      name = "看我七十二变";
      console.log(name); //
      看我七十二变
      
      
    2. var在for循环标记变量共享,一般在循环中使用的i会被共享,其本质上也是由于没有块级作用域造成的

      for (var i = 0; i < 3; i++) {
           setTimeout(function () {
               console.log(i);
           }, 0);
       }
      //结果 打印出 3次 3

    1.2 块级作用域

    在用var定义变量的时候,变量是通过闭包进行隔离的,现在用了let,不仅仅可以通过闭包隔离,还增加了一些块级作用域隔离。 块级作用 用一组大括号定义一个块,使用 let 定义的变量在大括号的外面是访问不到的

    1.2.1 实现块级作用域

    if(true){
        let name = '高佳睿';
    }
    console.log(name);// ReferenceError: name is not defined

    1.2.2 不会污染全局对象

    if(true){
        let name = '高佳睿';
    }
    console.log(window.name);  //undefined

    1.2.3 for循环中也可以使用i

    // 嵌套循环不会相互影响
        for (let i = 0; i < 3; i++) {
            console.log("out", i);
            for (let i = 0; i < 2; i++) {
                console.log("in", i);  //out 0  in 0 in 1   out 1 in 0 in 1    out 2 in 0 in 1
            }
        } 

    如果是使用var的话,实际使用是有问题的
        for (var i = 0; i < 3; i++) {
            console.log("out", i);
            for (vari = 0; i < 2; i++) {
                console.log("in", i);  //out 0  in 0 in 1  
            }
        } 

    1.2.4 重复定义会报错

    if(true){
        let a = 1;
        let a = 2; Uncaught SyntaxError: Identifier 'a' has already been declared
    }

    1.2.5 不存在变量的预解释

    for (let i = 0; i < 2; i ++){
        console.log('inner',i);
        let i = 100;
    }  //Uncaught ReferenceError: i is not defined

    1.2.6 闭包的新写法

    以前

    ;(function () {
    
    })();

    现在

    {
    }

    2. 常量

    使用const我们可以去声明一个常量,常量一旦赋值就不能再修改了

    2.1 常量不能重新赋值

    const MY_NAME = '高佳睿';
    MY_NAME = 'gjr';Uncaught TypeError: Assignment to constant variable

    2.2 变量值可改变

    注意const限制的是不能给变量重新赋值,而变量的值本身是可以改变的,下面的操作是可以的

    const names = ['高佳睿一号'];
    names.push('高佳睿二号');
    console.log(names);  //["高佳睿一号", "高佳睿二号"]

    2.3 不同的块级作用域可以多次定义

    const A = "0";
    {
        const A = "A";
        console.log(A)
    }
    {
        const A = "B";
        console.log(A)
    }
    console.log(A)  // A B 0

    3. 解构

    3.1 解析数组

    解构意思就是分解一个东西的结构,可以用一种类似数组的方式定义N个变量,可以将一个数组中的值按照规则赋值过去。

    var [name,age] = ['高佳睿',18];
    console.log(name,age);

    3.2 嵌套赋值

        let [x, [y], z] = [1, [2.1, 2.2]];
        console.log(x, y, z);  //1 2.1 undefined
    
        let [a, [b,c]] = [1, [2.1, 2.2]];
        console.log(a,b,c);  //1 2.1 2.2
    
        let [json,arr,num] = [{name:'高佳睿'},[1,2],3];
        console.log(json,arr,num);  //{name: "高佳睿"} [1, 2] 3

    3.3 省略赋值

    let [, , v] = [1, 2, 3];
    console.log(v);  //3

    3.4 解构对象

    对象也可以被解构

    var obj = {name:'高佳睿',age:18};
    //对象里的name属性的值会交给name这个变量,age的值会交给age这个变量
    var {name,age} = obj;
    //对象里的name属性的值会交给myname这个变量,age的值会交给myage这个变量
    let {name: myname, age: myage} = obj;
    console.log(name,age,myname,myage);  //高佳睿 18 高佳睿 18

    3.5 默认值

    在赋值和传参的时候可以使用默认值

    let [a = "a", b = "b", c =new Error('C必须指定')] = [1, , 3];
    console.log(a, b, c);  //1 "b" 3
    
    function ajax (options) {
        var method = options.method || "get";
        var data = options.data || {};
        //.....
    }
    function ajax ({method = "get", data}) {
        console.log(arguments);  //Arguments [{…}, callee: (...), Symbol(Symbol.iterator): ƒ]
    }
    ajax({
        method: "post",
        data: {"name": "高佳睿"}
    }); 

    4. 字符串

    4.1 模板字符串

    模板字符串用反引号(数字1左边的那个键)包含,其中的变量用${}括起来

    var name = '高佳睿',age = 18;
    let desc = `${name} is ${age} old!`;
    console.log(desc);  //高佳睿is 18 old!
    
    //所有模板字符串的空格和换行,都是被保留的
    var str = `<ul>
    <li>a</li>
    <li>b</li>
    </ul>`;
    console.log(str); 
    /*
      <ul>
    <li>a</li>
    <li>b</li>
    </ul>
    */

    其中的变量会用变量的值替换掉

    function replace(desc){
      return desc.replace(/${([^}]+)}/g,function(matched,key){
        return eval(key);
      });
    }

    4.2 带标签的模板字符串

    可以在模板字符串的前面添加一个标签,这个标签可以去处理模板字符串 标签其实就是一个函数,函数可以接收两个参数,一个是strings,就是模板字符串里的每个部分的字符 还有一个参数可以使用rest的形式values,这个参数里面是模板字符串里的值

    var name = '高佳睿',age = 18;
    function desc(strings,...values){
        console.log(strings,values);
    }
    desc`${name} is ${age} old!`;
    // ["", " is ", " old!", raw: Array(3)]  ["高佳睿", 18]

    4.3 字符串新方法

    • includes():返回布尔值,表示是否找到了参数字符串。
    • startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。
    • endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。
    var s = '高佳睿';
    s.startsWith('高') // true
    s.endsWith('佳') // false
    s.includes('睿') // true

    第二个参数,表示开始搜索的位置

    var w = '高佳睿';
    console.log(w.startsWith('高',2)); // false
    console.log(w.endsWith('佳',2)); // true
    console.log(w.includes('睿',2)); // true

    endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束

    4.4 repeat

    repeat方法返回一个新字符串,表示将原字符串重复n次。

    'x'.repeat(3);  // "xxx"
    'x'.repeat(0);  // ""

    5. 函数

    5.1 默认参数

    可以给定义的函数接收的参数设置默认的值 在执行这个函数的时候,如果不指定函数的参数的值,就会使用参数的这些默认的值

    function ajax(url,method='GET',dataType="json"){
      console.log(url);  //undefined
      console.log(method); //undefined
      console.log(dataType);  //undefined
    }

    5.2 展开操作符

    把...放在数组前面可以把一个数组进行展开,可以把一个数组直接传入一个函数而不需要使用apply

    //传入参数
    let print = function(a,b,c){
        console.log(a,b,c);
    }
    print([1,2,3]);  //[1, 2, 3] undefined undefined
    print(...[1,2,3]);  //1 2 3
    
    // 可以替代apply
    var m1 = Math.max.apply(null, [8, 9, 4, 1]);
    var m2 = Math.max(...[8, 9, 4, 1]);
    
    // 可以替代concat
    var arr1 = [1, 3];
    var arr2 = [3, 5];
    var arr3 = arr1.concat(arr2);
    var arr4 = [...arr1, ...arr2];
    console.log(arr3,arr4); // [1, 3, 3, 5] ,[1, 3, 3, 5]
    
    //类数组的转数组
    function max(a,b,c) {
        console.log(Math.max(...arguments));
    }
    max(1, 3, 4);  //4

    5.3 剩余操作符

    剩余操作符可以把其余的参数的值都放到一个叫b的数组里面

    let rest = function(a,...rest){
        console.log(a,rest);
    }
    rest(1,2,3); // 1 [2,3]

    5.4 解构参数

    let destruct = function({name,age}){
        console.log(name,age);
    }
    destruct({name:'高佳睿',age:6}); //高佳睿 6

    5.5 函数的名字

    ECMAScript 6 给函数添加了一个name属性

    var desc = function descname(){}
    console.log(desc.name); //descname

    5.6 箭头函数

    箭头函数简化了函数的的定义方式,一般以 "=>" 操作符左边为输入的参数,而右边则是进行的操作以及返回的值inputs=>output

    [1,2,3].forEach(val => console.log(val)););

    输入参数如果多于一个要用()包起来,函数体如果有多条语句需要用{}包起来

    箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。 正是因为它没有this,从而避免了this指向的问题。

    var person = {
        name:'高佳睿',
        getName:function(){
          setTimeout(function(){console.log(this);},1000); //在浏览器执行的话this指向window
          setTimeout(() => console.log(this),1000);//在浏览器执行的话this指向person
        }
    }
    person.getName();
    // Window
    //{name: "高佳睿", getName: ƒ}
     

    5.7 数组的新方法

    5.7.1 from

    将一个数组或者类数组变成数组,会复制一份

    let newArr = Array.from(oldArr);

    5.7.2 Array.of

    of是为了将一组数值,转换为数组

    console.log(Array(3), Array(3).length); //[empty × 3]length: 3__proto__: Array(0) 3
    console.log(Array.of(3), Array.of(3).length);  //[3] 1

    5.7.3 copyWithin

    Array.prototype.copyWithin(target, start = 0, end = this.length) 覆盖目标的下标 开始的下标 结束的后一个的下标

    [1, 2, 3, 4, 5].copyWithin(0, 1, 2);   //[2, 2, 3, 4, 5]

    5.7.4 find

    查到对应的元素和索引

    let arr = [1, 2 ,3, 3, 4, 5];
        let find = arr.find((item, index, arr) => {
            return item === 3;
        });
        let findIndex = arr.findIndex((item, index, arr) => {
            return item === 3;
        });
    
        console.log(find, findIndex); // 3 2

    5.7.5 fill

    就是填充数组的意思 会更改原数组 Array.prototype.fill(value, start, end = this.length);

     let arr = [1, 2, 3, 4, 5, 6];
     arr.fill('a', 1, 2);
     console.log(arr);  // [1, "a", 3, 4, 5, 6]

    5.7.5 map

    5.7.6 reduce

    5.7.7 filter

    5.7.8 forEach

    6. 对象

    6.1 对象字面量

    如果你想在对象里添加跟变量名一样的属性,并且属性的值就是变量表示的值就可以直接在对象里加上这些属性

    let name = '高佳睿';
    let age = 8;
    let getName = function(){
        console.log(this.name);
    }
    let person = {
        name,
        age,
        getName
    }
    person.getName();  //高佳睿

    6.2 Object.is

    对比两个值是否相等

    console.log(Object.is(NaN,NaN));  //true
    console.log(Object.is(123,"123")); //false

    6.3 Object.assign

    把多个对象的属性复制到一个对象中,第一个参数是复制的对象,从第二个参数开始往后,都是复制的源对象

    var nameObj = {name:'高佳睿'};
    var ageObj = {age:8};
    var obj = {};
    Object.assign(obj,nameObj,ageObj);
    console.log(obj);  // {name: "高佳睿", age: 8}
    
    //克隆对象
    function clone (obj) {
      return Object.assign({}, obj);
    }

    6.4 Object.setPrototypeOf

    将一个指定的对象的原型设置为另一个对象或者null

    var obj1  = {name:'高佳睿一号'};
    var obj2 =  {name:'高佳睿二号'};
    var obj = {};
    Object.setPrototypeOf(obj,obj1);
    console.log(obj.name);  //高佳睿一号
    console.log(Object.getPrototypeOf(obj));  //{name: "高佳睿一号"}
    Object.setPrototypeOf(obj,obj2); 
    console.log(obj.name);//高佳睿二号
    console.log(Object.getPrototypeOf(obj)) //{name: "高佳睿二号"}
    
    

    6.5 proto

    var obj1  = {name:'高佳睿'};
    var obj3 = {
        __proto__:obj1
    }
    console.log(obj3.name);  //高佳睿
    console.log(Object.getPrototypeOf(obj3));  //{name: "高佳睿"}

    直接在对象表达式中设置prototype

    6.6 super

    通过super可以调用prototype上的属性或方法

    let person ={
        eat(){
            return 'milk';
        }
    }
    let student = {
        __proto__:person,
        eat(){
            return super.eat()+' bread'
        }
    }
    console.log(student.eat());  //milk bread

    7. 类

    7.1 class

    使用class这个关键词定义一个类,基于这个类创建实例以后会自动执行constructor方法,此方法可以用来初始化

    class Person {
        constructor(name){
            this.name = name;
        }
        getName(){
            console.log(this.name);
        }
    }
    let person = new Person('zfpx');
    person.getName();
    

    7.2 get与set

    getter可以用来得获取属性,setter可以去设置属性

    class Person {
        constructor(){
            this.hobbies = [];
        }
        set hobby(hobby){
            this.hobbies.push(hobby);
        }
        get hobby(){
            return this.hobbies;
        }
    }
    let person = new Person();
    person.hobby = 'basketball';
    person.hobby = 'football';
    console.log(person.hobby);  //["basketball", "football"]

    7.3 静态方法-static

    在类里面添加静态的方法可以使用static这个关键词,静态方法就是不需要实例化类就能使用的方法

    class Person {
       static add(a,b){
           return a+b;
       }
    }
    console.log(Person.add(1,2));  //3

    7.4 继承extends

    一个类可以去继承其它的类里的东西

    class Person {
       constructor(name){
         this.name = name;
       }
    }
    class Teacher extends Person{
        constructor(name,age){
            super(name);
            this.age = age;
        }
    }
    var teacher = new Teacher('高佳睿',8);
    console.log(teacher.name,teacher.age);  //高佳睿 8

    8.生成器(Generator)与迭代器(Iterator)

    Generator是一个特殊的函数,执行它会返回一个Iterator对象。 通过遍历迭代器, Generator函数运行后会返回一个遍历器对象,而不是普通函数的返回值。

    8.1 Iterators模拟

    迭代器有一个next方法,每次执行的时候会返回一个对象 对象里面有两个属性,一个是value表示返回的值,还有就是布尔值done,表示是否迭代完成

    function buy(books) {
        let i = 0;
        return {
            next(){
                let done = i == books.length;
                let value = !done ? books[i++] : undefined;
                return {
                    value: value,
                    done: done
                }
            }
        }
    }
    
    let iterators = buy(['js', 'html']);
    var curr;
    do {
        curr = iterators.next();
        console.log(curr);
    } while (!curr.done);

    // {value: "js", done: false}
    // {value: "html", done: false}
    // {value: undefined, done: true}

    8.2 Generators

    生成器用于创建迭代器

    function* buy(books){
        for(var i=0;i<books.length;i++){
            yield books[i];
        }
    }
    let buying = buy(['js','html']);
    var curr;
    do {
        curr = buying.next();
        console.log(curr);
    } while (!curr.done);

    // {value: "js", done: false}
    // {value: "html", done: false}
    // {value: undefined, done: true}

    9.集合

    9.1 Set

    一个Set是一堆东西的集合,Set有点像数组,不过跟数组不一样的是,Set里面不能有重复的内容

    var books = new Set();
    books.add('js');
    books.add('js');//添加重复元素集合的元素个数不会改变
    books.add('html');
    books.forEach(function(book){//循环集合
        console.log(book);  // js html
    })
    console.log(books.size); // 2 集合中元数的个数 
    console.log(books.has('js'));// true 判断集合中是否有此元素
    books.delete('js');// 从集合中删除此元素
    console.log(books.size);  // 1
    console.log(books.has('js')); // false
    books.clear();//清空 set
    console.log(books.size);  //0

    9.2 Map

    可以使用 Map 来组织这种名值对的数据

    var books = new Map();
    books.set('js',{name:'js'});//向map中添加元素
    books.set('html',{name:'html'});
    console.log(books.size);// 2 查看集合中的元素
    console.log(books.get('js'));// {name: "js"} 通过key获取值
    books.delete('js');//执照key删除元素
    console.log(books.has('js'));// false 判断map中有没有key
    books.forEach((value, key) => { //forEach可以迭代map
        console.log( key + ' = ' + value);  //html = [object Object]
    });
    books.clear();//清空map

    10.模块

    可以根据应用的需求把代码分成不同的模块 每个模块里可以导出它需要让其它模块使用的东西 在其它模块里面可以导入这些模块导出的东西

    10.1 模块

    在浏览器中使用模块需要借助 导出

    export var name = 'zfpx';
    export var age = 8;

    导入

    //import {name,age} from './school.js';
    import * as school from './school.js';
    console.log(school.name,school.age);

    在页面中引用

    <script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script>
    <script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script>
    <script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script>
    <script type="module" src="index.js"></script>

    10.2 重命名

    导出时重命名

    function say(){
        console.log('say');
    }
    export {say as say2};

    导入时重命名

    import {say2 as say3} from './school.js';

    10.3 默认导出

    每个模块都可以有一个默认要导出的东西 导出

    export default function say(){
        console.log('say');
    }

    导入

    import say from './school.js';

    11 深度克隆

    var parent = {
      age: 5,
      hobby: [1, 2, 3],
      home: {city: '北京'},
    };
    
    var child = extendDeep(parent);
    child.age = 6;
    child.hobby.push('4');
    child.home.city = '广东';
    console.log('child ', child); //[1, 2, 3, 4]
    console.log('parent ', parent);
    function extend(parent) {
      let child;
      if (Object.prototype.toString.call(parent) == '[object Object]') {
        child = {};
        for (let key in parent) {
          child[key] = extend(parent[key])
        }
      } else if (Object.prototype.toString.call(parent) == '[object Array]') {
        child = parent.map(item => extend(item));
      } else {
        return parent;
      }
      return child;
    }
    
    function extendDeep(parent, child) {
      child = child || {};
      for (var key in parent) {
        if (typeof parent[key] === "object") {
          child[key] = (Object.prototype.toString.call(parent[key]) === "[object Array]") ? [] : {};
          extendDeep(parent[key], child[key]);
        } else {
          child[key] = parent[key];
        }
      }
      return child;
    }
  • 相关阅读:
    java中的subList
    值传递和引用传递
    java程序中有异常处理和没有异常处理的区别
    正则表达式
    poj 3187 三角数问题
    poj 2718 切数问题 穷竭搜索
    ACM 广度优化搜索算法总结
    poj 3669 火星撞地球问题 bfs算法
    poj 2251 三维地图最短路径问题 bfs算法
    ACM 深度优化搜索算法小总结
  • 原文地址:https://www.cnblogs.com/Scar007/p/8536893.html
Copyright © 2020-2023  润新知