4.数据类型中的一点细节知识;5.数据类型转换规则和练习题;

本文详细阐述了JavaScript中的数据类型转换规则,包括Number、String和Boolean之间的转换,重点讨论了NaN、Symbol和BigInt的特性。还介绍了数据类型的比较规则,特别是“==”操作符背后的类型转换逻辑,并通过示例解析了转换过程中的各种细节和陷阱。此外,文章提到了对象在转换过程中的特殊处理,如Symbol.toPrimitive方法和valueOf、toString的调用顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.数据类型中的一点细节知识;5.数据类型转换规则和练习题;

/* 
 * 数据类型解读
 *   @1 NaN / Infinity / isNaN / Object.is ...
 *   @2 symbol & 对象属性类型
 *   @3 bigint
 * 
 * 数据类型转换
 *   @1 把其它数据类型转换为number
 *     + Number([val])
 *       + 一般用于浏览器的隐式转换中
 *       + 规则:
 *         @1 把字符串转换为数字:空字符串变为0,如果出现任何一个非有效数字字符,结果都是NaN
 *         @2 把布尔转换为数字:true->1  false->0
 *         @3 null->0  undefined->NaN
 *         @4 Symbol无法转换为数字,会报错:Uncaught TypeError: Cannot convert a Symbol value to a number
 *         @5 BigInt去除“n”(超过安全数字的,会按照科学计数法处理)
 *         @6 把对象转换为数字:
 *            + 先调用对象的 Symbol.toPrimitive 这个方法,如果不存在这个方法
 *            + 再调用对象的 valueOf 获取原始值,如果获取的值不是原始值
 *            + 再调用对象的 toString 把其变为字符串
 *            + 最后再把字符串基于Number方法转换为数字
 * 
 *     + parseInt([val],[radix])
 *     + parseFloat([val])
 *       + 一般用于手动转换
 *       + 规则:[val]值必须是一个字符串,如果不是则先转换为字符串;然后从字符串左侧第一个字符开始找,把找到的有效数字字符最后转换为数字「一个都没找到就是NaN」;遇到一个非有效数字字符,不论后面是否还有有效数字字符,都不再查找了;parseFloat可以多识别一个小数点;
 * 
 *     + 场景:数学运算中「除了“+”还有字符串拼接的效果」、isNaN([val])、“==”比较的时候有可能也要转换为数字...
 * 
 * 
 *   @2 把其它类型转换为string
 *     + “+”代表的字符串拼接
 *       + 有两边,一边是字符串
 *       + 有两边,一边是对象
 *       + 只出现在左边
 *       + ...
 *     + Object.prototype.toString
 *    
 *    @3 把其它类型转换为布尔
 *     + 除了“0/NaN/空字符串/null/undefined”五个值是false,其余都是true
 * 
 *    @4 “==”比较时候的相互转换规则
 *     + “==”相等,两边数据类型不同,需要先转为相同类型,然后再进行比较
 *       @1 对象==字符串   对象转换为字符串「Symbol.toPrimitive -> valueOf -> toString」
 *       @2 null==undefined  -> true   null/undefined和其他任何值都不相等
 *          null===undefined -> false
 *       @3 对象==对象  比较的是堆内存地址,地址相同则相等
 *       @4 NaN!==NaN 
 *       @5 除了以上情况,只要两边类型不一致,剩下的都是转换为数字,然后再进行比较的       
 *     + “===”绝对相等,如果两边类型不同,则直接是false,不会转换数据类型「推荐」
 */

// obj[Symbol.toPrimitive] = function (hint) {
//     // hint: number / string / default 浏览器自己调用这个方法,会默认传递的实参值
//     // ...
// };


//=================

/* 
 数字类型 number
    整数、浮点数(小数)、正数、负数、零
    NaN:not a number,不是一个有效数字,但是它率属于number类型 
       + typeof NaN -> "number"
       + 出现场景:经常出现在,把其它类型值转换为数字的时候,如果无法转换为有效数字,结果就是NaN
       + NaN!==NaN   NaN和任何值(包含自己本身),都不相等
    Infinity  无穷大的值

    isNaN([val]):检测[val]是否“不是个有效数字”,如果真不是,返回true,如果是有效数字,则返回false;如果[val]不是数字类型的,浏览器首先会将其隐式转换为number类型,然后再进行检测; 
    Object.is(NaN,NaN) -> true   ES6中提供的办法,不兼容IE浏览器(EDGE不应该算IE)
 */
// let n = ? ;
// if (n === NaN) {
//     // 条件永远无法成立
//     console.log(`n不是有效数字`);
// }

// let n = ? ;
// if (isNaN(n)) {
//     console.log(`n不是有效数字`);
// }

/*
  Symbol 唯一值类型 
    Symbol()  创造一个唯一值
    Symbol('xxx')  创造一个唯一值,只不过设置了标记
    new Symbol() Uncaught TypeError: Symbol is not a constructor 不允许被new执行
    ----
    用途1:给对象设置一个唯一的属性「对象的成员只能是 string & symbol 类型的值,Map允许属性名是不同类型的{包含对象}」
    用途2:它是很多内置机制的实现方式
       Symbol.toPrimitive
       Symbol.hasInstance
       Symbol.toStringTag
       ...
 */
