跳到主要内容

数据类型

知识点

QA环节

  • 说一下js的数据类型,如何判断数据类型 🔗

  • 怎么实现一个通用数据类型判断 🔗

  • 怎么实现 instanceof 🔗

  • JS有哪些类型,基本类型引用类型的区别是什么,分别存储在哪 🔗

  • null 和 undefined 的区别是什么

    参考回答
    1. null 是一个空的对象,而 undefined 是一个全局变量的特殊属性。同时,null 是JavaScript的保留关键字,而 undefined 却不是。
    2. 进行数值运算时,null 返回值是0,而 undefined 是NaN
    3. null == undefined,但是 null !== undefined 。【我是这样理解的:null和undefined都是没有实际的值的,所以null == undefined,而本质上,null是空的对象,undefined是未定义的一个全局属性,所以null !== undefined。】
  • 通过 toString 判断的原理是什么

    参考回答

    任何一个 Object 的 toString 的结果都是 [object object] ,也就是说,Object 这个全局对象的原型里面的 toString 方法是:首先判断这是对象,然后再继续判断对象的类型。

    有点类似于 String 函数的准则(参考数据类型转换)那也就是说,任何的类型数据,再Object.prototype.toString 方法里首先会被定义成一个object,然后再去看是什么类型

  • 为什么 String 作为基本类型,通过 Object.prototype.toString.call 获取的结果是"[object String]"

    参考回答

    因为 toString 为 Object 的原型方法,而 Array 、Function 等类型作为 Object 的实例,都重写了 toString 方法。不同的对象类型调用 toString 方法时,(根据原型链的知识)调用的是对应的重写之后的 toString 方法(Function 类型返回内容为函数体的字符串,Array 类型返回元素组成的字符串...),而不会去调用 Object 上原型 toString 方法(返回对象的具体类型),所以采用 obj.toString() 不能得到其对象类型,只能将 obj 转换为字符串类型。因此,在想要得到对象的具体类型时,应该调用 Object 上原型 toString 方法

  • 如何将字符串转化为数字

    参考回答
    方法说明注意点栗子
    parseInt(str) | parseInt(str, 10)没有传入基数时,默认是传入的基数为 10如果不知道str属性的类型,不要使用该方式parseInt("08"); // returns 0 部分老浏览器parseInt("44.jpg"); // returns 44
    parseFloat(str)不解析 16 进制数是很好的方式如果不知道要转换对象的类型,不要使用该方式parseInt(-0xff); // returns -255parseInt("-0xFF"); // returns -255parseFloat(-0xff); // returns -255parseFloat("-0xFF"); // returns 0
    Number(str)JsPerf 中最慢的之一[几乎不用]与以上提及的转换方式一样存在这样的问题Number("023"); // returns 23 Number(023); // returns 19,023 实际上是一个八进制数,无论你怎么做,都是返回 19
    ~~str可以把字符串转换成整数,但他不是浮点数。如果是一个字符串转换,它将返回 0用它确保输入中没有字符,仅用于整数~1.23; // returns 1~"1.23"; // returns 1~~"23"; // returns 23~~"Hello world"; // returns 0
    str / 1
    str * 1
    str -

    参考☞ https://juejin.cn/post/6844904033933590536

代码理解

const a = {
name: 'lee',
age: 18
}
const b = a;
console.log(a.name); // lee
b.name = 'son';
console.log(a.name); // son
console.log(b.name); // son
const a = {
name: 'Julia',
age: 20
}
function change(o) {
o.age = 24;
o = {
name: 'Kath',
age: 30
}
return o;
}
const b = change(a);
console.log(b.age); // 30
console.log(a.age); // 24

/**
* 函数传参进来的o,传递的是对象在堆中的内存地址
* o.age 改变了a对象的相应属性
* return o 把o变成了另一个内存地址
* 如果去掉return 返回的会是 undefined
*/
null == undefined       // true 
null == 0 // false
'' == null // false
'' == 0 // true 字符串转隐式转换成Number之后对比
'123' == 123 // true 字符串转隐式转换成Number之后对比
0 == false // true 布尔型隐式转换成Number之后对比
1 == true // true 布尔型隐式转换成Number之后对比
var a = {
  value: 0,
  valueOf: function() {
    this.value++;
    return this.value;
  }
};
// 注意这里a又可以等于1、2、3
console.log(a == 1 && a == 2 && a == 3); // true
// 注:执行过3遍之后,再重新执行a == 3或之前的数字就是false,因为value已经加上去了
1 + 2             // 3  常规情况
'1' + '2' // '12' 常规情况
// 特殊情况
'1' + undefined // "1undefined" undefined转换字符串
'1' + null // "1null" null转换字符串
'1' + true // "1true" true转换字符串
'1' + 1n // '11' 比较特殊字符串和BigInt相加,BigInt转换为字符串
1 + undefined // NaN undefined转换数字相加NaN
1 + null // 1 null转换为0
1 + true // 2 true转换为1,二者相加为2
1 + 1n // 错误 不能把BigInt和Number类型直接混合相加
'1' + 3 // '13' 字符串拼接
var obj = {
value: 1,
valueOf() {
return 2;
},
toString() {
return '3'
},
[Symbol.toPrimitive]() {
return 4
}
}
console.log(obj + 1); // 5
// 因为有Symbol.toPrimitive,就优先执行这个;如果Symbol.toPrimitive这段代码删掉,则执行valueOf打印结果为3;如果valueOf也去掉,则调用toString返回'31'(字符串拼接)

// 两个特殊的case:
10 + {}
// "10[object Object]",注意:{}会默认调用valueOf是{},不是基础类型继续转换,调用toString,返回结果"[object Object]",于是和10进行'+'运算,按照字符串拼接规则来,参考'+'的规则C
[1,2,undefined,4,5] + 10
// "1,2,,4,510",注意[1,2,undefined,4,5]会默认先调用valueOf结果还是这个数组,不是基础数据类型继续转换,也还是调用toString,返回"1,2,,4,5",然后再和10进行运算,还是按照字符串拼接规则,参考'+'的第3条规则
'123' == 123        // true
'' == null // false
'' == 0 // true
[] == 0 // true
[] == '' // true
[] == ![] // true
null == undefined // true
Number(null) // 0
Number('') // 0
parseInt('') // NaN
{} + 10 // 10
let obj = {
[Symbol.toPrimitive]() { return 200 },
valueOf() { return 300 },
toString() { return 'Hello' }
}
console.log(obj + 200) // 400