JS数据类型

By 大Van家 on 2021-12-13
阅读时间 7 分钟
文章共 1.8k
阅读量

同系列文章请查看:Github:pre-interview

JS有哪些数据类型

Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt

ES6 中新增了一种 Symbol 。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。

谷歌67版本中还出现了一种 bigInt。是指安全存储、操作大整数。(但是很多人不把这个做为一个类型)。

Object 中包含了哪几种类型?

其中包含了Data、function、Array等。这三种是常规用的。

JS的基本类型和引用类型有哪些呢?

基本类型(单类型):除Object。 String、Number、boolean、null、undefined。

引用类型:object。里面包含的 function、Array、Date。

引用数据类型和原始数据类型有什么区别

:原始数据类型(Undefined、Null、Boolean、Number、String)

:引用数据类型(对象、数组和函数)

两种类型的区别在于存储位置的不同:

原始数据类型直接存储在栈(stack)中的简单数据段:

  • 占据空间小、大小固定
  • 属于被频繁使用数据,所以放入栈中存储;

引用数据类型存储在堆(heap)中的对象:

  • 占据空间大、大小不固定。
  • 如果存储在栈中,将会影响程序运行的性能;
  • 引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。
  • 当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

JS 中 typeof 输出分别是什么?

{ } 、[ ] 输出 object。

console.log( ) 输出 function。

注意:NaN 是 Number 中的特殊数值,非Number 。

1
2
3
4
5
6
7
8
Number('as') == NaN // false
Number('123') == NaN // fal
// 用 isNaN() 检测是否是非数值型

isNaN('123') // false
isNaN(123) // false
isNaN(Number('as')) // true
NaN == NaN // false

JS如何判断数据类型?

typeof

toString()

  • 作用:其他类型转成 string 的方法

  • 支持:number、boolean、string、object

  • 不支持:null 、undefined

toLocaleString()

  • 作用:把数组转成本地字符串
1
['1', '2','3'].toLocaleString() // '1, 2, 3'

检测数组类型的方法

① instanceof 操作符

1
2
let arr = ['1', '2','3']
console.log(arr instanceof Array) // true

②对象的 constructor 属性

1
2
let arr = ['1', '2','3']
console.log(arr.constructor === Array) // true

③ Array.isArray( ) 检验值是否为数组

1
2
let arr = ['1', '2','3']
console.log(Array.isArray(arr)) // true

Null 和 Undefined 有什么区别?

Null 只有一个值,是 null。不存在的对象。

Undefined 只有一个值,是undefined。没有初始化。undefined 是从 null 中派生出来的。

简单理解就是:undefined 是没有定义的,null 是定义了但是为空

Null 不存在的原因是什么?如何解决?

不存在的原因是:

  • 方法不存在
  • 对象不存在
  • 字符串变量不存在
  • 接口类型对象没初始化

解决方法:做判断处理的时候,放在设定值的最前面

或者避免展示null/undefined:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var Tools = {};

/**
* 移除空字符串或者非法字符串,返回""
* 如果是合法字符串,则返回原值
* @param obj 文本
*/
Tools.removeNullOrUndefined = function (obj) {
//typeof 返回的是字符串,有六种可能:"number"、"string"、"boolean"、"object"、"function"、"undefined"
if (typeof(obj) == "undefined" || obj == "" || obj == null || obj == "null" || obj.length == 0) {
return "";
} else {
//删除全是空格的情况
var regu = "^[ ]+$";
var re = new RegExp(regu);
if(re.test(obj)){
return "";
}else{
return obj;
}

}
}

== 和 === 有什么区别,什么场景下使用?

== 表示相同。

比较的是物理地址,相当于比较两个对象的 hashCode ,肯定不相等的。
类型不同,值也可能相等。

=== 表示严格相同。

例:同为 null/undefined ,相等。

简单理解就是 == 就是先比较数据类型是否一样。
=== 类型不同直接就是 false。

1
2
null == undefined // true
null === undefined // false

JS对象如何比较?

方法一:通过JSON.stringify(obj)来判断两个对象转后的字符串是否相等

缺点:这种方法有限制就是当两个对比的对象中key的顺序不是完全相同时会比较出错

方法二:浅层比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function shallowEqual(object1, object2) {
const keys1 = Object.keys(object1);
const keys2 = Object.keys(object2);

if (keys1.length !== keys2.length) {
return false;
}

for (let index = 0; index < keys1.length; index++) {
const val1 = object1[keys1[index]];
const val2 = object2[keys2[index]];
if (val1 !== val2) {
return false;
}
}

return true;
}

getOwnPropertyNames 方法可以将Object对象的第一层key获取到并返回一个由第一层key组成的数组。

优点:相对方法一进行了优化,可以应对不同顺序的Object进行比较,不用担心顺序不同而对比出错。
缺点:从方法中可以看到只能获取到第一层的key组成的数组,当对象是复合对象时无法进行多层对象的比较。

方法三:深度对比两个对象是否完全相等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function deepEqual(object1, object2) {
const keys1 = Object.keys(object1);
const keys2 = Object.keys(object2);

if (keys1.length !== keys2.length) {
return false;
}

for (let index = 0; index < keys1.length; index++) {
const val1 = object1[keys1[index]];
const val2 = object2[keys2[index]];
const areObjects = isObject(val1) && isObject(val2);
if (areObjects && !deepEqual(val1, val2) ||
!areObjects && val1 !== val2) {
return false;
}
}

return true;
}

function isObject(object) {
return object != null && typeof object === 'object';
}

总结:

引用相等性(使用 ===、 == 或 Object.is())用来确定操作数是否为同一个对象实例。

手动检查对象是否相等,需要对属性值进行手动比较。尽管这类检查需要手动编码来对属性进行比较,但由于很简单,所以这种方法很方便。

当被比较的对象有很多属性或在运行时确定对象的结构时,更好的方法是使用浅层检查。

如果比较的对象具有嵌套对象,则应该进行深度比较检查。

Object 类型

ECMAjavascript中的对象其实就是一组数据和功能的集合。对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。创建object类型的实例并为其添加属性(或)方法,就可以自定义创建对象。

如:var o = new Object( );

object 的每个实例都有下列属性和方法:

constructor:保存着用于创建当前对象的函数。(构造函数)constructor就是object();

hasOwnProperty(propertyName):用于检查给定的当前属性在当前对象实例中)而不是在实例原型中)是否存在。其中,作为参数的属性名(propertyName)必须以字稚串形式指定(例如:o.hasOwnProperty(“name”))。

isPrototypeOf(object):用于检查传入的对象是否是传入对象原型。

propertyIsEnumerable(propertyName):用于检查给定属性是否能够用for-in语句。与hasOwnProperty()方法一样,作为参数的属性名必须以字符串形式指定。

toLocaleString( ):返回对象的字符串表示,该字符串与执行环境的地区对应。

toString( ):返回对象的字符串表示。

valueOf( ):返回对象的字符串、数值或者布尔值表示。通常与toString( )方法的返回值得相同。

ECMAJS中object是所有对象的基础,因些所有对象都具有这些基本的属性和方法。


Tips: Please indicate the source and original author when reprinting or quoting this article.