常见JS问题,

1 JS内置类型

• JS 中分为七种内置类型,七种内置类型又分为两大类型:基本类型和对象(Object)。
• 基本类型有七种: null,undefined,boolean,number,string,symbol, bigint。
• 其中 JS 的数字类型是浮点类型的,没有整型。并且浮点类型基于 IEEE 754标准实现,在使用中会遇到某些 Bug。NaN 也属于 number 类型,并且 NaN 不等于自身。
• 对于基本类型来说,如果使用字面量的方式,那么这个变量只是个字面量,只有在必要的时候才会转换为对应的类型。

引用数据类型:

• 对象Object(包含普通对象-Object,数组对象-Array,正则对象-RegExp,日期对象-Date,数学函数-Math,函数对象-Function)

let a =111// 这只是字面量,不是 number 类型
对象(Object)是引用类型,在使用过程中会遇到浅拷贝和深拷贝的问题。
let a ={ name:‘FE’}let b = a
b.name =‘EF’
console.log(a.name)// EF
说出下面运行的结果,解释原因。
functiontest(person){
person.age =26
person ={
name:‘hzj’,
age:18
}
return person}const p1 ={
name:‘fyq’,
age:19}const p2 =test(p1)
console.log(p1)// -> ?
console.log(p2)// -> ?
// 结果:
p1:{name: “fyq”, age:26}
p2:{name: “hzj”, age:18}
原因: 在函数传参的时候传递的是对象在堆中的内存地址值,test函数中的实参person是p1对象的内存地址,通过调用person.age = 26确实改变了p1的值,但随后person变成了另一块内存空间的地址,并且在最后将这另外一份内存空间的地址返回,赋给了p2。

null和undefined区别

Undefined类型只有一个值,即undefined。当声明的变量还未被初始化时,变量的默认值为undefined。用法
• 变量被声明了,但没有赋值时,就等于undefined。
• 调用函数时,应该提供的参数没有提供,该参数等于undefined。
• 对象没有赋值的属性,该属性的值为undefined。
• 函数没有返回值时,默认返回undefined
Null类型也只有一个值,即null。null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。用法
• 作为函数的参数,表示该函数的参数不是对象。
• 作为对象原型链的终点

null是对象吗?为什么?

结论: null不是对象。
解释: 虽然 typeof null 会输出 object,但是这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象然而 null 表示为全零,所以将它错误的判断为 object 。

‘1’.toString()为什么可以调用?

其实在这个语句运行的过程中做了这样几件事情:
var s = new Object(‘1’);
s.toString();
s = null;
• 第一步: 创建Object类实例。注意为什么不是String ? 由于Symbol和BigInt的出现,对它们调用new都会报错,目前ES6规范也不建议用new来创建基本类型的包装类。
• 第二步: 调用实例方法。
• 第三步: 执行完方法立即销毁这个实例。
整个过程体现了基本包装类型的性质,而基本包装类型恰恰属于基本数据类型,包括Boolean, Number和String。
#1.5 0.1+0.2为什么不等于0.3?
0.1和0.2在转换成二进制后会无限循环,由于标准位数的限制后面多余的位数会被截掉,此时就已经出现了精度的损失,相加后因浮点数小数位的限制而截断的二进制数字在转换为十进制就会变成0.30000000000000004

如何理解BigInt

