• JavaScript面试题整理(二)


    数据类型篇

    13、其他值到字符串的转换规则?

    • Null和Undefined类型,null转换为‘null’,undefined转换为‘undefined’
    • Boolean类型,true转换为‘true’,false转换为‘false’
    • Number类型的值直接转换,不过那些极小和极大的数字会使用指数形式
    • Symbol类型的值直接转换,但是只允许显式强制类型转换,使用隐式强制类型转换会产生错误
    • 对普通对象来说,除非自行定义toString()方法,否则会调用toString()(Object.prototype.toString())来返回内部属性[[Class]]的值,如‘[object Object]’。如果对象有自己的toSting()方法,字符串化时就会调用该方法并使用其返回值。

    14、其他值到数字值的转换规则?

    • Undefined类型的值转换为NaN

    • Null类型的值转换为0

    • Boolean类型的值,true转换为1,false转换为0

    • String类型的值转换如同使用Number()函数进行转换,如果包含非数字值则转换为NaN,空字符串为0

    •  Symbol类型的值不能转换为数字,会报错

    • 对象(包含数组)会首先被转换为相应的基本类型值,如果返回的是非数字的基本类型值,则再遵循以上规则将其强制转换为数字。

    为了将值转换为相应的基本类型值,抽象操作ToPrimitive会首先(通过内部操作DefaultValue)J检查该值是否有valueOf()方法。如果有并且返回基本类型值,就使用该值进行强制类型转换。如果没有就使用toString()的返回值(如果存在)来进行强制类型转换。

    如果valueOf()和toString()均布返回基本类型值,会产生TypeError错误。

    15、JS字符串转数字的方法

    通过函数parseInt(t),可以解析一个字符串,并返回一个整数,语法为parseInt(tsring,radix)

    string:被解析的字符串

    radix:表示要解析的数字的基数,默认是十进制,如果radix<2或者>36,则返回NaN

    16、其他值到布尔类型的值的转换规则?

    以下这些是假值:

    • undefined
    • null
    • false
    • +0、-0、NaN
    • ''、""

    假值的布尔强制类型转换结果都为false,从逻辑上说,假值列表以外的都应该是真值。

    17、|| 和&& 操作符的返回值?

    || 和 && 首先会对第一个操作数执行条件判断,如果其不是布尔值就先强制转换为布尔类型,然后再执行条件判断。

    • 对于||来说,如果条件判断结果为true就返回第一个操作数的值,如果为false就返回第二个操作数的值
    • &&则相反,如果条件判断结果为true就返回第二个操作数的值,如果为false就返回第一个操作数的值

    || 和 &&返回它们其中一个操作数的值,而非条件判断的结果 

    18、Object.is()与比较操作符'==='、‘==’的区别?

    ‘==’:不全相等,只比较数据,不比较类型,如果两边的类型不一致,则会进行强制类型转换后再进行比较

    ‘====’:全等,既要比较数据,也比较数据类型,如果两边的类型不一致时,不会做强制类型转换,直接返回false

    (1)==主要存在:强制转换成number,null==undefined

    1. " " == 0 //true
    2. "0" == 0 //true
    3. " " != '0' //true
    4. 123 == '123' //true
    5. null == undefined //true

    (2)Object.is():一般情况下和三等好的判断相同,它处理了一些特殊的情况,比如-0和+0不再相等,两个NaN是相等的

    主要的区别就是 +0  != -0  而 NaN==NaN

    19、什么时候JavaScript中的包装类型?

    在JavaScript中,基本类型是没有属性和方法的,但是为了便于操作基本类型的值,在调用基本类型的属性和方法时JavaScript会在后台隐式地将基本类型的值转换为对象,例如:

    const a = 'abc';

    a.length; //3

    a.toUpperCase(); //ABC

    在访问‘abc’.length时,JavaScript将‘abc’在后台转换成String('abc'),然后再访问其length属性。

    JavaScript也可以使用Object函数显式地将基本类型转换为包装类型:

    let a = 'abc'

    Object(a)  //String{'abc'} 

    也可以使用valueOf方法将包装类型倒转成基本类型:

    let a = 'abc'

    let b = Object(a)

    let c = b.valueOf() //abc 

    看看如下代码会打印出什么:

    1. let a = new Boolean(false);
    2. if(!a){
    3. console.log('Oops');
    4. }

     答案是什么都不会打印出来,因为虽然包裹的基本类型是false,但是false被包裹成包装类型后就成了对象,所以其非值为false,所以循环体中的内容不会运行。

    20、JavaScript中如何进行隐式类型转换?

    首先看ToPrimitive方法,这是JavaScript中每个值隐含的自带的方法,用来将值(无论是基本类型值还是对象)转换为基本类型值。如果值为基本类型,则直接方法会值本身;如果值为对象,看起来就如下所示:

    ToPrimitive(obj,type)

    type的值为number或者string

    (1)当type为number时规则如下:

    • 调用obj的valueOf方法,如果为原始值,则返回,否则下一步
    • 调用obj的toString方法,后续同上
    • 抛出TypeError异常

    (2)当type为string时规则如下:

    • 调用obj的toString方法,如果为原始值,则返回,否则下一步
    • 调用obj的valueOf方法,后续同上
    • 抛出TypeError异常 

    可以看出两者的主要区别在于调用toString和valueOf的先后顺序。默认情况下:

    • 如果对象为Date对象,则type默认为string
    • 其他情况下,type默认为number

    总结上面的规则,对于Date以外的对象,转换为基本类型的大概规则可以概括为一个函数:

    let objToNumber = value => Number(valueOf().toString())

    objToNumber([]) === 0

    objToNumber({}) === NaN

    而JavaScript中的隐式类型转换主要发生在+、-、*、/以及==、>、<这些运算符之间。而这些运算符只能操作基本类型值,所以在进行这些运算前的第一步就是将两边的值用ToPrimitive转换成基本类型,再进行操作。

    一下是基本类型的值在不同操作符的情况下隐式转换的规则(对于对象,其会被ToPrimitive转换成基本类型,所以最终还是要应用基本类型转换规则)

    1.+操作符  

    +操作符的两边有至少一个string类型变量时,两边的变量都会被隐式转换为字符串;其他情况下两边的变量都会被转换为数字。

    1+'23' //'123'

    1+false //1

    1+Symbol() //  Cannot convert a Symbol value to a number

    '1'+false //'1false'

    false+true // 1

    2.-、*、\操作符

    NaN也是一个数字

    1*‘23’   //23

    1*false //0

    1/'aa  //NaN 

    3.==操作符

    操作符两边的值都尽量转成number

    3 == true //false  3转为number为3,true转为number为1

    ‘0’ == false //true  ‘0’转为number为0 false转为number为0 

    ‘0’ == 0 //true  ‘0’转为number为0

    4.>和<比较符

    如果两边都是字符串,则会比较字符顺序

     'ca'<'bd'  //false

    'a' < 'b' //true

    其他情况下,转换为数字再比较:

    '12' < 13 //true

    false > -1 //true 

    以上都是基本类型的隐式转换,而对象会被ToPrimitive转换为基本类型再进行转换:

    let a = {}

    a > 2 //false 

    对比过程如下:

    a.valueOf()  //{}  ToPrimitive默认type为number,所以先valueOf,结果还是个对象

    a.toString() // '[object Object]'

    Number(a.toString())  //NaN  根据上面<和>操作符的规则,要转换成数字

    NaN > 2  //false   得出比较结果 

     再或者

    let a = {name:'Jack'}

    let b = {age:18}

    a+b  //"[object Object][object Object]"

     运算过程如下:
    a.valueOf() // {},上⾯提到过,ToPrimitive默认type为number,所以先
    valueOf,结果还是个对象,下⼀步
    a.toString() // "[object Object]"
    b.valueOf() // 同理
    b.toString() // "[object Object]"
    a + b // "[object Object][object Object]"

    21、+操作符什么时候用于字符串的拼接?

    根据ES5规范,如果某个操作数是字符串或者能够通过以下步骤转换为字符串的话,+将进行拼接操作。如果其中一个操作数是对象(包括数组),则首先对其调用ToPrimitive抽象操作,该抽象操作再调用[[DefaultValue]],以数字作为上下文。如果不能转换为字符串,则会将其转换为数字类型来进行计算。

    简单来说就是,如果+的其中一个操作数是字符串(或者通过以上步骤最终得到了字符串),则执行字符串拼接,否则就执行数字加法。

    那么对于除了加法的运算符来说,只要其中一方是数字,那么另一方就会被转为数字。

    22、为什么会有BigInt的提案?

    JavaScript中Number.MAX_SAFE_INTEGER表示最大安全数字,计算结果是9007199254740991,即在这个数范围内不会出现精度丢失(小数除外)。但是一旦超过这个范围,JavaScript就会出现计算不准确的情况,这在大数计算的时候,不得不依靠一些第三方库进行解决,因此官方提出了BigInt来解决此问题。

    23、object.assign和扩展运算法是深拷贝还是浅拷贝,两者有什么区别?

    扩展运算符:

    1. let outObj = {
    2. inObj:{a:1,b:2}
    3. }
    4. let newObj = {...outObj}
    5. newObj.inObj.a = 2
    6. console.log(outObj); //{ inObj: { a: 2, b: 2 } }

    Object.assign()

    1. let outObj = {
    2. inObj:{a:1,b:2}
    3. }
    4. let newObj = Object.assign({},outObj)
    5. newObj.inObj.a = 2
    6. console.log(outObj); //{ inObj: { a: 2, b: 2 } }

    可以看出,两个都是浅拷贝。

    • Object.assign()方法接收的第一个参数作为目标对象,后面的所有参数作为源对象。然后把所有的源对象合并到目标对象中。它会修改了一个对象,因此会触发ES6 setter。
    • 扩展操作符(...)使用它时,数组或对象中的每一个值都会被拷贝到一个新的数组或对象中。它不复制继承的属性或类的属性,但是它会复制ES6的symbols属性。

  • 相关阅读:
    路网编辑器技术预研
    VUE cli3.0项目打包部署服务器
    C++——多态|多态的概念|多态的定义及实现|虚函数|多态的原理|虚函数表构成虚表的条件
    大规模分布式链路分析计算在字节跳动的实践
    正负折线图凸显数据趋势变化
    系统运维管理小记
    数商云S2B2B商城系统:商品管理功能亮点,为建筑建材企业采购提供极致网购体验
    自己动手写编译器:创建由 C 语言编译而成的语法解析器
    瑞芯微RK3568核心板在边缘服务器产品中的应用-迅为电子
    Nebula Importer 数据导入实践
  • 原文地址:https://blog.csdn.net/m0_73634593/article/details/132993905