1、ECMAScript-262核心规范及v8运行机制
- js中9大数据类型以及堆栈内存
- EC/VO/GO/scope/scope-chain等规范机制
- GC垃圾回收、内存泄漏及闭包作用域机制
- ES6混合模式下的v8词法分析和变量提升机制
- 函数设计规范:普通函数、构造函数、箭头函数、生成器函数、静态对象
- 面向对象OOP的底层设计原则:prototype/_ proto _
- v8渲染页面的全套机制及DOM性能优化
- 同步异步编程及EventLoop事件循环机制
- 事件对象/事件传播/事件代理等处理机制
- js中的this处理五大原则
1.1数据类型
- 原始值类型(值类型/基本数据类型)
- number 数字 1、2、0、1.2 Infinity(无限值 -Infinity) NaN(不是一个数,是number类型) NaN === NaN ->false Object.is(NaN,NaN)->true 检测是否未有效数字的方法
if (Object.is(num,NaN)) {
// num就是NaN num不是有效数字
}
// 浏览器提供的内置方法isNaN 是有效数字返回false 否则返回true 项目里主要使用这种方式
if (isNaN(num)) {
// 先将num隐式转为number类型然后判断是不是NaN
}
-
string 字符串 '' "" es6``模版字符串
-
boolean 布尔 true false
-
null 空对象指针
-
undefined 未定义
-
symbol 唯一值 只能是个函数,不能当作构造函数 所以不能new
Symbol() === Symbol() -->false
Symbol('A') === Symbol('A') -->false
作用1:可以给对象设置唯一值类型的属性---对象的属性类型:string、symbol
let a = [10,20];
// 如果想访问到obj中Symbol类型的key的值
let sym = Symbol('BB')
let obj = {
name: 'lele',
age: 26,
0: 100,
// 特殊类型数据作为key 需要用[]包起来
[{xxx: 'xxx'}]: 200, // "[object object]": 200
// a 的数值[10,20]作为key
[a]: 300, // '10,20': 300
[Symbol('AA')]: 400,
[sym]: 500
};
console.log(obj['name']) // lele
console.log(obj['age']) // 26
console.log(obj[0]) // 100
console.log(obj['0']) // 100
console.log(obj[Symbol('AA')]) // undefined
console.log(obj[sym]) // 500
// 迭代
for (let key in obj) {
// for in 循环是无法迭代symbol 类型的私有属性
console.log(key);
}
// 获取非symbol类型的私有属性 返回一个数组
let keys = Object.keys(obj)
// 获取symbol类型的私有属性 返回一个数组
let symKeys = Object.getOwnPropertySymbols(obj)
keys = keys.concat(symKeys);
// 第二种方法通过es6的Reflect.ownKeys获取所有的私有属性
let keys = Reflect.ownKeys(obj)
作用2:把Symbol作为对象,提供的很多静态属性方法,是js很多的知识的底层实现原理 Symbol.toPrimitive/hasInstance/toString/interator/asyncIterator..... 作用3:vuex/redux中我们需要派发很多行为标识,我们可以把这些行为标识统一管理,为了行为保证标识的唯一性,所以可以基于symbol进行管理
- bigint 大数 Number.MAX_SAFE_INTETGER 最大安全数字 9007199254740991 超过这个数字进行运算,运算结果不一定准确
- 对象类型(引用数据类型)
- 标准普通对象 object
- 标准特殊对象 Array、RegExp、Date、Math、Error.......
- 非标准特殊对象 Number、String、Boolean......
- 可调用/执行对象 函数 function
1.2数据类型检测
数据类型的检测方式
- typeof [value] 返回值是字符串,字符串中包含所属的类型 typeof 检测对象类型,除函数被识别为'function',其余都是'object',不能细分对象,检测未被声明的变量不会报错,typeof xxx 结果是'undefined',为啥会这样呢???
@1 js中创建的所有类型值,在计算机底层都是按照二进制形式进行存储的
@2 typeof检测也是根据二进制值进行检查,其中有一条规则:如果以‘000’开始的二进制,则被识别为对象(null存储的二进制值都是0,符合以000开始);然后再去看对象是否实现了[[call]],实现了则为函数返回‘function',没有实现就返回‘object';因为按照二进制值进行检测速度更快
- 000 对象
- 1 整数
- 010 浮点数
- 100 字符串
- 110 布尔
- 000000 null
- -2^30 undefined
- typeof typeof typeof [1,2,3] --->'string'
- typeof 12 --->'number'
- typeof 'lele' --->'string'
- typeof true --->'boolean'
- typeof null --->'object'
- typeof undefined --->'undefined'
- typeof Symbol() ---> 'symbol'
- typeof 10n ---> 'bigint'
- typeof [] ---> 'object'
- typeof {} ---> 'object'
- typeof /^$/ ---> 'object'
- typeof function(){} ---> 'function'
// 检测是否为对象
// 方案一
if (value !== null && typeof value === 'object' || typeof value === 'function') {}
// 方案二
if (value !== null && /^(object | function)$/i.test(typeof value)) {}
- Object.prototype.toString.call([value])
- [value].instanceof [Constructor]
- [vlaue].constructor
- Array.isArray([value])
- isNaN([value])
1.3数据类型转换
- 隐式转换:一般用于浏览器的隐式转换中 Number()先转为数字
- 数学运算 10 - '2' = 8
- isNaN检测
- == 比较
- 规则:
- 字符串转为数字:空字符串变为0,如果出现非有效数字字符,结果都是NaN Number('') === 0, Number('10') === 10, Number('10px') === NaN
- 布尔转为数字: Number(true) === 1, Number(false) === 0
- null是0,undefined是NaN Number(null) === 0, Number(undefined) === NaN
- Symbol无法转为数字
- 对象转数字:
- 先调用对象的Symbol.toPrimitive('number') 这个方法,如果这个方法不存在
// 标准普通对象
let time = new Date(); 日期对象
dir(time)
time[Symbol.toPrimitive]('number') 时间戳
// 数组
let arr = [10]
arr[Symbol.toPrimitive]-------->undefined
arr.valueOf()------->[10]
arr.toString()------>'10'
Number(arr)----->10
- 调用对象的valueOf() 获取原始值,如果获取的不是原始值
- 调用对象的toString() 变成字符串
- 最后把字符串基于Number方法转为数字
- parseInt(val,radix) 1、val必须是字符串,如果不是,要先隐式转换为字符串 String(val)
2、radix 进制:如果不写,或者为0,默认是10(如果字符串是以0x开始的,默认值是16)
3、有效范围:2-36之间
4、从val左侧第一个字符开始查找,查找出符合radix进制的值(如果遇到不符合的则结束查找,不论后面是否还有符合的),把找到的内容,按照radix进制,转换为10进制
5、parseInt(val,10)严谨写法,否则会出现异常情况
console.log(parseInt('10102px13',2)); //10
//找到符合二进制的'1010'
//把这个二进制的值转换为10进制“按权展开求和”
//1*2^3+0*2^2+1*2^1+0*2^0 === 10
console.log(parseInt(27.2,0)); //27
console.log(parseInt(27.2,1)); //NaN 第二个参数需要2-36之间
- 其它类型转布尔
除了0/NaN/空字符串/null/undefined是false,其余都是true
![] === false
!! [] === true 两个叹号相当于Boolean转为布尔类型
- 两个等号== 1、对象==字符串 对象转为字符串
2、null==undefined true null/undefined和其他任何值都不相等
3、对象==对象 比较堆内存地址,地址相同则相等
4、NaN!==NaN
5、除了以上情况,只要两边类型不一致,都是先转为数字,然后再进行比较
6、=== 绝对相等,如果两边类型不同,则直接是false
- 浮点数计算的解决方案 1、toFixed保留小数点后面N位,自动会四舍五入
2、扩大系数法
// 获取系数
const coeddicient = num => {
num = num + '';
let [,char = '']=num.split('.');
let len = char.length;
return Math.pow(10,len); // 10**len
}
const plus = (num1,num2){
num1 = +num1;
num2 = +num2;
if(isNaN(num1) || isNaN(num2)) return NaN;
let max = Math.max(coeddicient(num1),oeddicient (num2));
return (num1*max + num2*max)/max;
}
console.log(plus(0.1,0.23)) //0.33
a=?
if(a==1 && a==2 && a==3){
console.log('ok')
}
// 重写对象Symbol.toPrimitive
a={
i:0,
[Symbol.toPrimitive](){
return ++this.i;
}
}