1. 数据类型
基本类型 null(值为空/逻辑上表示空指针) undefined(没有负值) number string boolean Symble(唯一不可变) bigInt(任意精度的整数)
引用类型 object array function
存储区别 基本类型:值存储在栈中,引用类型:栈中存储引用地址 对象存储在堆中
let a = 10; let b = a;
变量赋值相当于把值赋值了一份 修改 a不会影响b
let obj1 = { key: 'value' }; let obj2 = obj1;
把引用复制了一份 ,内存地址是一致的,指向同一个对象,会互相影响
区别:
存储
基本数据类型存储在栈中,大小固定且频繁使用
引用数据类型存储在堆内存中,栈中存储的是引用地址(大小不固定,变量存储的是引用地址)
赋值:
复制的是变量本身
复制的是引用(浅拷贝) 修改一个会影响其他
栈(内存分配效率高,自动分配)
堆(分配灵活,需要手动创建)
1-2.null undefined区别?
null == undefined// true
null 赋值为null // undefined 没有赋值
1-3. 为什么? typeof null //Object (二进制表示和对象相同 被认定为空指针)
1-4 区别?
typeof 判断基本类型
instanceof 检查引用类型 (某个对象是否是另一个对象的实例)
特殊情况:
typeof function(){} //function
typeof null //Object
1-5 typeof NaN 的结果?
typeof NaN //number(not a number)
NaN !== NaN
无法计算出结果 会返回NaN (0/0)
使用Number显示转换非数字的变量 Number("abc")
isNaN 和Number.isNaN的区别
isNaN 会进行类型转换(判断一个变量是否可以被解析为数字的时候使用)
Number.isNaN 只判断是否是NaN(更严格)
1-6 类型转换:
隐式转化 运算(- * / % <= >=)/判断==
两个操作数有一个是字符串 + 字符串拼接
1+ false //1
1+ true //2
对象数组会先转换为原始值
console.log([1, 2, 3] + [4, 5, 6]); // "1,2,34,5,6"
console.log({} + {}); // "[object Object][object Object]"
显示转换 Number() Boolean() String()
特殊 Number(null) //0 Number(undefined) // NaN 1
symbol 不能转换为数字会报错
Boolean() +0 -0 null undefined '' false NaN 为false 其余都为true
1-7 为什么要新增Bigint 数据类型
js 数据类型是基于双精度浮点数实现的,处理非常大的整数会出现精度问题
2. 判断数组
Array.isArray() //结果true/false
Object.prototype.toString.call() // [object Array]
[] instanceof Array // true
使用原型链进行 判断 ['a','b'].__proto__ == Array.prototype
Array.prototype.isPrototypeOf([]) // true
数组常用的方法:
操作方法:
增: push(末尾添加一个或多个)
unshift(开头添加一个或多个)
concat (不会更改原数组) 拼接数组
splice array.splice(start, deleteCount, item1, item2, ...) 改变原数组
删: pop (删除并返回最后一个数据)
shift(删除并返回第一个元素)
splice array.splice(start, deleteCount, item1, item2, ...)
slice() //两个参数 开始 结束(不包括) 截取 不改变原数组
改:
splice array.splice(start, deleteCount, item1, item2, ...)
查: indexOf 返回查到元素的索引,查不到返回-1
includes 包含某个元素 true
find 查找数组中符合条件的第一个元素,并返回该元素
arr.find(element => element % 2 === 0)
排序方法:reverse()
sort(比较函数)
转换方法: join() 默认“,” 拼接成字符
迭代方法: arr.some((item index arr) => {})
arr.every ((item index arr) => {})
arr.filter((item) => item > 2)
arr.forEach map
reduce 高阶函数 累加 乘 数组扁平化 数组去重 reduce((pre,cur,index,arr) =>{},(初始值)) for ... in ... 对象 for ... of ... 数组
类数组
Array.prototype.splice.call()
Array.form()
扩展运算符可以把具有迭代协议的类数组转换为数组
常见的类数组 arguments nodeList
为什么arguments 被定义为类数组
历史原因:之前没有数组的概念
性能原因:真正的数组开销比较大,类数组更高效的实现某些操作
3. 0.1 + 0.2 !== 0.3
二进制浮点数表示的 精度限制所以不相等
解决办法:1.误差范围:Number.EPSILON
2.保留小数 (0.1+0.2).toFixed(2) == 0.3
4. || 和 &&
|| 返回遇到的第一个真值,都为假返回最后一个结果
&& 返回第一个假值, 都为真返回最后一个结果
5. == 和 === Object.is()
== 先进行类型转换(隐式)在判断 (判断是否==null 的时候使用)
=== 类型不一致 返回false 类型相同,在判断值
Object.is() 与 === 基本一致
特殊
Object.is(+0,-0) false
Object.is(NaN,NaN) true
6. 包装类型(原始类型没有属性方法)
Number String Boolean 方法
let str = "hello";
let obj = new String(str); // 装箱
console.log(obj); // String { "hello" }
7. 深拷贝 浅拷贝
浅拷贝:复制对象的基本类型值,引用类型共享内存地址。
深拷贝:递归复制对象及其嵌套对象的所有属性值。
Object.assign() 对象浅拷贝 合并
扩展运算符 {...obj1,...obj2} 创建新对象
深拷贝
JSON.parse(JSON.stringify())
lodash cloneDeep()
额外的递归逻辑来实现
8. Map 和 Object
Map默认情况下不包含任何键 频繁增加删除的场景表现更好
const map = new Map()
map.set('key','value')
map.get('key')
map.size
map.delect('key)
Object
const obj = {
name:'lili',
age:18,
}
delete obj.age
Object.keys(obj).map((key) =>{
console.log(key,obj[key]);
})
9. 脚本延迟加载的方式
async(异步 脚本下载完成执行,不会等待html解析完 多个脚本执行顺序不确定) 使用场景:独立性较高的脚本 第三方代码统计,广告
defer(异步 html解析完成 后执行 多个脚本按照执行顺序) 需要操作DOM的脚本(依赖html的脚本)
动态创建脚本 动态创建script标签插入文档 (灵活性高)需要某种条件触发才执行脚本的场景
模块化加载工具 requireJs webpack 动态加载 (大型项目,解决代码拆分,按需加载的问题)
10. 对象
判断一个对像是否属于某个类
class Person{
constructor(name,age){
this.name = name
this.age = age
}
fullName(){
return `${this.name} ---- ${this.age}`
}
}
const p1 = new Person('zhangsan',18)
p1 instanceof Person
Person.prototype.isPrototypeOf(p1)
p1.__proto__ == Person.prototype
Object.isPrototypeOf(p1) == Person.prototype
p1.constructor == Person
11. 常见字符串操作
concat trim subString slice split(字符串转数组)toUppercase toLowerCase endsWith startsWith
length…

1409

被折叠的 条评论
为什么被折叠?



