原文:http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000


$(function(){
    test1();
    test2();
    test3();
    test4();
    test5();
    test6();
    test7();
    test8();
    test9();
    test10();
    test11();
    test12();
    test13()
});

function test1(){
    
    console.debug('**************************** test1 ****************************');
    
    var str = 'Hello, World';
    var arr1 = ['A', 'B', 'C'];
    var arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    // 把字符串全部变成大写,返回'HELLO, WORLD'
    console.debug(str.toUpperCase());
    
    // 把字符串全部变成小写,返回'hello, world'
    console.debug(str.toLowerCase());
    
    // 搜索指定字符串出现的位置,返回7
    console.debug(str.indexOf('World'));
    
    // 没有找到指定的子串,返回-1
    console.debug(str.indexOf('world'));
    
    // 从索引0开始到5(不包括5),返回'Hello'
    console.debug(str.substring(0, 5));
    
    // 从索引7开始到结束,返回'World'
    console.debug(str.substring(7));
    
    // 从索引0开始,到索引2结束,但不包括索引2,返回: ['A', 'B']
    console.debug(arr1.slice(0, 2));
    
    // 从索引1开始到结束,返回: ['B', 'C']
    console.debug(arr1.slice(1));
    
    // 如果不给slice()传递任何参数,它就会从头到尾截取所有元素。利用这一点,我们可以很容易地复制一个Array
    var arrCopy = arr1.slice();
    console.debug(arrCopy);
    
    // 数值型数组转化为String数组
    var _arr2 = arr2.map(String);
    console.debug(_arr2);
    console.debug(arr2);
}

function test2(){
    
    console.debug('**************************** test2 ****************************');
    
    var arr = ['A', 'B', 'C'];
    
    // push()向Array的末尾添加若干元素, 返回Array新的长度: 5, arr=['A', 'B', 'C', 'D', 'E']
    console.debug(arr.push('D', 'E'));
    console.debug('arr=[' + arr + ']');
    
    // pop()把Array的最后一个元素删除掉,返回被删掉的元素'E', arr=['A', 'B', 'C', 'D']
    console.debug(arr.pop());
    console.debug('arr=[' + arr + ']');
    
    // 连续pop 4次后,arr=[]
    arr.pop();
    arr.pop();
    arr.pop(); 
    arr.pop();
    console.debug('arr=[' + arr + ']');
    
    // 空数组继续pop不会报错,而是返回undefined,arr还是=[]
    console.debug(arr.pop());
    console.debug('arr=[' + arr + ']');
}

function test3(){
    
    console.debug('**************************** test3 ****************************');
    
    var arr = ['A', 'B', 'C'];
    
    // unshift()向Array的头部添加若干元素, 返回Array新的长度: 5, arr=[1, 2, 'A', 'B', 'C']
    console.debug(arr.unshift('1', '2'));
    console.debug('arr=[' + arr + ']');
    
    // shift()把Array的第一个元素删除掉,返回被删掉的元素1, arr=[2, 'A', 'B', 'C']
    console.debug(arr.shift());
    console.debug('arr=[' + arr + ']');
    
    // 连续shift 4次后,arr=[]
    arr.shift();
    arr.shift();
    arr.shift(); 
    arr.shift();
    console.debug('arr=[' + arr + ']');
    
    // 空数组继续shift不会报错,而是返回undefined,arr还是=[]
    console.debug(arr.shift());
    console.debug('arr=[' + arr + ']');
}

function test4(){
    
    console.debug('**************************** test4 ****************************');
    
    var arr1 = ['B', 'C', 'A'];
    var arr2 = ['one', 'two', 'three'];
    
    // 对当前Array进行排序,它会直接修改当前Array的元素位置,直接调用时,按照默认顺序排序, arr1=['A', 'B', 'C']
    arr1.sort()
    console.debug('arr1=[' + arr1 + ']');

    // 把整个Array的元素给掉个个,也就是反转,arr2=['three', 'two', 'one']
    arr2.reverse()
    console.debug('arr2=[' + arr2 + ']');
}

