zoukankan      html  css  js  c++  java
  • ES6(简)

      

    一、 let、const 和 var
    
    let和const只在当前块级作用域中有效
    const用来声明常量
    var是全局作用域有效的
    
    constants.js 模块
    export const A = 1;
    export const B = 3;
    export const C = 4;
    
    test1.js 模块
    import * as constants from './constants';
    console.log(constants.A); // 1
    console.log(constants.B); // 3
    
    test2.js 模块
    import {A, B} from './constants';
    console.log(A); // 1
    console.log(B); // 3
    
    全局对象的属性 (下面是等价的)
    window.a = 1
    var a = 1
    global.a = 1
    二、 解构赋值: ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)
    
    如: var [a, b, c] = [1, 2, 3];
        a = 1
        b = 2
        c = 3
        
        let [head, ...tail] = [1, 2, 3, 4];
        head // 1
        tail // [2, 3, 4]
    
        let [x, y, ...z] = ['a'];
        x // "a"
        y // undefined
        z // []
        
    
    如果等号的右边不是数组,那么就会报错
    // 报错
    let [foo] = 1;
    let [foo] = false;
    let [foo] = NaN;
    let [foo] = undefined;
    let [foo] = null;
    let [foo] = {};
    
    ES6内部使用严格相等运算符(===),判断一个位置是否有值。所以,如果一个数组的员不严格等于undefined,默认值是不会生效的
    var [x = 1] = [undefined];
    x // 1
    
    var [x = 1] = [null];
    x // null
    
    对象解构赋值中如果变量名与属性名不一致,必须写成下面这样
    下面真正被赋值的是baz
    var { foo: baz } = { foo: "aaa", bar: "bbb" };
    baz // "aaa"
    foo // error: foo is not defined  foo是模式
    
    let obj = { first: 'hello', last: 'world' };
    let { first: f, last: l } = obj;
    f // 'hello'
    l // 'world'
    
    解构赋值的规则是,只要等号右边的值不是对象,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错
    let { prop: x } = undefined; // TypeError
    let { prop: y } = null; // TypeError
    
    注: 模式不能带有圆括号
    三、字符串的扩展
    
    模板字符串, 用反引号标示普通字符串或者多行字符串, 使用反引号需要加反斜杠
    传统的写法
    $("#result").append(
    "There are <b>" + basket.count + "</b> " +
    "items in your basket, " +
    "<em>" + basket.onSale +
    "</em> are on sale!"
    );
    模板字符串写法
    $("#result").append(`
    There are <b>${basket.count}</b> items
    in your basket, <em>${basket.onSale}</em>
    are on sale!
    `);
    四、数组的扩展
    
    Array.from() 将类数组转换成数组
    Array.from('hello')
    // ['h', 'e', 'l', 'l', 'o']
    
    Array.of() 将一组值转换为数组
    Array.of(3, 11, 8) // [3,11,8]
    
    只有当参数个数不少于2个时,Array()才会返回由参数组成的新数组。参数个数只有一个时,实际上是指定数组的长度
    Array() // []
    Array(3) // [, , ,]
    Array(3, 11, 8) // [3, 11, 8]
    五、函数的扩展
    
    rest参数,获取函数多余的参数
    function add(...values) {
        
        let sum = 0;
        
        for (var val of values) {
            
            sum += val;
        }
        
        return sum;
    }
    add(2, 5, 3)  // 10
    
    扩展运算符(...), 将一个数据转为用逗号分隔的参数序列
    function add(x, y) {
    return x + y;
    }
    
    var numbers = [4, 38];
    add(...numbers) // 42
    
    替代数组的apply方法 : 由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了
    // ES5的写法
    function f(x, y, z) {
    // ...
    }
    var args = [0, 1, 2];
    f.apply(null, args);
    
    // ES6的写法
    function f(x, y, z) {
    // ...
    }
    var args = [0, 1, 2];
    f(...args);
    
    箭头函数都没有自己的this, this表示的是最外层的
    
    :: 双冒号左边是对象,右边是函数
    六、对象的扩展
    
    Object.is(,) 比较2个值是否严格相等,与(===)行为基本一致
    不同之处为:Object.is的 +0不等于-0, Nan等于自身
    
    Object.assign 用于对象的合并,同名后面的会覆盖前面  是浅拷贝,而不是深拷贝
    var obj1 = {a: {b: 1}};
    var obj2 = Object.assign({}, obj1);
    
    obj1.a.b = 2;
    obj2.a.b // 2
    七、二进制数组
    
    用ArrayBuffer对象、TypeArray视图和DataView视图操作JS的二进制数据, 直接操作内存数据
    
    ArrayBuffer与字符串的相互转换
    // ArrayBuffer转为字符串,参数为ArrayBuffer对象
    function ab2str(buf) {
    return String.fromCharCode.apply(null, new Uint16Array(buf));
    }
    
    // 字符串转为ArrayBuffer对象,参数为字符串
    function str2ab(str) {
    var buf = new ArrayBuffer(str.length * 2); // 每个字符占用2个字节
    var bufView = new Uint16Array(buf);
    for (var i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
    }
    return buf;
    }
    八、 Set和Map
    
    Set类似数组, 它的成员是唯一的,里面没有重复的值
    var set = new Set([1, 2, 3, 4, 4]
    set.add(5)
    [...set]
    // [1, 2, 3, 4, 5]
    
    var items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
    items.size // 5
    
    Set的遍历
    keys():返回一个键名的遍历器
    values():返回一个键值的遍历器
    entries():返回一个键值对的遍历器
    forEach():使用回调函数遍历每个成员
    let set = new Set(['red', 'green', 'blue']);
    
    for ( let item of set.keys() ){
    console.log(item);
    }
    // red
    // green
    // blue
    
    for ( let item of set.values() ){  // 可以省略values
    console.log(item);
    }
    // red
    // green
    // blue
    
    for ( let item of set.entries() ){
    console.log(item);
    }
    // ["red", "red"]
    // ["green", "green"]
    // ["blue", "blue"]
    
    数组的map和filter方法也可以用于Set了
    let set = new Set([1, 2, 3]);
    set = new Set([...set].map(x => x * 2));  // [...set].map映射新的结构
    // 上面的代码可用: new Set(Array.from(set, val => val * 2)) // Array.from映射新的结构
    // 返回Set结构:{2, 4, 6}
    
    let set = new Set([1, 2, 3, 4, 5]);
    set = new Set([...set].filter(x => (x % 2) == 0));
    // 返回Set结构:{2, 4}
    
    Set结构的实例的forEach方法,用于对每个成员执行某种操作,没有返回值
    let set = new Set([1, 2, 3]);
    set.forEach((value, key) => console.log(value * 2) )
    // 2
    // 4
    // 6
    
    JS的Object只把字符串当作键 字符串--值, 而Map不限于字符串作键可以是各种类型 值--var m = new Map();
    var o = {p: "Hello World"};
    
    m.set(o, "content")
    m.get(o) // "content"
    
    m.has(o) // true
    m.delete(o) // true
    m.has(o) // false
    
    Map结构转数组结构
    let map = new Map([
    [1, 'one'],
    [2, 'two'],
    [3, 'three'],
    ]);
    
    [...map.keys()]
    // [1, 2, 3]
    
    [...map.values()]
    // ['one', 'two', 'three']
    
    [...map.entries()]
    // [[1,'one'], [2, 'two'], [3, 'three']]
    
    [...map]
    // [[1,'one'], [2, 'two'], [3, 'three']]
    九、Iterator(遍历器): 为各种不同的数据结构提供统一的访问机制,任何部署Iterator接口的数据结构们都有遍历操作
    
    部署Iterator接口: 只有三类结构原生具有Iterator接口数组、类数组对象以及Set和Map
    一个对象如果要有可被for...of循环调用的Iterator接口,就必须在Symbol.iterator的属性上部署遍历器生成方法(原型链上的对象具有该方法也可)
    class RangeIterator {
    constructor(start, stop) {
    this.value = start;
    this.stop = stop;
    }
    
    [Symbol.iterator]() { return this; }
    
    next() {
        var value = this.value;
        if (value < this.stop) {
        this.value++;
        return {done: false, value: value};
        } else {
        return {done: true, value: undefined};
        }
    }
    }
    
    function range(start, stop) {
        return new RangeIterator(start, stop);
    }
    
    for (var value of range(0, 3)) {
        console.log(value);
    }
    
    Symbol.iterator方法的最简单实现
    var myIterable = {};
    
    myIterable[Symbol.iterator] = function* () {
        yield 1;
        yield 2;
        yield 3;
    };
    [...myIterable] // [1, 2, 3]
    
    // 或者采用下面的简洁写法
    
    let obj = {
        * [Symbol.iterator]() {
        yield 'hello';
        yield 'world';
    }
    };
    
    for (let x of obj) {
        console.log(x);
    }
    // hello
    // world
    
    for...of循环内部调用的是数据结构的Symbol.iterator方法, 是遍历所有数据结构的统一的方法
    for...of循环可以代替数组实例的forEach方法
    JavaScript原有的for...in循环,只能获得对象的键名,不能直接获取键值。ES6提供for...of循环,允许遍历获得键值
    十、 Generator 用来处理异步操作 返回遍历对象 调用next执行yield定义的下一条,返回出对象, 直到value为undefined, done的值为true function* helloWorldGenerator() { yield 'hello'; yield 'world'; return 'ending'; }
    
    var hw = helloWorldGenerator();
    hw.next(); // ()里面可以带参数
    
    利用Generator函数,可以在任意对象上部署iterator接口
    function* iterEntries(obj) {
    let keys = Object.keys(obj);
    for (let i=0; i < keys.length; i++) {
    let key = keys[i];
    yield [key, obj[key]];
    }
    }
    
    let myObj = { foo: 3, bar: 7 };
    
    for (let [key, value] of iterEntries(myObj)) {
    console.log(key, value);
    }
    
    // foo 3
    // bar 7
    十一、Promise 是异步编程的一种解决方案 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果  三种状态:Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败) var promise = new Promise(function(resolve, reject) { // ... some code
    
        if (// 异步操作成功){
        resolve(value);
        } else {
        reject(error);
        }
    });
    
    Promise实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数, 第二个函数参数是可选的
    promise.then(function(value) {
        // success
    }, function(value) {
        // failure
    });
    
    示例:
    function timeout(ms) {
        return new Promise((resolve, reject) => {
        setTimeout(resolve, ms, 'done');
        });
    }
    
    timeout(100).then((value) => {
        console.log(value);
    });
    
    Promise新建后就会立即执行,then方法是在当前脚本所有同步任务执行完成后再执行
    
    Promise对象实现Ajax操作示例:
    var getJSON = function(url) {
    var promise = new Promise(function(resolve, reject){
        var client = new XMLHttpRequest();
        client.open("GET", url);
        client.onreadystatechange = handler;
        client.responseType = "json";
        client.setRequestHeader("Accept", "application/json");
        client.send();
    
        function handler() {
        if ( this.readyState !== 4 ) {
        return;
        }
        if (this.status === 200) {
        resolve(this.response);
        } else {
        reject(new Error(this.statusText));
        }
    };
    });
    
    return promise;
    };
    
    getJSON("/posts.json").then(function(json) {
        console.log('Contents: ' + json);
    }, function(error) {
        console.error('出错了', error);
    });
    十二、 异步操作和Async(ES7)
    
    JS异步编程方法:
        回调函数
        事件监听
        发布/订阅
        Promise 对象
    
    async 函数的实现,就是将 Generator 函数和自动执行器,包装在一个函数里
    // 50毫秒后输出“hello world”
    function timeout(ms) {
        return new Promise((resolve) => {
            setTimeout(resolve, ms);
        });
    }
    
    async function asyncPrint(value, ms) {
        await timeout(ms);
        console.log(value)
    }
    
    asyncPrint('hello world', 50);
    
    Async的使用方式
    // 函数声明
    async function foo() {}
    
    // 函数表达式
    const foo = async function () {};
    
    // 对象的方法
    let obj = { async foo() {} }
    
    // 箭头函数
    const foo = async () => {};
    
    最好把await命令放在try...catch代码
    async function myFunction() {
        try {
            await somethingThatReturnsAPromise();
        } catch (err) {
            console.log(err);
        }
    }
    // 另一种写法
    async function myFunction() {
        await somethingThatReturnsAPromise().catch(err => {
            console.log(err);
        };
    }
    
    如果希望多个请求并发执行,可以使用Promise.all方法
    let [foo, bar] = await Promise.all([getFoo(), getBar()]);
    十三、 类: 类的数据类型就是函数,类本身就指向构造函数 //定义类 class Point {
    
        constructor(x, y) {
            this.x = x;
            this.y = y;
        }
    
        toString() {
            return '(' + this.x + ', ' + this.y + ')';
        }
    
    }
    
    向类添加多个方法
    class Point {
        constructor(){
        // ...
        }
    }
    
    Object.assign(Point.prototype, {
        toString(){},
        toValue(){}
    })
    
    Class之间可以通过extends关键字实现继承
    class Point {
        constructor(x, y) {
            this.x = x;
            this.y = y;
        }
    }
    
    class ColorPoint extends Point {
        constructor(x, y, color) {
            this.color = color; // ReferenceError
            super(x, y);
            this.color = color; // 正确
        }
    }
    
    子类的__proto__属性,表示构造函数的继承,总是指向父类
    子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性
    
    static调用静态方法(类似类方法), 父类的静态方法能被子类继承
    class Foo {
    static classMethod() {
    return 'hello';
    }
    }
    
    Foo.classMethod() // 'hello'
    
    var foo = new Foo();
    foo.classMethod()
    // TypeError: undefined is not a function
    十四、 Module
    
    export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能
    
    // export命令:
    // 写法一
    export var m = 1;
    // 写法二
    var m = 1;
    export {m};
    // 写法三
    var n = 1;
    export {n as m};
    
    // import命令:
    A、
    import {firstName, lastName, year} from './profile';
    function setName(element) {
        element.textContent = firstName + ' ' + lastName;
    }
    B、
    import * as circle from './circle';
    console.log('圆面积:' + circle.area(4));
    console.log('圆周长:' + circle.circumference(14));
    
    export default命令 : 一个模块只能有一个默认输出
    // export-default.js
    export default function () {
    console.log('foo');
    }
    // import-default.js:  import命令可以为该匿名函数指定任意名字 如: customName
    import customName from './export-default';
    customName(); // 'foo'
    欢迎加QQ群交流: iOS: 279096195 React Native: 482205185
  • 相关阅读:
    [原创] 腾讯RTX二次开发相关的一些注意事项
    小技巧:快速清除项目中的svn相关文件!
    用SQL实现的BASE64加密及解密函数(SQL2005以上有效)
    摄影基础知识
    优秀的WEB前端开发框架:Bootstrap!
    virtualbox 安装 mac os x lion 10.7实现全屏显示!
    按摩穴位治疗鼻炎
    实用技巧:利用Excel实现客户档案的统一管理
    写了个小游戏:怪兽岛之挖矿练习
    闲来无事,用javascript写了一个简单的轨迹动画
  • 原文地址:https://www.cnblogs.com/GeekStar/p/5362163.html
Copyright © 2011-2022 走看看