你真的懂js数据类型么?

概念

在这里插入图片描述如图所示,js数据类型有七种,前六种为基本数据类型,symbol为es6引入的特殊基本数据类型,而最后一种也是最需要关注的类型,引用类型,引用类型又有图上五种类型。

了解完数据类型的分类后,大家需要明白数据类型的存放方式:

  • 基础类型存储在栈内存,被引用或拷贝时,会创建一个完全相等的变量
  • 引用类型存储在堆内存,存储的是地址,多个引用指向同一个地址,这里涉及到共享的概念。

例题1

let a = {
    
    
  name: 'lee',
  age: 18
}
let b = a;
console.log(a.name);  //第一个console
b.name = 'son';
console.log(a.name);  //第二个console
console.log(b.name);  //第三个console

这道题比较简单,我们可以看到第一个 console 打出来 name 是 ‘lee’,这应该没什么疑问;但是在执行了 b.name=‘son’ 之后,结果你会发现 a 和 b 的属性 name 都是 ‘son’,第二个和第三个打印结果是一样的,这里就体现了引用类型的“共享”的特性,即这两个值都存在同一块内存中共享,一个发生了改变,另外一个也随之跟着变化。
下面我们再看一段代码,它是比题目一稍复杂一些的对象属性变化问题。

例题2

let a = {
    
    
  name: 'Julia',
  age: 20
}
function change(o) {
    
    
  o.age = 24;
  o = {
    
    
    name: 'Kath',
    age: 30
  }
  return o;
}
let b = change(a);     // 注意这里没有new,后面new相关会有专门文章讲解
console.log(b.age);    // 第一个console
console.log(a.age);    // 第二个console

这道题涉及了 function,你通过上述代码可以看到第一个 console 的结果是 30,b 最后打印结果是 {name: “Kath”, age: 30};第二个 console 的返回结果是 24,而 a 最后的打印结果是 {name: “Julia”, age: 24}。
是不是和你预想的有些区别?你要注意的是,这里的 function 和 return 带来了不一样的东西。
原因在于:函数传参进来的 o,传递的是对象在堆中的内存地址值,通过调用 o.age = 24(第 7 行代码)确实改变了 a 对象的 age 属性;但是第 12 行代码的 return 却又把 o 变成了另一个内存地址,将 {name: “Kath”, age: 30} 存入其中,最后返回 b 的值就变成了 {name: “Kath”, age: 30}。而如果把第 12 行去掉,那么 b 就会返回 undefined。

你不知道的数据类型检测

说到数据类型检测,大家对typeof和instanceof想必是信手拈来,但是Object.prototype.toString,大家是否知道呢?
下面我们看一下它的使用方法:
toString() 是 Object 的原型方法,调用该方法,可以统一返回格式为 “[object Xxx]” 的字符串,其中 Xxx 就是对象的类型。对于 Object 对象,直接调用 toString() 就能返回 [object Object];而对于其他对象,则需要通过 call 来调用,才能返回正确的类型信息。我们来看一下代码。

Object.prototype.toString({
    
    })       // "[object Object]"
Object.prototype.toString.call({
    
    })  // 同上结果,加上call也ok
Object.prototype.toString.call(1)    // "[object Number]"
Object.prototype.toString.call('1')  // "[object String]"
Object.prototype.toString.call(true)  // "[object Boolean]"
Object.prototype.toString.call(function(){
    
    })  // "[object Function]"
Object.prototype.toString.call(null)   //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g)    //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([])       //"[object Array]"
Object.prototype.toString.call(document)  //"[object HTMLDocument]"
Object.prototype.toString.call(window)   //"[object Window]"

但是在写判断条件的时候一定要注意,使用这个方法最后返回统一字符串格式为 “[object Xxx]” ,而这里字符串里面的 “Xxx” ,第一个首字母要大写(注意:使用 typeof 返回的是小写),这里需要多加留意。

猜你喜欢

转载自blog.csdn.net/weixin_42898315/article/details/112687421