JS基础

155 阅读8分钟

数组

1. concat() 连接数组,不改变原数组,返回一个新数组(字符串/数组适用)
let a = ['1','2']
let b = ['3','4']
console.log(a.concat(b)) //结果是['1','2','3','4']
2. join() 用指定分隔符连接数组元素,返回string
let a = ['hello','work','!']
console.log(a.join(.)) //结果是'hello.work.!'
// 不指定默认','
3. reverse() 颠倒数组元素顺序,改变原数组
let a = ['1','2']
let b = []
b = a.reverse()
console.log(a, b) //结果是['2','1'],['2','1']
4. slice() 截取指定索引之间(包括start,不包括end),不改变原数组,返回一个新数组(字符串/数组适用)
let a = ['1','2','3','4']
console.log(a.slice(2,4)) //结果是['3','4']
// 不填则默认到字符串最后;若出现 - ,则表示倒着数
5. sort() 数组排序,改变原数组
let a = [40, 100, 1, 5, 25, 10]
a.sort(function(a, b){ return a - b })
//升序,若降序return b - a
console.log(a) //结果是[1, 5, 10, 25, 40, 100]
6. toString() 把数组以逗号相连转为字符串
ler arr = [1, 2, 3, 4, 5]
console.log(arr.toString()) // '1,2,3,4,5'
7. Array.isArray() 鉴别数组,返回布尔类型
let arr = [1,2,3,4,5]
console.log(Array.isArray(arr)) //true
console.log(Array.isArray('123')) //false
8. push() pop() shift() unshift()改变原数组
  • push() 从后面添加元素,返回新数组的长度
  • pop() 从后面删除元素,返回被删除的元素
  • shift() 从前面删除元素,返回被删除的元素
  • unshift() 从前面添加元素,返回新数组的长度
9. splice() 删除数组中的元素,会对原数组进行修改,返回删掉的数组,改变原数组
let arr = [4, 6, 7, 8, 3, 46, 8]
let newArr = arr.splice(0, 2)
console.log(arr) // [7, 8, 3, 46, 8]
console.log(newArr) // [4, 6]
// 从一个索引开始,删除多少个元素
// 第三个参数可以往删除的地方添加元素,可以添加多个,使用逗号隔开即可
10. indexOf() 查找元素
let arr = ['orange', '2016', '2016'];
arr.indexOf('orange'); // 0
arr.indexOf('o'); // -1
arr.indexOf('2016'); // 1
arr.indexOf(2016); // -1
11. findIndex() 查找元素

方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。

let arr = [1, 2, 3];
arr.findIndex(item => item >= 2) // 1

遍历数组方法

1. filter过滤
let arr = [1500, 1200, 2000, 2100, 1800]
let newArr = arr.filter(e => e < 2000)
console.log(newArr) // [1500, 1200, 1800]
// return 为 true 则保留当前元素,false 不保留当前元素,无法改变 return 的值
2.forEachmap区别
let arr = [1500, 1200, 2000, 2100, 1800]
let newArr = arr.forEach(function (item, index, array) {
    return item
})
console.log(arr) // [1500, 1200, 2000, 2100, 1800]
console.log(newArr) // undifined


let newArr = arr.map(function (item, index, array) {
    return item + 1
})
console.log(arr) // [1500, 1200, 2000, 2100, 1800]
console.log(newArr) // [1501, 1201, 2001, 2101, 1801]

// 总结:1.map循环有返回值,forEach无返回值
//      2.map支持链式
//      3.map return 可以改变返回值
3.someevery的区别和用法
let ary = [12, 23, 24, 42, 9]
let res1 = ary.every(function (item, index, input) {
    return item > 10
})

let res2 = ary.some(function (item, index, input) {
    return item > 10
})

console.log('every的返回结果',res1) // false
console.log('some的返回结果',res2) // true
// 总结:
// 1.全部符合条件即为true
// 2.有符合条件即为true
4. reduce()接收一个函数作为累加器
//  array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
//- total             必需。初始值, 或者计算结束后的返回值。
//- currentValue      必需。当前元素
//- currentIndex      可选。当前元素的索引
//- arr               可选。当前元素所属的数组对象。
//- initialValue      可选。传递给函数的初始值
let arr = [1,2,3,4]
function getSum(total, num) {
    return total + num
}
console.log(arr.reduce(this.getSum)) // 10
5. find()返回函数内判断的数组的第一个元素的值
let age = ages.find(e => e >= 4)
console.log(age) // 10

字符串

1. slice()、substring()和substr() 有什么区别
  1. slice() 从start位置开始,截取到end位置,end取不到
  2. substring() 从start位置开始,截取到end位置,end取不到
  3. substr() 从start位置开始,截取length个字符 正数无区别
let str = 'hello world'
console.log(str.slice(3)) // 'lo world'
console.log(str.substring(3)) // 'lo world'
console.log(str.substr(3)) // 'lo world'

console.log(str.slice(3, 7)) // 'lo w'
console.log(str.substring(3, 7)) // 'lo w'
console.log(str.substr(3, 7)) // 'lo worl' 7是长度,从3开始截取长度7

负数区别

var str = 'hello world';
console.log(str.slice(-3)) // 'rld'
console.log(str.substring(-3)) // 'hello world' 为负,默认从0开始
console.log(str.substr(-3)) // 'rld'

