一、基础

1、基本类型(原始数据类型,栈)

  • boolean
  • string
  • number
  • null
  • undefined
  • symbol(ES6)

2、引用数据类型(堆)

  • object
  • function
  • array

3、二者的不同

  • 1)、存储方式不同
    • 原始数据类型,由于其频繁被使用,因此存储在栈中,占据空间小,大小固定
    • 引用数据类型,占据空间大,大小不固定,存储在堆中,但是其在栈中也存放了地址,通过栈中堆的地址来找到对象
  • 2)、传值方式不同
    • 原始数据类型,传参的策略为按值传递,形参传递过去的是本身的副本,对形参的操作并不会改变原始数据
    • 引用数据类型,传参的策略为按引用传递,形参的传递为原始数据的地址,因此对形参的操作会直接影响原始数据

二、typeof 和 instanceof 的差别

1、typeof

用于获取数据的类型,只能返回如下的几种结果
“number”、”string”、”boolean”、”object”、”function” 和 “undefined”

  1. console.log(typeof "1"); // string
  2. console.log(typeof 1); // number
  3. console.log(typeof null); // object
  4. console.log(typeof function a(){}); // function
  5. console.log(typeof []); // object
  6. console.log(typeof true); // boolean

2、instanceof

用来判断某对象是否是另一对象的实例(本质是判断原型链,可以参考原型链笔记)

  1. var s1 = String("123");
  2. var s2 = "123";
  3. var s3 = new String("123");
  4. console.log(s1 instanceof String); // false
  5. console.log(s2 instanceof String); // false
  6. console.log(s3 instanceof String); // true

上述代码,虽然 s1 s2 s3 都为string数据类型,但只有 s3 是 String 对象的实例,而 instanceof 只能比较对象,因此只有 s3 返回了true;
另外 s1 s2 不是String对象的实例,缺能用 String对象的方法,是因为js内部存在的装箱

  1. var s1 = String("123");
  2. var s2 = "123";
  3. var s3 = new String("123");
  4. console.log(s1 instanceof Object); // false
  5. console.log(s2 instanceof Object); // false
  6. console.log(s3 instanceof Object); // true

上述代码表明,虽然 Object 是一切对象的原型,但是由于 s1 s2 根本就不是一个对象,因此也会输出 false


三、装箱与拆箱

1、装箱

  1. var s1 = "01234567";
  2. s1 = s1.substring(0, 3);
  3. console.log(s1); // 012
  4. console.log(s1 instanceof String); // false

装箱可以让基础数据类型调用对象的操作,在上述代码中,即是让 string 这个数据类型转换为 String 这个对象,并且调用这个 String 对象的方法
装箱只存在那一行代码,代码结束后,装箱所创建的零时 String 对象就会被销毁,因此第四行输出的仍然是 false

2、拆箱

  1. var s1 = new String("123");
  2. console.log(s1 instanceof String); // true
  3. s1 = s1.valueOf(); // 或 s1.toString()
  4. console.log(s1 instanceof String); // false

拆箱会将引用类型转为原始数据类型,上述代码中,即将 String对象 转为 string 数据类型