zoukankan      html  css  js  c++  java
  • 简述ES6

    this指向
     
    this 是javascript的一个关键字
    它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用
    随着函数使用场合的不同,this的值会发生变化
    但是有一个总的原则,那就是this指的是函数的调用对象或事件的调用对象
    注意:找不到调用对象时this指向window对象
     
    改变匿名函数的this指向:function (){}.bind(函数体内this指向的对象)
    var obj = {name: '隔壁王叔叔',age: 33};
    setTimeout(function (){
        console.log(this);
    }.bind(obj),1000);
     
    改变非匿名函数的this指向:call、apply,如:函数.call(函数体内this指向的对象)
    var obj = {name: '隔壁王叔叔',age: 33};
    var arr = [1,2,3];
    arr.fn = function () {
        console.log(this);
    }
    arr.fn();
    arr.fn.call(obj);
    注意:关于call和apply,目前只需了解,后面的课程继续学习!
     
     
    ES6常用内容
     
    let与const
     
    let关键字,用来声明变量,它的用法类似于var。
     
    let不允许重复声明变量;
    var a = 1;
    var a = 2;
    console.log(a);
     
    let b = 1;
    let b = 2;
    console.log(b);
     
    let声明变量仅在块级作用域内有效;
    for (var i = 0; i < 10; i++) {
        console.log(i);
    };
    alert(i);
     
    for (let v = 0; v < 10; v++) {
        console.log(v);
    }
    alert(v);
     
    不能通过let声明和形参相同的变量;
    function test(a) {
        let a = 123;
        console.log(a);
    }
    test(456);
     
    let声明变量不会提升;
    alert(a); 
    var a = 2;
     
    alert(b); 
    let b = 2;
    注意:let声明的变量一定要在声明之后使用,否则报错。
     
    暂时性死区;
    ES6规定在某个区块中, 一旦用let或const声明一个变量,那么这个区块就变成块级作用域,用let或const声明的变量就“绑定”这个区域,不再受外部的影响。 在该变量声明之前不可以用,在语法上我们叫这种情况为:暂时性死区 (temporal dead zone,简称 TDZ)。
    var tmp = 123;
    if (true) {
        tmp = 'abc';
        let tmp;
    }
    上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。
     
    let应用:改造选项卡效果
     
     
    const关键字,用来声明一个只读的常量。
    const与let类似,但是,const常量一旦声明,常量将不能重新赋值!
    const AGE = 18;
    alert(AGE);
    AGE = 20;
    alert(AGE);
     
    意味着,const一旦声明,就必须立即初始化,不能留到以后赋值!
    const AGE;
     
    本质:const实际上保证的,并不是值不能改变,而是指向的那个内存地址不能改变。
    const FOO = {name: 'xm'};
    FOO.age = 18;
    console.log(FOO.age);
    FOO = {name: 'xh'};
     
    注意:为了和变量区分,一般常量用大写字母。
    如:const PI = 3.14;
     
    arrow functions(箭头函数)
     
    定义:( 形参 ) => { 函数体 }
    var box = document.getElementById('box');
    box.onclick = function () { // ES5
        console.log(this);
    }
    box.onclick = () => { // ES6
        console.log(this);
    }
     
    用箭头函数来写比原来的function写法要简洁很多(针对匿名函数使用)。
    var reflect = function (value){ //ES5
        return value;
    };
    let reflect = value => value; //ES6
     
    箭头函数与传统的JavaScript函数主要区别在于以下几点:
    1.对 this 的关联。函数内部的 this 指向,取决于箭头函数在哪定义,而非箭头函数的调用对象。
    var name = 'xh';
    var obj = {
        name: 'xm',
        say: () => {
            alert(this.name);
        }
    }
    obj.say();
     
    当我们使用箭头函数时,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,它的this是继承外面的,因此内部的this就是外层代码块的this。
    var box = document.getElementById('box');
    box.onclick = function () {
        setTimeout(() => {
            console.log(this);
        },2000);
    }
     
    2.new 不可用。箭头函数不能使用 new 关键字来实例化对象,不然会报错。
    var Test = function () {};
    var obj = new Test();
    console.log(obj);
     
    var Test = () => {};
    var obj = new Test(); //Test is not a constructor
     
    3.this 不可变。函数内部 this 不可变,在函数体内整个执行环境中为常量。
    var obj1 = {
        name: '隔壁王叔叔',
        age: 33
    }
    setTimeout(() => {
        console.log(this);
    }.bind(obj1),1000); //报错
     
    4.没有arguments对象。更不能通过arguments对象访问传入参数。
    function fn(){
        console.log(arguments[0]);
        console.log(arguments[1]);
    }
    fn(1,2);
     
    var fn = () => {
        console.log(arguments[0]); //报错
    }
    fn(3);
     
    template string((字符串模板)
     
    ES6中字符串模板使用反引号 ` ` 表示,字符串模板中可以解析变量和函数,使用 ${ } 解析
    var sname = "小错";
    function fnAge(){
        return 18;
    }
    var str = `大家好,我叫${sname},我今年${fnAge()}岁了`;
    alert( str );
     
    字符串模板非常有用,当我们要插入大段的html内容到文档中时,传统的写法非常麻烦
    var box = document.getElementById('box');
    var val1 = 11, val2 = 22, val3 = 33;
    box.innerHTML = '<ul><li>'+val1+'</li><li>'+val2+'</li><li>'+val3+'</li></ul>';
    box.innerHTML = '<ul>'+
                                    '<li>'+val1+'</li>'+
                                    '<li>'+val2+'</li>'+
                                    '<li>'+val3+'</li>'+
                                '</ul>';
     
    使用ES6字符串模板:
    box.innerHTML = `
        <ul>
            <li>${val1}</li>
            <li>${val2}</li>
            <li>${val3}</li>
        </ul>
    `;
     
    Destructuring(解构赋值)
     
    ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。
    解构赋值:解析解构进行赋值。
     
    var x = 10 , y = 20 , z = 30;
     
    var cat = 'ken';
    var dog = 'lili';
    var zoo = {cat: cat, dog: dog};
    console.log(zoo);
     
    用ES6完全可以像下面这么写:
     
    var [x,y,z] = [10,20,30];
    var {sname,age} = {age : 10, sname : "xm" }
    console.log( sname );
    console.log( age );
     
    let cat = 'ken';
    let dog = 'lili';
    let zoo = {cat, dog};
    console.log(zoo);
     
    反过来可以这么写:
    let dog = {type: 'animal', many: 2};
    let { type, many} = dog;
    console.log(type);
    console.log(many);
     
    解构赋值可以作用在函数的参数上,让函数参数的值传递顺序改变
    function fn( {sname,age} ){
    return `大家好我叫${sname},我今年${age}岁了`;
    }
    console.log( fn( {age:23,sname:"jack"} ) );
     
    Array.from( )
     
    Array.from:将含有length属性的对象、类数组转成真正的数组。
    Array.from(obj, map函数);
    第一个参数为要转换的对象,第二个参数为一个函数,可选,类似map函数。
    map函数 : 遍历数组--操作数组--返回数组
    var arr = [1,2,3,4,5];
    var newArr = arr.map( (item) => { return item*2 } );
    console.log( newArr );
     
    类数组元素集合:
    var lis = document.getElementsByTagName("li");
    console.log(lis);
    lis.push('abc');
    console.log(lis);
     
    将lis集合(类数组)转成 数组:
    lis = Array.from(lis);
    console.log( lis )
    lis.push('abc');
    console.log(lis);
     
    将对象转成 数组:
    var obj = {
        "0" : 10 ,
        "1" : 20 ,
        "2" : 30 ,
        "length" : 3
    };
    var arr = Array.from( obj );
    console.log( arr );
     
    第二个参数是一个匿名函数 实现的是map功能:
    var newArr = Array.from( obj , (item) => { return item*2; } )
    console.log( newArr );
     
    三个点(...)
     
    扩展运算符用三个点号表示,其功能是把数组或类数组对象展开成一系列用逗号隔开的参数序列。
    console.log(...[1, 2, 3]);
    console.log(1, ...[2, 3, 4], 5);
     
    var lis = document.getElementsByTagName("li");
    console.log([...lis]);
     
    其他用法:
    var arr1 = [1,2];
    var arr2 = [3,4,5];
    function addItems(arr, ...items) {
        arr.push(...items);
    };
    addItems(arr1,...arr2);
    console.log(arr1);
     
    arr.push(...items) 和 addItems(arr1,...arr2) 函数调用都使用了扩展运算符将数组变为参数序列
    注意这行:function addItems(arr, ...items) 这里的三个点并不是扩展运算符,而是 rest运算符
     
    rest运算符是三个点,其功能与扩展运算符恰好相反,把逗号隔开的参数序列组合成一个数组
     
    var arr = [1,2,3];
    function fn(...args) {// rest运算符 组合数组
    console.log(args);
    };
    fn(...arr);// 扩展运算符 展开数组
    console.log(...arr);
     
     
    Set 和 Map
     
    ES6 提供了两种新的数据结构 Set 和 Map。
     
    Set 是一个构造函数,用来生成 Set 数据结构,它类似于数组,但是成员的值都是唯一的、没有重复的, 初始化 Set 可以接受一个数组或类数组对象作为参数,也可以创建一个空的 Set:
    var s1 = new Set();
    var s2 = new Set([1, 2, 3]);
    console.log(s1);
    console.log(s2);
     
    在 Set 中成员的值是唯一的,重复的值自动被过滤掉
    var s1 = new Set([1, 2, 2, 3, 1, 4]);
    console.log(s1);
     
    Set 的一些属性方法:
    size:返回成员总数
    add(value):添加某个值,返回Set结构本身
    delete(value):删除某个值,返回一个布尔值,表示删除是否成功
    has(value):返回一个布尔值,表示该值是否为Set的成员
    clear():清除所有成员,没有返回值
     
    var set = new Set([1,2]);
    set.add(3);// 添加成员
    console.log(set.size);// 3 成员总数
    console.log(set);// Set(3) {1, 2, 3}
    set.add([4,5]);// 添加成员
    console.log(set.size);// 4 成员总数
    console.log(set.has(2));// true 有该成员
    console.log(set);// Set(4) {1, 2, 3, [4, 5]}
    set.delete(2);// 删除成员
    console.log(set);// Set(3) {1, 3, [4, 5]}
    console.log(set.has(2));// false 没有该成员
    set.clear();// 清除所有成员
    console.log(set);// Set(0) {}
     
    得益于数据结构 Set 查找更快速高效,但也因为数据结构的内部数据是无序的,无法实现按下标改查,排序等操作
    var arr = [1,2,3,'a',4,'b'];
    var set = new Set(arr);
    console.log(set[0]);// undefined
    console.log(set['a']);// undefined
     
    遍历 Set 对象
    var set = new Set(['a','b','c','d']);
    set.forEach((val,key,set)=>{
        console.log('val: '+val);
        console.log('key: '+key);
        console.log(set);
    });
     
    使用ES6的 for of 遍历
    var set = new Set(['a','b','c','d']);
    for (const val of set) {
        console.log(val);
    }
     
    Set 没有类似 get 的方法,怎么取值呢?
    可以用上面的遍历取值,或者可以把 Set 转成真正的数组!
     
     
    for/of 与 for/in 区别
    for/of:遍历值
    var arr = [4,5,6,7];
    for (var val of arr) {
        console.log(val);//4 5 6 7
    }
     
    for/in:遍历键
    var arr = [4,5,6,7];
    for (var key in arr) {
        console.log(key);//0 1 2 3
    }
     
     
    Map 是一个构造函数,用来生成 Map 数据结构,它类似于对象,也是键值对的集合,但是“键”可以是非字符串, 初始化 Map 需要一个二维数组,或者直接初始化一个空的 Map:
    var m1 = new Map();
    var m2 = new Map([['a', 123], ['b', 456], [3, 'abc']]);
    console.log(m1);
    console.log(m2);
     
    Map 的一些操作方法:
    set(key, value):设置键值对
    get(key):获取键对应的值
    has(key):是否存在某个键
    delete(key):删除某个键值对,返回一个布尔值,表示删除是否成功
     
    var map = new Map([['a', 123], ['b', 456], [3, 'abc']]);
    map.set('c',789);
    console.log(map.get('c')); // 789
    console.log(map.has('b')); // true 此key存在
    map.delete(3); // true 成功删除key
    console.log(map); // Map(3) {"a" => 123, "b" => 456, "c" => 789}
     
    遍历 Map 对象
    var map = new Map([['a', 123], ['b', 456], [3, 'abc'],['c', 789]]);
    map.forEach((val,key,obj)=>{
        console.log('val: '+val);
        console.log('key: '+key);
        console.log(obj);
    });
     
    当然也可以使用ES6的 for of 遍历
    var map = new Map([['a', 123], ['b', 456], [3, 'abc'],['c', 789]]);
    for (const [key,val] of map) {
        console.log(key+' : '+val);
    }
     
    传统 Object 只能用字符串作键,Object 结构提供了“字符串 — 值”的对应
    Map 结构提供了“值 — 值”的对应,是一种更完善的 Hash 结构实现
    如果你需要“键值对”的数据结构,Map 比 Object 更快速 更高效 更合适。
     
    Symbol类型
     
    ES5 的对象属性名都是字符串,这容易造成属性名的冲突。
    ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。
    Symbol 是 JavaScript 语言的第七种数据类型。
     
    let s = Symbol('xm');
    console.log( s );
    console.log( typeof s );
     
    对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。
    var xm = Symbol();
    var obj = {
        [xm] : "小明" //对象的属性是Symbol类型
    }
     
    Symbol类型的属性 取值是 必须 obj[xm] 不能用obj.xm
    console.log( obj[xm] );
     
    修改symbol类型的属性
    obj[xm] = "web前端";
    console.log( obj[xm] );
     
    Symbol可以用来保护对象的某个属性
    var obj = {
        "sname":"小明",
        "skill" : "web"
    }
    var age = Symbol();
    obj[age] = 18;
    console.log( obj );
    for( var key in obj ){
        console.log(key + " -> " + obj[key] );
    }
     
     
  • 相关阅读:
    疯狂学java的第32天
    疯狂学java的第31天
    疯狂学java的第30天
    疯狂学java的第29天
    疯狂学java的第28天
    javaSE_day14_抽象类
    javaSE_day13_继承、super、this
    JavaSE_day12_static关键字丶单列设计模式丶代码块
    JavaSE_day11_常用类(String类丶StringBuffer类丶StringBuilder类)
    JavaSE_day10_初识API丶常用类(Scanner丶Random丶ArrayList)
  • 原文地址:https://www.cnblogs.com/tangyuqi/p/11218581.html
Copyright © 2011-2022 走看看