console.log(str.slice(3, -4)) // 'lo w' 下标从3开始到-4(从后往前数4个)
console.log(str.substring(3, -4)) // 'hel'
console.log(str.substr(3, -4)) // ''(空字符串)
2. trim()去掉字符串的首尾的空格
let str = ' abcd '
console.log(str.trim()) // 'abcd'
3. toUpperCase()将小写转换成大写 toLowerCase()将大写转换成小写
4. indexOf()返回指定字符的位置 lastIndexOf()
let a = 'hello word'
console.log(a.indexOf('or', 3)) // 7 
// 匹配到第一个即返回,若无则返回-1,第二个参数可选,指定位置起搜索

let num = 2016;
num.indexOf(2);  //Uncaught TypeError: num.indexOf is not a function
// 不能找纯数字类型
5. split() 字符串分割成字符串数组
let str='How are you doing today?'
console.log(str.split(' ', 2)) // ['How', 'are']
// 第二个参数可选,指定返回的数组的最大长度
6. replace() 替换
let str='How are you doing today?'
console.log(str.replace('today', 'tomorrow')) // 'How are you doing tomorrow?'
// 仅替换第一次符合条件的字符

Number类型

0.1 + 0.2的结果不是 0.3

0.1 + 0.2的结果不是 0.3,而是 0.30000000000000004。这是因为0.1和0.2在转换成二进制后会无限循环,由于标准位数的限制后面多余的位数会被截掉,此时就已经出现了精度的损失,相加后因浮点数小数位的限制而截断的二进制数字在转换为十进制就会变成0000000000000004。所以BigInt就应运而生。

数值转换

JavaScript提供3个函数可以把非数值转换为数值:

  • Number()可以用于任何数据类型
  • parseInt()parseFloat()专门用于把字符串转换为数值
Number()

Number()函数的转换规则很多,这里直接引用红宝书里的描述:

如果是 Boolean 值,true 和 false 将分别被转换为 1 和 0。

如果是数字值,只是简单的传入和返回。

如果是 null 值,返回 0。 如果是 undefined,返回 NaN。

如果是字符串,遵循下列规则:

a、中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即"1" 会变成 1,"123"会变成 123,而"011"会变成 11(注意:前导的零被忽略了);

b、串中包含有效的浮点格式,如"1.1",则将其转换为对应的浮点数值(同样,也会忽 略前导零);

c、字符串中包含有效的十六进制格式,例如"0xf",则将其转换为相同大小的十进制整 数值;

d、字符串是空的(不包含任何字符),则将其转换为 0;如果字符串中包含除上述格式之外的字符,则将其转换为 NaN。

如果是对象,则调用对象的 valueOf()方法,然后依照前面的规则转换返回的值。如果转换 的结果是 NaN,则调用对象的 toString()方法,然后再次依照前面的规则转换返回的字符 串值。

var num1 = Number("Hello world!"); //NaN 
var num2 = Number(""); //0 
var num3 = Number("000011"); //11 
var num4 = Number(true); //1 
parseInt()

parseInt()函数在转换字符串时,更多的是看其是否符合数值模式。它会忽略字 符串前面的空格,直至找到第一个非空格字符。如果第一个字符不是数字字符或者负号,parseInt() 就会返回 NaN;也就是说,用 parseInt()转换空字符串会返回 NaNNumber()对空字符返回 0)。如 果第一个字符是数字字符,parseInt()会继续解析第二个字符,直到解析完所有后续字符或者遇到了 一个非数字字符。

var num1 = parseInt("1234blue"); // 1234 
var num2 = parseInt(""); // NaN 
var num3 = parseInt("0xA"); // 10(十六进制数)
var num4 = parseInt(22.5); // 22 
var num5 = parseInt("070"); // 56(八进制数)
var num6 = parseInt("70"); // 70(十进制数)
var num7 = parseInt("0xf"); // 15(十六进制数)

JS中数据类型的判断( typeof,instanceof,constructor,Object.prototype.toString.call()

typeof()

typeof 对于原始类型来说,除了 null 都可以显示正确的类型

console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object     []数组的数据类型在 typeof 中被解释为 object
console.log(typeof function(){});    // function
console.log(typeof {});              // object
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object     null 的数据类型被 typeof 解释为 object
instanceof

instanceof 可以正确的判断对象的类型,因为内部机制是通过判断对象的原型链中是不是能找到类型的 prototype。

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false  
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true    
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);
constructor
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true

这里有一个坑,如果我创建一个对象,更改它的原型,constructor就会变得不可靠了

function Fn(){};
 
Fn.prototype=new Array();
 
var f=new Fn();
 
console.log(f.constructor===Fn);    // false
console.log(f.constructor===Array); // true 

Object.prototype.toString.call()  

使用 Object 对象的原型方法 toString ,使用 call 进行狸猫换太子,借用Object的 toString 方法

var a = Object.prototype.toString;

console.log(a.call(2));             // [object Number]
console.log(a.call(true));          // [object Boolean]
console.log(a.call('str'));         // [object String]
console.log(a.call([]));            // [object Array]
console.log(a.call(function(){}));  // [object Function]
console.log(a.call({}));            // [object Object]
console.log(a.call(undefined));     // [object Undefined]
console.log(a.call(null));          // [object Null]