美文网首页
JavaScript 补缺补漏(一)

JavaScript 补缺补漏(一)

作者: 唐大树 | 来源:发表于2019-10-24 08:37 被阅读0次

    本章目录

    1. JavaScript在设计时,有两种比较运算符,推荐 ===:

    2. ES6标准新增了一种多行字符串的表示方法,用反引号 表示。

    3. ES6新增了一种模板字符串,反引号内直接引入变量

    4. String 字符串 indexOf()会搜索指定字符串出现的位置

    5. Array的“万能方法”

    6. JavaScript的对象是什么?

    7. JavaScript把null、undefined、0、NaN和空字符串''视为false,其他值一概视为true

    8. for循环的 break;  for ...in 循环对象

    9. 为什么使用map  和 set 

    10. for ... in   和 for ...of 的使用区别 + forEach()

    --------------分割线-----------------

    1. JavaScript在设计时,有两种比较运算符:

    第一种是==比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;

    第二种是===比较,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较。

    由于JavaScript这个设计缺陷,不要使用==比较

    始终坚持使用    ===    比较

    2. ES6标准新增了一种多行字符串的表示方法,用反引号 表示。

    如果浏览器不支持ES6,将报SyntaxError错误: 如果不支持,请把多行字符串用\n重新表示出来

    `这是一个

    多行

    字符串`;

    3. ES6新增了一种模板字符串,反引号内直接引入变量

    var name ='小明'; var age =20; var message ='你好, '+ name +', 你今年'+ age +'岁了!';

    var template = `你好,${name} , 你今年 ${age} 岁了`;    

    4. String 字符串 indexOf()会搜索指定字符串出现的位置

    用于查找判断是否包含具体字段

    vars ='hello, world';

    s.indexOf('world');    // 返回7

    s.indexOf('World');    // 没有找到指定的子串,返回    -1    

    5. Array的“万能方法”

    它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素:

    array.indexOf()  返回元素下标或者-1,一组数组中通过indexOf查找某个元素的具体位置,或者判断数组是否包含某个元素

    var arr = [10, 20, '30', 'xyz'];     

    arr.indexOf(30); // 元素30没有找到,返回-1

    arr.indexOf('30'); // 元素'30'的索引为2

    slice()就是对应String的substring()版本,它截取Array的部分元素,然后返回一个新的Array

    push()    pop()    unshift()    shift()    concat()    indexOf()    join()    some()    filter()    forEach()    every()    sort()    reverse()    reduce()    reduceRight()    map()      toString()数组转为字符串

    Array.reduce()    https://blog.csdn.net/zhendong9860/article/details/74908062

    假如现在有个需求:我们的产品经理想要所有users的名字拼成字符串,每人的全称后需要跟一个换行(可能是写到md文件或者什么东西,谁知道呢)

    /* 原始写法 */

    let everyonesName = '';

    users.forEach(user => {

        everyonesName += `${user.firstName} ${user.lastName}\n`;

    });

    /*  优化后的写法  */

    const everyonesName = users.map(

        user => `${user.firstName} ${user.lastName}\n`

    ).join('');

    /*  使用reducer后最好的写法  */

    const everyonesName = users.reduce(

        (acc, user)=> `${acc}${user.firstName} ${user.lastName}\n`,

        ''

    );

    Array.filter()    返回一个新数组,但不会改变原数组。它用于把Array的某些元素过滤掉,然后返回剩下的元素。(注意使用filter可以有效实现数组去重)

    filter 接收的回调函数,其实可以有多个参数。通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身:

    var ages = [32, 33, 16, 40];    const a = ages.filter(item => item > 32);  // [33, 40]

    let arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];

    let r = arr.filter(function (element, index, self) {

        return self.indexOf(element) === index;

    });

    如果是用ES6 set 一行代码就够了

    [...new Set(arr)]     

    Array.map()    mapping(映射)一个数组每项到函数,然后得到一个新的数组,在react中常用于渲染列表 

    var array = [1, 2, 3, 4, 5];

    // map方法第一个参数 为回调函数,该函数拥有三个参数

    // 第一个参数表示array数组中的每一个

    // 第二参数表示当前遍历的索引值

    // 第三个参数表示数组

    // 该函数中的this指向map方法的第二个参数,若该参数不存在,则this指向丢失

    var newArray = array.map((item, i, array)=>{

    console.log(item, i, array, this);

    return item + 1;

    }, {a: 1})

    Array.slice(0, 1)   截取数组中某一段,返回一个新数组

    var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];

    arr.slice(0, 3);    //  从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C']

    var str = 'abcdefg';

    str.substring(0, 3);    // 'abc'

    Array.splice(index, n, n )    删除 、替换数组元素

    var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];

    // 从索引2开始删除3个元素,然后再添加两个元素:

    arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']

    arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']

    // 只删除,不添加:

    arr.splice(2, 2); // ['Google', 'Facebook']

    arr; // ['Microsoft', 'Apple', 'Oracle']

    // 只添加,不删除:

    arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素

    arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']

    6. JavaScript的对象是什么?

    它是一种无序的集合数据类型,它由若干键值对组成。

    JavaScript的对象用于描述现实世界中的某个对象

    由于JavaScript的对象是动态类型,你可以自由地给一个对象添加或删除属性

    var xiaoming = {

        name: '小明',

        birth: 1990,

        school: 'No.1 Middle School',

        height: 1.70,

        weight: 65,

        score: null

    };

    xiaoming.age;        // undefined 

    JavaScript规定,访问不存在的属性不报错,而是返回undefined

    'name' in xiaoming;     // true     

    如果我们要检测xiaoming是否拥有某一属性,可以用in操作符

    'toString' in xiaoming;    //true  

    不过要小心,如果in判断一个属性存在,这个属性不一定是xiaoming的,它可能是xiaoming继承得到的  。因为toString定义在object对象中,而所有对象最终都会在原型链上指向object,所以xiaoming也拥有toString属性。

    xiaoming.hasOwnProperty('name');//true

    xiaoming.hasOwnProperty('toString');//false

    要判断一个属性是否是xiaoming自身拥有的,而不是继承得到的,可以用hasOwnProperty()方法

    delete    xiaoming.age;     

    // 删除一个不存在的school属性也不会报错

    7. JavaScript把null、undefined、0、NaN和空字符串''视为false,其他值一概视为true

    8. for循环的 break;  for ...in 循环对象

    for循环的3个条件都是可以省略的,如果没有退出循环的判断条件,就必须使用break语句退出循环,否则就是死循环:

    for循环的一个变体是for ... in循环,它可以把一个对象的所有属性依次循环出来:要过滤掉对象继承的属性,用hasOwnProperty()来实现

    在编写循环代码时,务必小心编写初始条件和判断条件,尤其是边界值。特别注意i < 100和i <= 100是不同的判断逻辑

    var o = {

        name: 'Jack',

        age: 20,

        city: 'Beijing'

    };

    for (var key in o) {

        if (o.hasOwnProperty(key)) {

            console.log(key); // 'name', 'age', 'city'

        }

    }

    请注意,for ... in对Array的循环得到的是String而不是Number

    var a = ['A', 'B', 'C'];

    for (var i in a) {

        console.log(i); // '0', '1', '2'

        console.log(a[i]); // 'A', 'B', 'C'

    }

    9. 为什么使用map  和 set 

    1.javascript 对象的键必须是一个字符串,这是一个设计上缺陷。Map是一组键值对的结构,具有极快的查找速度,同时键可以使任意的。

    举个例子,假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Array。给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,Array越长,耗时越长。

    var names = ['Michael', 'Bob', 'Tracy'];

    var scores = [95, 75, 85];

    如果用Map实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。

    var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);

    m.get('Michael'); // 95

    初始化Map需要一个二维数组,或者直接初始化一个空Map

    var m = new Map(); // 空Map

    m.set('Adam', 67); // 添加新的key-value

    m.set('Bob', 59);

    m.has('Adam'); // 是否存在key 'Adam': true

    m.get('Adam'); // 67

    m.delete('Adam'); // 删除key 'Adam'

    m.get('Adam'); // undefined

    由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉

    Set和Map类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。

    要创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set

    var s1 = new Set(); // 空Set

    var s2 = new Set([1, 2, 3]); // 含1, 2, 3

    重复元素在Set中自动被过滤:

    var s = new Set([1, 2, 3, 3, '3']);

    s; // Set {1, 2, 3, "3"}

    注意数字3和字符串'3'是不同的元素。

    10. for ... in   和 for ...of 的使用区别 + forEach()

    遍历Array可以采用下标循环,遍历Map和Set就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型。

    具有iterable类型的集合可以通过新的for ... of循环来遍历。

    for ... in循环由于历史遗留问题,它遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。

    当我们手动给Array对象添加了额外的属性后,for ... in循环将带来意想不到的意外效果:

    for ... in循环将把name包括在内,但Array的length属性却不包括在内。

    var a = ['A', 'B', 'C'];

    a.name = 'Hello';

    for (var x in a) {

        console.log(x);     // '0', '1', '2', 'name'   循环的属性包括外部添加的

    }

    console.log(a.length);  // 3  

    for ... of循环则完全修复了这些问题,它只循环集合本身的元素

    var a = ['A', 'B', 'C'];

    a.name = 'Hello';

    for (var x of a) {

        console.log(x); // 'A', 'B', 'C'    数组以为添加的属性不在循环内,只循环原始数组

    }

    console.log(a.length)

    iterable内置的forEach方法,它接收一个函数,每次迭代就自动回调该函数。【推荐使用】

    var a = ['A', 'B', 'C'];

    a.forEach(function (element, index, array) {

        // element: 指向当前元素的值

        // index: 指向当前索引

        // array: 指向Array对象本身

        console.log(element + ', index = ' + index);

    });

    var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);

    m.forEach(function (value, key, map) {

        console.log(value, key, ...map);

    });

    相关文章

      网友评论

          本文标题:JavaScript 补缺补漏(一)

          本文链接:https://www.haomeiwen.com/subject/ysyfvctx.html