基础:Number、Math、正则表达式、json、循环遍历

216 阅读7分钟

一、数值

JS 内部,所有数字都是以 64位浮点数 形式存储,所以涉及小数的运算要注意,最大安全整数2^53 - 1

1. NaN

  • NaN 是 Number类型,不等于任何值、包括它本身
  • NaN 在布尔运算时被当作 false
  • isNaN 只对数值有效,并且也不准确,因为当输入的是字符串、数组等,也会返回 true
  • indexOf 认为NaN不等于自身

2. parseInt

parseInt 用于将字符串转为整数。一个个地转换,当遇到不能转为数字的字符,就不再进行下去,如果第一个字符都不能转为数字,则返回NaN。也就是说,parseInt 要么返回一个十进制整数,要么返回NaN

parseInt 的第 2 个参数,表示的是 第 1 个参数的进制,返回的是对应的十进制数。 第 2 个参数的范围只能在 [2, 36] 之间,否则返回 NaN。如果第 2 个参数是 0、undefined、null,则直接忽略、按十进制处理

parseInt('100', 2);  // 4
parseInt('100', null);  // 100

3. Number

Number 可以将任何类型的值转为数值。实例方法 toString() 用来将一个数值转为字符串形式。

4. 数值和字符串之间的转换

  • 字符串->数值:Number(转null为0,转undefined为NaN)、parseInt(转null和undefined都是NaN)、parseFloat。

  • 数值->字符串:String、toString。

二、数学 Math 对象的静态方法

  • Math.abs():绝对值
  • Math.max() 和 Math.min():参数必须是散列形式,不能是数组。
  • Math.floor() 和 Math.ceil():向下的整数、向上的整数。
  • Math.round():用于四舍五入。但注意对于 负数的0.5 也会舍去。
  • Math.pow(x, y):幂运算值。
  • Math.random():返回 [0, 1) 之间的一个伪随机数,左闭右开
// 如果想生成任意范围的随机数
Math.random() * (maxValue - minValue) + minValue

三、正则表达式

正则表达式是一种表达 字符串结构 的方法,常用来 按照给定模式 匹配文本。

// 斜杠表示开始和结束,第2个参数为修饰符
let regex = /xyz/i 

1. 正则实例对象的test

test 方法返回一个布尔值,表示当前模式是否能匹配参数字符串。如果正则表达式带有g修饰符,那么每次test的搜索都从上一次结束的位置开始。

/cat/.test('cats and dogs') // true

2. 相关的字符串实例方法

  1. match:匹配成功就返回一个数组,失败返回 null,并且匹配总是从字符串的第一个字符开始。
var s = 'abba';
s.match(/a/);  // ['a']
s.match(/a/g);  // ['a', 'a']
s.match(/x/);  // null
  1. search:返回第一个满足条件的匹配结果的位置索引,不匹配则返回 -1,没有必要加g修饰符。
'_x_x'.search(/x/);  // 1
  1. replace:接受两个参数,第 1 个参数的正则表达式,第 2 个参数是替换的内容。
var s = 'abba';
s.replace(/a/, 'x');  // xbba
s.replace(/a/g, 'x');  // xbbx

replace的第 2 个参数还可以是一个函数,将每一个匹配项替换为函数返回值。该函数可以有多个参数:

  • 第1个参数:匹配到的内容。
  • 第2个参数:匹配到的组匹配(有多少个组匹配,就有多少个对应的参数)。
  • 倒数第2个参数:匹配到的内容在整个字符串中的位置。
  • 倒数第1个参数:原字符串。
  1. split:参数可以是正则表达式。

3. 匹配规则

  • .:匹配除 回车\r、换行\n以外的所有字符。
  • $:字符串的结束位置。
  • |选择符:或关系,即cat|dog匹配catdog
  • []:只要匹配其中一个即可。
    • ^脱字符:[^xyz] 脱字符在第一个位置,表示除了内部的字符x, y, z,其他都可以匹配。
    • [^]:只有这个没有其他字符,表示匹配一切字符,包括换行符。
    • -连字符:对于连续范围的字符从简写形式,[a-z]连字符只有放在[]中才具备简写的功能。

4. 预定义模式

  • \d:匹配 0-9 之间的任一数字,相当于 [0-9]\D则相反,表示匹配0-9以外的字符。
  • \w:匹配所有的字母、数字和下划线,相当于[A-Za-z0-9_]\W也与之相反。

5. 重复类

  • {}{n}恰好重复n次,{n,}至少重复n次,{n, m}重复不少于n次,不多于m次。

