1. var、let、const
- var:有变量提升,无块级作用域
- let:不能重复声明,有块级作用域
- const:不能重复声明,有块级作用域,声明时必须设置初始值,并且之后不能修改
image.png
这里再提一个dom id创建的全局变量问题 ↓↓↓↓
1710396573252.png
解释一下上面这张图的问题:
1. initCardMenu方法里面创建了一个局部变量cardMenuWin,mini.create()又创建了一个id为cardMenuWin的dom元素
2. 编码时,我以为cardMenuWin这个menu是一个全局对象,因为我一开始没有注意到 let,
于是我在rejectToPrev里面访问了cardMenuWin的属性curId
3. 现在问题来了,我没有访问到我预期的属性curId( 它的值是'举个例子'),但同时【没有任何报错】
4. 问题就在于!!没有!!报错!!而我的使用方法本身是有错的,它让我看不清我自己--哭泣
5. 现在,由于这个变量命名和dom id重名的问题,导致我的错误本应该在访问 cardMenuWin.curId 时就报
cardMenuWin is not defined 错误,现在我却看不到报错,只自己在那里疑惑怎么访问不到属性呢哈哈??
综上:DOM元素的id,会直接在window对象上创建一个同名的全局变量,我以为严格模式下就能禁止这种行为,我错了
自己命名变量的时候,不要有和dom id同名的习惯
2. 数据类型
- | 基本数据类型 | 引用数据类型 |
---|---|---|
- | String、Number、Boolean、null、undefined、Symbol、bigInt | Object |
- | 值存储在栈内存中 | 栈内存中存的指针,实际值存在堆内存中 |
- | - | - |
2.1 堆和栈的区别
- 栈为系统分配,获得的空间较小;堆为人为申请开辟,空间更大;
- 栈是连续的空间,而堆是不连续的空间
- 栈比堆运行速度快
2.2 null和undefined
- undefined ,字面意思是“未定义的值”,一般都来自于某个表达式最原始的状态值,不是人为操作的结果
- null 的字面意思是:空值 。一个对象被人为的重置为空对象
2.3 bigInt
2.4 Symbol
image.png
-
Object.keys()
只能获取到key
为String
类型并且enumerable
为true
的属性,获取Symbol
类型的key
要用Object.getOwnPropertySymbols()
image.png 创建私有属性或方法:防止被随意修改,或者属性直接被覆盖。↓↓↓
const init = Symbol('init');
const value = Symbol('value');
export class Test {
// 则Test实例既不能调用init方法,
// 也不能直接访问和修改value属性,只能通过setValue和getValue
[value] = 'default'
constructor() {
this[init]();
}
[init]() {
console.log('call by myself only');
}
setValue(v) {
this[value] = v;
}
getValue() {
return this[value];
}
}
-
当需要唯一值时:↓↓↓
image.png
3. for-of 可以用来迭代哪些对象
- 可迭代的对象,比如Array、arguments
- 用
const isIterable = obj => obj != null && typeof obj[Symbol.iterator] === 'function';
来判断对象是否可迭代
3.1 for-of 和 for-in的区别
- 不能用for-of迭代普通对象,比如
{ name: 'huhu' }
,因为普通对象的[Symbol.iterator]
是undefined - 日常开发就用for-of迭代数组,迭代出value,用for-in迭代普通对象,迭代出key
4. 类数组与数组
最本质的区别是:类数组是一个简单对象,和数组的原型关系不同,所以类数组无法调用数组的方法。要使用可以先Array.from(arrayLike)
转换成数组
简单对象.png
5. 箭头函数和普通函数的比较
- 箭头函数简化代码
- 箭头函数没有自己的this和arguments。this指向的是定义时外层函数的this指向,而且无法被call方法修改。没有arguments可以使用扩展运算符来获取参数列表
- 箭头函数不能用来做构造函数,因为没有this和原型prototype
6. Set/WeakSet/Map/WeakMap
- Set 是不重复的值的集合
- WeakSet 只能是对象的集合
- WeakSet 持弱引用: 如果一个变量引用一个对象,那这个对象不会被回收。但是如果这个对象的只剩下weakSet中在引用它,那么它会被当成垃圾回收。
- WeakSet不能被遍历:因为垃圾回收节点是不确定的,回收前后的weakSet可能是不同的
- Map 存放key-value结构的数据,跟对象的不同是:Map的key可以是任何类型,而对象的key只能是String或者Symbol
- WeakMap的key只能是对象类型
- WeakMap 持有的是每个key对象的“弱引用”
使用场景
WeakSet存放dom元素
-
在Vue3中的使用
① 做数据响应式时,proxyMap(WeakMap类型)存放原对象和它的代理对象:proxyMap = new WeakMap(); proxyMap.set(target, proxy)
② 为对象收集依赖时,将依赖收集到bucket(WeakMap类型)里:key为原对象,value是一个Map类型,它的key为对象的各属性名,value为Set类型,存属性对应的effect函数
image.png -
babel在编译class的私有属性时就使用了WeakMap,保存每个实例以及这个实例对应的私有属性值
image.png
7. js中的对象
image.png
8. 面向对象的3个特征
封装:隐藏实现细节,使得代码模块化
继承:扩展已经存在的类,目的:代码复用
多态:同类事物,调用相同接口时的表现不同
9. 数字每满千位加逗号
-
方法1
toLocaleString()
image.png 方法2:整数部分使用正则:
num.toString().replace(/(\d)(?=(\d{3})+$)/g, '$1,')
10. 如何能拿到匿名函数的引用?
arguments.callee
function test() {
console.log(arguments.callee === test) // true
}
11. 创建函数的几种方法
function foo() {} // 函数声明
const foo = function() {} // 函数表达式
const foo = () => {} // 箭头函数
const obj = {
foo() {} // 作为对象的方法
}
12. typeof 和 instanceof 区别
typeof 检查的是数据的基础类型
- 返回值为
string、number、boolean、undefined、object、symbol、bigInt、function
8种(跟js数据类型相比:少了null,多了funciton) typeof null // 'object'
instanceof 检测的是实例的原型链上是否包含某个构造函数的
prototype
- 返回的是一个布尔值
mycat instanceof Animal
用
typeof
检查值类型并不可靠
image
13. 数组扁平化除了用递归还能怎么做?
- 用
Array.prototype.flat
方法,入参表示层级,不传默认为1,不确定的层级传Infinity