null、undefined、boolean、number、string、symbol、object(array、function)
- undefined:声明了,但未被赋值
- null:曾经被赋值,现在没有值
- NaN:计算失败得到的结果 NaN != NaN
基本数据类型:null、undefined、boolean、number、string、symbol
引用类型:object、array、function、data、正则、math
栈(stack)和堆(heap):stack为自动分配的内存空间,它由系统自动释放;而heap则是动态分配的内存,大小也不一定会自动释放
区别:
- 声明变量时内存分配不同
- 原始类型:存在栈中,占据固定空间
- 引用类型:存在堆中,栈中存储的变量是引用地址。因为栈分配内存后就不会改变大小,而引用值的大小会改变,所以存储值不变的地址。
- 访问机制不同
- 引用类型按引用地址访问。
- 基本类型的值直接访问。
- 复制变量时的不同
- 基本类型:在将一个保存着原始值的变量复制给另一个变量时,会将原始值的副本赋值给新变量,此后这两个变量是完全独立的,他们只是拥有相同的value而已。
- 引用值:在将一个保存着对象内存地址的变量赋给给另一个变量时,会把这个内存地址赋值给新变量,指向堆中同一个对象,任何一个作出的改变都会反映在另一个身上
基本包装类型和引用类型主要区别:对象的生存期。使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都是一直保存在内存中.而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁(说的详细一点就是,JS引擎通过在内部临时创建一个对应的包装类型的临时对象,并把对基本类型的操作代理到这个临时对象身上,使得对基本类型的属性访问看起来像对象一样。但是在操作完成后,临时对象就扔掉了,下次再访问时,会重新建立临时对象,当然对之前的临时对象的修改都不会有效。)。所以基本类型的值是不可以被方法改变的,调用方法后返回的是新的值,原来的变量值没有变。
- 为什么string、number也有自己的方法
JavaScript 为基本数据类型值提供了封装对象,称为原生函数(如 String、Number、Boolean 等)。它们为基本数据类型值提供了该子类型所特有的方法和属性(如:String#trim() 和 Array#concat(..))。
对于简单标量基本类型值,比如 "abc",如果要访问它的 length 属性或 String.prototype 方法,JavaScript 引擎会自动对该值进行封装(即用相应类型的封装对象来包装它)来实 现对这些属性和方法的访问。
当原始数据类型(boolean,Number、String)在调用方法时,JS 将会创建对象,以便调用方法属性,而在使用完毕后将会销毁该对象。原始值被当作构造函数创建的一个对象来使用时, JS 会将其转换为一个对象,以便其可以使用对象的特性(如方法),而后抛弃对象性质,并将它变回到原始值。
-
instanceof、typeof、Object.stringOf
typeof: undefined、boolean、number、string、symbol、object、function
console.log(typeof NaN); // number
console.log(typeof undefined); // undefined
console.log(typeof null); // Object
console.log(typeof []); // Object
⭐️instanceof:左边是对象,右边是函数 就是检查,左边对象的原型链上 是否存在 右边构造函数的原型
反过来操作就是:Foo.prototype.isPrototypeOf(a):foo是否出现在a的原型链中
使用instanceof容易造成误解:
⚠️需要注意的是,构造函数本身还是函数,new操作符只是将其调用方式变成“构造函数调用”,本质上还是需要去执行它。在 JavaScript 中对于“构造函数”最准确的解释是,所有带 new 的函数调用。
网友评论