function test5(){
    
    console.debug('**************************** test5 ****************************');
    
    var arr = ['A', 'B', 'C'];
    
    // 把当前的Array和另一个Array连接起来,并返回一个新的Array,arr不变化
    var added = arr.concat([1, 2, 3]);
    console.debug('added=[' + added + ']');
    console.debug('arr=[' + arr + ']');

    // 把当前Array的每个元素都用指定的字符串连接起来,然后返回连接后的字符串,added不变化,如果Array的元素不是字符串,将自动转换为字符串后再连接
    var addedStr = added.join('-');
    console.debug(addedStr);
    console.debug('added=[' + added + ']');
}

function test6(){
    
    console.debug('**************************** test6 ****************************');
    
    var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
    
    // splice()方法是修改Array的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素
    // 从索引2开始删除3个元素,然后再添加两个元素. 返回删除的元素 ['Yahoo', 'AOL', 'Excite'], arr=['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
    var rel1 = arr.splice(2, 3, 'Google', 'Facebook');
    console.debug(rel1);
    console.debug(arr);
    
    // 只删除,不添加. 返回删除的元素['Google', 'Facebook'],arr=['Microsoft', 'Apple', 'Oracle']
    var rel2 = arr.splice(2, 2);
    console.debug(rel2);
    console.debug(arr);
    
    // 只添加,不删除. 返回[],因为没有删除任何元素,arr=['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
    var rel3 = arr.splice(2, 0, 'Google', 'Facebook');
    console.debug(rel3);
    console.debug(arr);
}

function test7(){
    
    console.debug('**************************** test7 ****************************');
    
    var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
    var obj = {
        name: 'Jack',
        age: 20,
        city: 'Beijing'
    };
    
    // for ... in循环,它可以把一个对象的所有属性依次循环出来
    for (var key in obj) {
        console.debug(key + '=' + obj[key]);
    }
    
    // 要过滤掉对象继承的属性,用hasOwnProperty()来实现
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            console.debug(key + '=' + obj[key]);
        }
    }
    
    // 由于Array也是对象,而它的每个元素的索引被视为对象的属性,因此,for ... in循环可以直接循环出Array的索引
    // 请注意for ... in对Array的循环得到的是String而不是Number
    for (var i in arr) {
        console.debug(i + '=' + arr[i]);
    }
}

function test8(){
    
    console.debug('**************************** test8 ****************************');
    
    // 创建一个空Map
    // Map是一个二维数组
    // Map是ES6标准新增的数据类型,请根据浏览器的支持情况决定是否要使用
    var _map1 = new Map();
    console.debug(_map1);
    
    // 添加新的key-value
    _map1.set('Adam', 67);
    _map1.set('Bob', 59);
    console.debug(_map1);
    
    // 是否存在key 'Adam': true
    console.debug(_map1.has('Adam'));
    
    // 获取指定key对应的value
    console.debug(_map1.get('Adam'));
    
    // 删除,获取一个不存在的key,返回undefined
    _map1.delete('Adam');
    console.debug(_map1.get('Adam'));
    
    
    // 由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉
    var _map2 = new Map();
    _map2.set('Adam', 67);
    _map2.set('Bob', 59);
    _map2.set('Adam', 88);
    console.debug(_map2);
}

function test9(){
    
    console.debug('**************************** test9 ****************************');
    
    var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
    var map = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
    
    // 遍历Array
    for (var x of arr) {
        console.debug(x);
    }
    
    console.debug('-------------------------');
    
    // 遍历Map
    for (var x of map) {
        console.debug(x[0] + '=' + x[1]);
    }
    
    console.debug('-------------------------');
    
    // element: 指向当前元素的值
    // index: 指向当前索引
    // array: 指向Array对象本身
    arr.forEach(function (element, index, array) {
        console.debug(element);
    });
    
    console.debug('-------------------------');
    
    map.forEach(function (value, key, map) {
        console.debug(key + '=' + value);
    });
}

