JavaScript 补缺补漏(一)

2019-10-24  本文已影响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);

});

上一篇下一篇

猜你喜欢

热点阅读