1、数据类型的存储形式
栈(Stack)和堆(Heap),是两种基本的数据结构。Stack 在内存中自动分配内存空间的;Heap 在内存中动态分配内存空间的,不一定会自动释放。一般我们在项目中将对象类型手动置为 null 原因,减少无用内存消耗。
1.原始类型是按值形式存放在栈中的数据段,内存空间可以自由分配,同时可以按值直接访问
2.引用类型是存放在堆内存中,每个对象在堆内存中有一个引用地址,就像是每个房间都有一个房间号一样。引用类型在栈中保存的就是这个对象在堆内存的引用地址,我们所说的“房间号”。通过“房间号”可以快速查找到保存在堆内存的对象。
2.javascript 的数据类型有哪些?
JavaScript 语言的每一个值都属于某一种数据类型。JavaScript 语言规定了 7 种语言类型。语言类型广泛用于变量、函数参数、表达式、函数返回值等场合。根据最新的语言标准,这 7 种语言类型是:
1.String
2.Number
3.Boolean
4.Undefined
5.Null
6.Symbol(es6新加)
7.Object
1.String
String 用于表示文本数据。String 的最大长度是 2^53 - 1,String 的意义并非“字符串”,而是字符串的 UTF16 编码,我们字符串的操作 charAt、charCodeAt、length 等方法针对的都是 UTF16 编码。所以,字符串的最大长度,实际上是受字符串的编码长度影响的。
2.Number
Number 类型表示我们通常意义上的“数字”。这个数字大致对应数学中的有理数。
3.Boolean
Boolean 类型有两个值, true 和 false,它用于表示逻辑意义上的真和假,同样有关键字 true 和 false 来表示两个值。
4.Undefined
Undefined 类型表示未定义,它的类型只有一个值,就是 undefined。任何变量在赋值前是 Undefined 类型、值为 undefined,一般我们可以用全局变量 undefined(就是名为 undefined 的这个变量)来表达这个值。
5.Null
null 表示的是:“定义了但是为空”。在实际编程时,我们一般不会把变量赋值为 undefined,这样可以保证所有值为 undefined 的变量,都是从未赋值的自然状态。Null 类型也只有一个值,就是 null,它的语义表示空值,与 undefined 不同,null 是 JavaScript 关键字,所以在任何代码中,你都可以放心用 null 关键字来获取 null 值。
注意:typeof null 等于 Object。
不同的对象在底层原理的存储是用二进制表示的,在 javascript
中,如果二进制的前三位都为 0 的话,系统会判定为是 Object
类型。null
的存储二进制是 000
,也是前三位,所以系统判定 null
为 Object
类型。
6.Symbol(es6新加)
Symbol 是 ES6 中引入的新类型,表示独一无二的值,它是一切非字符串的对象 key 的集合,在 ES6 规范中,整个对象系统被用 Symbol 重塑。最大的用法是用来定义对象的唯一属性名。
基本用法:
Symbol 函数不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的 Symbol 提供描述,用来显示在控制台或者作为字符串的时候使用,便于区分。
let sy = Symbol("ahao");
console.log(sy); //Symbol(ahao)
typeof sy; // "symbol"
// 相同参数 Symbol() 返回的值不相等
let sy1 = Symbol("ahao");
sy === sy1; // false
用法
由于每一个 Symbol 的值都是不相等的,所以 Symbol 作为对象的属性名,可以保证属性不重名。
注意:Symbol 作为对象属性名时不能用.运算符,要用方括号。因为.运算符后面是字符串,所以取到的是字符串 sy 属性,而不是 Symbol 值 sy 属性。
let sy = Symbol("key1");
// 写法1
let syObject = {};
syObject[sy] = "ahao";
console.log(syObject); // {Symbol(key1): "ahao"}
// 写法2
let syObject = {
[sy]: "ahao",
};
console.log(syObject); // {Symbol(key1): "ahao"}
// 写法3
let syObject = {};
Object.defineProperty(syObject, sy, { value: "ahao" });
console.log(syObject); // {Symbol(key1): "ahao"}
7.Object
Object 是 JavaScript 中最复杂的类型,也是 JavaScript 的核心机制之一。Object 表示对象的意思,它是一切有形和无形物体的总称。在 JavaScript 中,对象的定义是“属性的集合”。属性分为数据属性和访问器属性,二者都是 key-value 结构,key 可以是字符串或者 Symbol 类型。
JavaScript 中的几个基本类型,都在对象类型中有一个“亲戚”。它们是:
- Number;
- String;
- Boolean;
- Symbol
所以,我们必须认识到 ahao 与 new String(3) 是完全不同的值,它们一个是 String类型, 一个是对象类型。
Number、String 和 Boolean,三个构造器是两用的,当跟 new 搭配时,它们产生对象,当直接调用时,它们表示强制类型转换。
Symbol 函数比较特殊,直接用 new 调用它会抛出错误,但它仍然是 Symbol 对象的构造器。
JavaScript 语言设计上试图模糊对象和基本类型之间的关系,我们日常代码可以把对象的方法在基本类型上使用
console.log("ahao".charAt(0)); //a
3.数据类型的判断
1.typeof
typeof
是一元运算符,同样返回一个字符串类型。一般用来判断一个变量是否为空或者是什么类型。除了 null
类型以及 Object
类型不能准确判断外,其他数据类型都可能返回正确的类型。
typeof undefined // 'undefined'
typeof '10' // 'String'
typeof 10 // 'Number'
typeof false // 'Boolean'
typeof Symbol() // 'Symbol'
typeof Function // ‘function'
typeof null // ‘Object’
typeof [] // 'Object'
typeof {} // 'Object'
2.instanceof
instanceof 可以判断某个对象是不是另一个对象的实例。返回值的是一个布尔类型。
var ahao = [];
console.log(ahao instanceof Array) // true
4.类型的转换
javaScript
是一种弱类型语言,变量不受类型限制,所以在特定情况下我们需要对类型进行转换。类型转换分为显式类型转换和隐式类型转换。每种转换又分为原始类型转换和对象类型转换。
1.显示类型转换(也就是我们讲的强制类型转换)
(1)其他数据类型转字符串类型
对于原始类型来说,转字符串类型会默认调用 toString()
方法。
String(123); // "123"
String(true); // "true"
String(null); // "null"
String(undefined);// "undefined"
String([1,2,3]) // "1,2,3"
String({}); // "[object Object]"
(2)其他数据类型转布尔类型
除了特殊的几个值 ``、 undefined
、 NAN
、 null
、 false
、 0
转化为 Boolean
为 false
之外,其他类型值都转化为 true
。
Boolean('') // false
Boolean(undefined) // false
Boolean(null) // false
Boolean(NaN) // false
Boolean(false) // false
Boolean(0) // false
Boolean({}) // true
Boolean([]) // true
(3)其他数据类型转化为数字类型
数据类型 | 数字类型 |
string | (1) 数字转化为对应的数字 (2) 其他转化为 NaN |
boolean | (1) true 转化为 1 |
null | 0 |
undefined | NaN |
Array | (1) 数组为空转化为 0; (2) 数组只有一个元素转化为对应元素; (3) 其他转化为NaN |
'' | 0 |
\
Number(10); // 10
Number('10'); // 10
Number(null); // 0
Number(''); // 0
Number(true); // 1
Number(false); // 0
Number([]); // 0
Number([1]); // 1
Number([1,2]); // NaN
Number('10a'); // NaN
Number(undefined); // NaN
对象类型在转原始类型的时候,会调用内置的 valueOf()和 toString() 方法,这两个方法是可以进行重写的。
转化原始类型分为两种情况:转化为字符串类型或其他原始类型。
如果已经是原始类型,不需要再进行转化。
如果转字符串类型,就调用内置函数中的 toString()方法。
如果是其他基本类型,则调用内置函数中的 valueOf()方法。
如果返回的不是原始类型,则会继续调用 toString() 方法。
如果还没有返回原始类型,则报错。
2.隐示类型转换
隐士类型转化是不需要认为的强制类型转化,javaScript
自动将类型转化为需要的类型,所以称之为隐式类型转换。
加法运算
如果双方都不是字符串,则将转化为数字或字符串。
Boolean + Boolean会转化为数字相加。
Boolean + Number 布尔类型转化为数字相加。
Object + Number 对象类型调用 valueOf,如果不是 String、Boolean或者 Number类型,则继续调用 toString()转化为字符串。
字符串和字符串以及字符串和非字符串相加都会进行连接。
其他运算
其他算术运算符(比如减法、除法和乘法)都不会发生重载。它们的规则是:所有运算子一律转为数值,再进行相应的数学运算。
参考文献:
1.https://blog.csdn.net/qq_36903042/article/details/104207646
2.前端面试之道