function test10(){
    
    console.debug('**************************** test10 ****************************');
    
    var arr1 = [1, 3, 5, 7, 9];
    var arr2 = ['A', '', 'B', null, undefined, 'C', '  '];
    
    // 数组值求和
    var _sum = arr1.reduce(function (x, y) {
        return x + y;
    });
    console.debug(_sum);
    
    // 把数组变换成整数
    var _i = arr1.reduce(function (x, y) {
        return x * 10 + y;
    });
    console.debug(_i);
    
    // 过滤,把一个Array中的空字符串删掉
    var _f = arr2.filter(function (s) {
        return s && s.trim();
    });
    console.debug(_f);
}

function test11(){
    
    console.debug('**************************** test11 ****************************');
    
    var arr1 = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
    var arr2 = [6, 14, 9, 1, 5, 3];
    
    // STR-ASC
    arr1.sort(function (s1, s2) {
        x1 = s1.toUpperCase();
        x2 = s2.toUpperCase();
        if (x1 < x2) {
            return -1;
        }
        if (x1 > x2) {
            return 1;
        }
        return 0;
    });
    console.debug(arr1);
    
    // STR-DESC
    arr1.sort(function (s1, s2) {
        x1 = s1.toUpperCase();
        x2 = s2.toUpperCase();
        if (x1 < x2) {
            return 1;
        }
        if (x1 > x2) {
            return -1;
        }
        return 0;
    });
    console.debug(arr1);
    
    // INT-ASC
    arr2.sort(function (x, y) {
        if (x < y) {
            return -1;
        }
        if (x > y) {
            return 1;
        }
        return 0;
    });
    console.debug(arr2);
    
    // INT-DESC
    arr2.sort(function (x, y) {
        if (x < y) {
            return 1;
        }
        if (x > y) {
            return -1;
        }
        return 0;
    });
    console.debug(arr2);
}

function test12(){
    
    console.debug('**************************** test12 ****************************');
    
    // 箭头函数
    // 零个参数用 () 表示;
    var fun_1 = () => 10 * 10;
    console.debug(fun_1());
    
    // 一个参数可以省略 ();
    var fun_2 = x => x * x;
    console.debug(fun_2(10));
    
    // 多参数不能省略 ();
    var fun_3 = (x, y) => x * y;
    console.debug(fun_3(10, 10));
    
    // 箭头右侧实现部分如果多行,需要用大括号括起来,并return返回值
    var fun_4 = (x, y) => {
        if(x < 10) {
            return x + y;
        } else {
            return x * y;
        }
    }
    console.debug(fun_4(9, 10));
    console.debug(fun_4(10, 10));
}

function test13(){
    
    console.debug('**************************** test13 ****************************');
    
    // generator和函数不同的是,generator由function*定义(注意多出的*号),并且,除了return语句,还可以用yield返回多次。
    // next()方法会执行generator的代码,每次遇到yield x;就返回一个对象{value: x, done: true/false},然后“暂停”。
    // 返回的value就是yield的返回值,done表示这个generator是否已经执行结束了。
    // 如果done为true,则value就是return的返回值。
    function* foo(x) {
        yield x + 1;
        yield x + 2;
        return x + 3;
    }
    var fun_1 = foo(5);
    console.debug(fun_1.next());
    console.debug(fun_1.next());
    console.debug(fun_1.next());
    
    console.debug('-------------------------');
    
    // 如果没有return,最后一次执行也会返回done:false,还继续执行next()的话,则value才会返回undefined, done:true
    // 需要额外注意最后的return是否需要,如何处理
    function* fib(max) {
        var a = 0;
        var n = 1;
        while (n < max) {
            a += n;
            yield a;
            n ++;
        }
        // return a;
    }
    var fun_2 = fib(5);
    console.debug(fun_2.next());
    console.debug(fun_2.next());
    console.debug(fun_2.next());
    console.debug(fun_2.next());
    console.debug(fun_2.next());
    
    console.debug('-------------------------');
    
    // 循环generator每个value
    // 循环出的value都满足done:false
    for (var x of fib(5)) {
        console.debug(x); 
    }
}