# JS数据类型

# 堆栈内存

js中有两大内存:堆内存(heap)、栈内存(stack)

  • 堆内存作用:用来存储内容的(对象存储的是键值对,函数存储的是代码字符串)
  • 栈内存作用:也可以被称为作用域,是代码解析和执行的环境

# JS中的基本(原始)数据类型

js中的基础数据类型,这些值都有固定的大小,往往都是保存在内存空间中,由系统自动分配存储空间。我们可以直接操作保存在栈(stack)内存空间里面的值,因此基本数据类型都是按值访问的

JS中,存在的7中原始值分别是:

  • string
  • number
  • boolean
  • undefined
  • null
  • symbol(es6)
  • bigint

基本数据类型的值是不可变的

var str = "string";
str.toUpperCase(); // STRING
console.log(str); // string
1
2
3

按值进行比较

  var a = 1;
  var b = true;
  console.log(a == b); // true
  console.log(a === b); // false
1
2
3
4

其中,a == b,虽然数据类型不相同(true为boolean, 1为Number)但在比较之前js自动进行了数据类型的隐式转换

数据类型的隐式转换: 在算数运算符时,运算符两边的数据类型可以是任意的,比如,一个字符串可以和一个数字相加。但是如果两边数据不统一的话,CPU就无法进行计算,所以我们的编译器会自动的对数据进行隐式类型转换后再进行计算。

== 是进行值比较所以为true

=== 不仅比较值还要比较数据类型所以为false

栈内存中保存了变量的标识符和变量的值

var a,b;
a = 1;
b = a;
console.log(a); // 1
console.log(b); // 1
a = 2;
console.log(a); // 2
console.log(b); // 1
1
2
3
4
5
6
7
8

# JS中的引用数据类型

由于引用数据类型存储的值过于复杂(结构复杂即内容较多),渲染引擎会在堆内存(Heap)中开辟一个新的内存空间,单独来存储这些值,最后把内存空间引用地址赋值给对应的变量,后期所有的操作都是基于地址找到空间,然后对空间中的内容进行操作。

在JS中引用数据类型被统称为Object:

  • Object
    • Object
    • Function
    • Array
    • RegExp
    • Date
    • Math

这里要特殊注意的是 typeof null 也是 object.

引用类型的值是可变化的

var obj = { name: 'renbo' };
obj.name = 'zhangsan';
obj.age = 28;
obj.say = function () {
    return 'My name is' + this.name + 'I‘m' + this.age+ 'years old';
}
obj.say(); //My name is zhangsan I‘m 28 years old
1
2
3
4
5
6
7

引用类型是按引用地址进行比较

var obj = {};
var obj1 = {};
console.log(obj == obj1); // false
console.log(obj === obj1) // false
1
2
3
4

栈内存中保存了变量标识符和指向堆内存中该对象的指针

堆内存中保存了对象的内容

如以下示例所示:

var a = { name: 'renbo' };
var b = a;
a.name = 'zhangsan';
console.log(b.name); // zhangsan
b.age = 28;
console.log(b.age) // 28
b.say = function () {
    return 'My name is' + this.name + 'I‘m' + this.age+ 'years old';
}
console.log(a.say()); //My name is zhangsan I‘m 28 years old
var c = {
    name:'zhangsan',
    age:28
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 小结

# 对象数据类型

  • 1.开辟一个内存空间(有一个16进制的地址)
  • 2.把对象中的属性名和属性值一次存储到内存空间中
  • 3.把内存空间的地址赋值给变量

# 函数数据类型

  • 1.开辟一个内存空间(有一个16进制的地址)
  • 2.把函数体中的代码当作"字符串"存储到内存空间中
    • 函数创建的时候都是无意义的字符串所以说函数只创建不执行是毫无意义的
    • 变量提升只对当前作用域下的 var/function 处理,主要原因是函数中存的都是字符串,我们看到的函数中的 var/function 此时还都是字符串呢
    • 当函数执行的时候,就是要把这堆字符串拿出来执行的
  • 3.把内存空间地址赋值给变量

# typeof

经常用以检查变量是不是基本数据类型

特殊的有

  • null: typeof null // object
  • function: typeof function(){} // function
var a;
a = "hello";
typeof a; // string

a = true;
typeof a; // boolean

a = 1;
typeof a; // number 

a = null;
typeof a; // object

typeof a; // undefined

a = Symbol();
typeof a; // symbol

a = function(){}
typeof a; // function

a = [];
typeof a; // object

a = {};
typeof a; // object

a = /renbo/g;
typeof a; // object   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# Object.prototype.toString

除 typeof 之外,我们还经常用另一种方法来检测变量的数据类型。

const toString = Object.prototype.toString;
// 首字母大写
function upperFirst (word) {
    return word[0].toUpperCase() + word.slice(1);
}
// 判断类型
function isType (obj, type) {
    return type
        ? toString.call(obj) === '[object ' + upperFirst(type) + ']'
        : toString.call(obj).match(/(?![\[object ]).*(?=\])/i)[0].toLowerCase();
};

isType("111") // string
isType("111", "string") // true
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# instanceof

经常用来判断引用类型的变量具体是某种类型

var a;
a = function(){}
a instanceof Function; // true

a = [];
a instanceof Array; // true

a = {};
a instanceof Object; // true

a = /renbo/g;
a instanceof RegExp ; // true    
1
2
3
4
5
6
7
8
9
10
11
12

具体的instanceOf详见 手写一个instanceOf

# 致谢

感谢大家阅读我的文章,如果对我感兴趣可以点击页面右上角,帮我点个star。

作者:前端小然子

链接: https://xiaoranzife.com/guide/jichu/type.html

来源:前端小然子的博客

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

上次更新: 2019-11-18 2:58:36 ├F10: PM┤