6. 量词符

  • ?:某个模式出现0或1次。
  • *:某个模式出现0次或多次。
  • +:某个模式出现1次或多次。

7. 修饰符

  • g:全局匹配。
  • i:忽略大小写。

四、json

json 是一种数据交换格式,是和html、markdown一样的标记语言。每个 json 对象只能是一个值,可能是一个数组或对象,也可能是一个原始类型的值。

  1. 复合类型的值只有2种:数组或对象(狭义),不能是函数、Date等。
  2. 原始类型的值只有4种:字符串、数值(必须十进制表示,不能用NaN、Infinity、-Infinity)、布尔值、null(没有undefined)。
  3. 字符串必须双引号,对象的键名必须双引号
  4. 数组或对象的最后一个成员后面,不能加逗号。

1. JSON.stringify

用来将一个值转为 json 字符串

最外层会先包装成一个字符串,对内部的字符串或对象键名会用【双引号】

JSON.stringify('abc');    // '"abc"',字符串  
JSON.stringify(12);    // '12',数值
JSON.stringify(true);    // 'true',布尔值
JSON.stringify(null);    // 'null'
JSON.stringify([1, true, 'a']);  // '[1, true, "a"]',数组
JSON.stringify({a: 4, b: 5});   // '{"a": 4, "b": 5}', 对象

如果对象的属性是undefined、函数,则会被JSON.stringify过滤。
如果数组的属性是undefined、函数,则会被转成 nullJSON.stringify({a:undefined, b: function f(){}})   // '{}'

JSON.stringify()的第 2 个参数(可选)可以是一个(1)数组,指定参数对象的哪些属性需要转成字符串,对数组无效。(2)也可以是一个函数,用来更改JSON.stringify()的返回值。

var obj = {
  'prop1': 'value1',
  'prop2': 'value2',
  'prop3': 'value3'
};
JSON.stringify(obj, ['prop1', 'prop2'])
// '{"prop1":"value1","prop2":"value2"}'
function f(key, value) {
  if (typeof value === "number")  value = 2 * value;
  return value;
}
JSON.stringify({ a: 1, b: 2 }, f)
// '{"a": 2,"b": 4}'

JSON.stringify()的第 3 个参数(可选),用来增加返回的JSON字符串的可读性。

// 分行输出
JSON.stringify({ p1: 1, p2: 2 }, null, '\t')

2. JSON.parse

将 json 字符串转换成对应的值。

五、循环遍历的多种方式

1. for

常用于数组,可以随时中断。

2. for in:适合对象

for in 用于遍历对象的全部属性

  • 遍历的是可遍历的属性,会跳过不可遍历的属性
  • 不仅遍历自身属性,还会遍历继承的属性(和原型链有关)。这时可以结合 hasOwnProperty 判断一下某属性是否为对象自身的属性。
const obj = { foo: 'hello' };
for (let key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key);
    console.log(obj[key]);
  }
}
// 'foo'  'hello'

3. Object.keys():适合对象

返回了一个自身可枚举属性组成的数组

let obj = {
    a:1,
    b:2
}
for (let i of Object.keys(obj)) {  // for..of,for..in均可
    console.log(i);
}
// a b

4. for of(ES6)

任何数据结构只要部署了 Symbol.iterator 属性,就可以用 for of 遍历。适用于:

  • 数组、字符串
  • Set、Map
  • 类数组对象:arguments 对象
  • Generator 对象

注意:不能用于对象!

数组:遍历键值。
let arr = ['a', 'b', 'c'];
for (let item of arr) {
    console.log(item);
}
// a b c
Set:遍历键值。
let set = new Set(['a', 'b', 'c']);
for (let item of set) {
    console.log(item);
}
// a b c
Map:都遍历。
let map = new Map([
    ['a', 1],
    ['b', 2]
]);
for (let [key, value] of map) {
    console.log(key);
}
// a b

4. forEach、map、reduce、filter

  • map、filter 返回的一个数组,reduce 返回的是一个累积值,forEach 没有返回值。
  • forEach、map、filter 都无法中断执行,breakcontinue会报错!

5. for..in和for..of的区别:适用对象

  • for..of能够遍历可迭代对象,不能用于普通对象。遍历数组时,遍历是键值。
  • for..in能够遍历对象的可枚举属性。遍历对象时,遍历的是键名。

总结

  • 数组: for 和 for of 都能用,优先使用 for。
  • 对象:for in + hasOwnProperty、Object.keys()。