什么是BigInt?
BigInt是一种新的数据类型,用于当整数值大于Number数据类型支持的范围时。这种数据类型允许我们安全地对大整数执行算术操作,表示高分辨率的时间戳,使用大整数id,等等,而不需要使用库。
为什么需要BigInt?
在JS中,所有的数字都以双精度64位浮点格式表示,那这会带来什么问题呢?
这导致JS中的Number无法精确表示非常大的整数,它会将非常大的整数四舍五入,确切地说,JS中的Number类型只能安全地表示-9007199254740991(-(253-1))和9007199254740991((253-1)),任何超出此范围的整数值都可能失去精度。
console.log(999999999999999); //=>10000000000000000
同时也会有一定的安全性问题:
9007199254740992 === 9007199254740993; // → true 居然是true!
如何创建并使用BigInt?
要创建BigInt,只需要在数字末尾追加n即可
console.log(9007199254740995n);// → 9007199254740995n
console.log(9007199254740995);// → 9007199254740996
另一种创建BigInt的方法是用BigInt()构造函数
BigInt(“9007199254740995”);// → 9007199254740995n
简单使用如下:
10n+20n;// → 30n 10n-20n;// → -10n +10n;// → TypeError: Cannot convert a BigInt value to a number -10n;// → -10n 10n*20n;// → 200n 20n/10n;// → 2n 23n%10n;// → 3n 10n**3n;// → 1000n
const x =10n; ++x;// → 11n --x;// → 9n
console.log(typeof x);//“bigint”
值得警惕的点
BigInt不支持一元加号运算符, 这可能是某些程序可能依赖于 + 始终生成 Number 的不变量,或者抛出异常。另外,更改 + 的行为也会破坏 asm.js 代码。
因为隐式类型转换可能丢失信息,所以不允许在bigint和 Number 之间进行混合操作。当混合使用大整数和浮点数时,结果值可能无法由BigInt或Number精确表示。
10 + 10n; // → TypeError
不能将BigInt传递给Web api和内置的 JS 函数,这些函数需要一个 Number 类型的数字。尝试这样做会报TypeError错误。
Math.max(2n, 4n, 6n); // → TypeError
当 Boolean 类型与 BigInt 类型相遇时,BigInt 的处理方式与Number类似,换句话说,只要不是0n,BigInt就被视为truthy的值。
if(0n){//条件判断为false

}
if(3n){//条件为true

}
• 元素都为BigInt的数组可以进行sort。
• BigInt可以正常地进行位运算,如|、&、<<、>>和^
浏览器兼容性
caniuse的结果:

数据类型检测

.1 typeof类型判断
在写业务逻辑的时候,经常要用到JS数据类型的判断,面试常见的案例深浅拷贝也要用到数据类型的判断。
typeof
console.log(typeof2);// number
console.log(typeoftrue);// boolean
console.log(typeof’str’);// string
console.log(typeofundefined);// undefined
console.log(typeof[]);// object
console.log(typeof{});// object
console.log(typeoffunction(){});// function
console.log(typeofnull);// object
优点:能够快速区分基本数据类型 缺点:不能将Object、Array和Null区分,都返回object
instanceof
console.log(2instanceofNumber);// false
console.log(trueinstanceofBoolean);// false
console.log('str’instanceofString);// false
console.log([]instanceofArray);// true
console.log(function(){}instanceofFunction);// true
console.log({}instanceofObject);// true
• 优点:能够区分Array、Object和Function,适合用于判断自定义的类实例对象
• 缺点:Number,Boolean,String基本数据类型不能判断
Object.prototype.toString.call()
var toString =Object.prototype.toString;

console.log(toString.call(2));//[object Number]
console.log(toString.call(true));//[object Boolean]
console.log(toString.call(‘str’));//[object String]
console.log(toString.call([]));//[object Array]
console.log(toString.call(function(){}));//[object Function]
console.log(toString.call({}));//[object Object]
console.log(toString.call(undefined));//[object Undefined]
console.log(toString.call(null));//[object Null]
• 优点:精准判断数据类型
• 缺点:写法繁琐不容易记,推荐进行封装后使用
判断是否是promise对象
functionisPromise(val){
return(
typeof val.then ===‘function’&&
typeof val.catch =‘function’
)}
#2.2 typeof 于 instanceof 区别
typeof 对于基本类型,除了 null都可以显示正确的类型
typeof1// ‘number’typeof’1’// 'string’typeofundefined// 'undefined’typeoftrue// 'boolean’typeofSymbol()// 'symbol’typeof b // b 没有声明,但是还会显示 undefined
typeof 对于对象,除了函数都会显示 object
typeof[]// 'object’typeof{}// 'object’typeof console.log // ‘function’
对于 null 来说,虽然它是基本类型,但是会显示 object,这是一个存在很久了的 Bug
typeof null // ‘object’
instanceof 可以正确的判断对象的类型,因为内部机制是通过判断对象的原型链中是不是能找到类型的 iprototype
// 我们也可以试着实现一下 instanceoffunctioninstanceof(left, right){
// 获得类型的原型
let prototype = right.prototype
// 获得对象的原型
left = left.proto
// 判断对象的类型是否等于类型的原型
while(true){
if(left =null)
returnfalse
if(prototype === left)
returntrue
left = left.proto
}}
#2.3 Object.is和
=的区别
Object在严格等于的基础上修复了一些特殊情况下的失误,具体来说就是+0和-0,NaN和NaN。 源码如下
functionis(x, y){
if(x === y){
//运行到1/x === 1/y的时候x和y都为0,但是1/+0 = +Infinity, 1/-0 = -Infinity, 是不一样的
return x !0|| y !<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值