本章目录
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);
});