// console.log(Symbol('AA') === Symbol('AA')); //false 创造了两个唯一值
// let sy = Symbol('AA'),
//     ys = sy;
// console.log(ys === sy); //true 只创建了一个唯一值

// let key = Symbol('KEY');
// let obj = {
//     // 属性名:“name” “age” “0” “1” Symbol() Symbol('KEY') “[object Object]”
//     name: 'zhufeng',
//     age: 12,
//     0: 100,
//     1: 200,
//     [Symbol()]: 300,
//     [key]: 400,
//     // 把对象转换为字符串,去充当它的属性名
//     [{
//         name: 'xxx'
//     }]: 500
// };
// console.log(obj[Symbol()]); //undefined  用新创建的唯一值去获取,肯定获取不到
// console.log(obj[key]); //400
// console.log(obj[0]); //100  -> obj[“0”]

/*
  BigInt 大数
    JS中的最大/最小安全数字:Number.MAX_SAFE_INTEGER / Number.MIN_SAFE_INTEGER / Math.pow(2,53)-1
       -> 9007199254740991  -9007199254740991  16位
       -> 超过这个范围的值进行数组运算,结果是不准确的

    场景:服务器端存储的ID是一个很大的值「数据库我们可以基于longInt处理」,现在我们把这个值返回给客户端,客户端获取值之后,需要进行运算处理,如果超过安全数字,导致结果是不准确的!!

    ---

    new BigInt()  Uncaught TypeError: BigInt is not a constructor
    BigInt("90071992547409919007199254740991") -> 90071992547409919007199254740991n
    一个数字后面加“n”就是BigInt

    ---

    计算完成的超长结果,基于toString转换为字符串「去掉n了」,把这个再传递给服务器即可
 */

//==================

/* let result = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false;
console.log(result); */



//=========================
/* console.log([] == false); //true
// [] -> 0  false -> 0
console.log(![] == false); //true
// ![] -> false
// false == false  */


/*
   “==”比较:数据类型转换的机制,需要把a转换为数字
   因为把对象转换为数字,我么可以做的事很多  Symbol.toPrimitive -> valueOf -> toString -> Number
 */
// var a = {
//     i: 0,
//     // 还可以重写 valueOf & toString
//     [Symbol.toPrimitive]() {
//         // this:a
//         return ++this.i;
//     }
// };
// if (a == 1 && a == 2 && a == 3) {
//     console.log('OK');
// }

// var a = [1, 2, 3];
// a.toString = a.shift;
// if (a == 1 && a == 2 && a == 3) {
//     console.log('OK');
// }

/*
  全局上下文 
  基于var声明的变量是给GO{window}设置的一个属性
  获取属性a的值:Object.defineProperty 进行数据劫持
 */
// var i = 0;
// Object.defineProperty(window, 'a', {
//     get() {
//         return ++i;
//     }
// });
// if (a == 1 && a == 2 && a == 3) {
//     console.log('OK');
// }


//=========================
/* let arr = [27.2, 0, '0013', '14px', 123];
arr = arr.map(parseInt);
/!* 
  parseInt(27.2,0)
    parseInt('27.2',10)  ->  '27'  ->  把'27'看做10进制,转换为10进制  =>27

  parseInt(0,1)  =>NaN
    
  parseInt('0013',2)
    parseInt('0013',2)  ->  '001'  ->  把'001'看做2进制,转换为10进制  =>1
      0*2^2 + 0*2^1 + 1*2^0

  parseInt('14px',3)
    parseInt('14px',3)  ->  '1'  ->  把'1'看做3进制,转换为10进制  =>1
      1*3^0   

  parseInt(123,4)
    parseInt('123',4)  ->  '123'  ->  把'123'看做4进制,转换为10进制  =>27
      1*4^2 + 2*4^1 + 3*4^0

  parseInt传递的第二个值是一个radix进制 
    + radix不写或者写0,默认是10进制「如果第一个传递的字符串是以“0x”开始的,那么默认是16进制」
    + radix取值范围:2~36,不在这个范围内,处理的结果都是NaN
    + 在传递的字符串中,从左到右,找到符合radix进制的值{遇到不符合的则结束查找},把找到的值,看做radix进制,最后转换为10进制
    + 把其它进制的值转换为10进制:“按权展开求和”
*!/
console.log(arr); */

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

arr = arr.map(function (item, index) {
    return item + '@';
});

'12.21' 看做3进制,转换为10进制
    1*3^1  2*3^0  2*3^-1  1*3^-2     3^-1   1/3   3^-2  1/9
    
console.log([] == false); //true
// [] -> 0  false -> 0
console.log(![] == false); //true
// ![] -> false
// false == false

JS中的值,在计算机底层都是按照64位的2进制值来进行存储的

JS中我们平时写的数字 浏览器都认为是10进制的

浏览器有一个操作:把我们自己写的10进制值 交给计算机的时候,会转换为2进制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值