前言

二刷JavaScript高级了,上一次是刷的黑马pink老师的课程,这次刷的是尚硅谷的课程,都是B站的课程,对课程进行了些许总结。

可能是课程有些老的原因,例如视频中仅有5个基本类型,但是目前好像是有7种。

所以结合之前所学的一些知识,对内容进行了补充。

如有错误,还望指正。

分类

基本(值)类型

  • String:任意字符串
  • Number:任意的数字
  • boolean:true / false
  • undefined:undefined
  • null:null
  • bigInt:可以用任意精度表示整数
  • symbol:符号类型是唯一的并且是不可修改的,通常用来作为object的key

引用(对象)类型

  • Object:任意对象
  • Function:一种特别的对象(可以执行)
  • Array:一种特别的对象(数值下标,内部数据是有序的)

如何判断数据类型

三种方法:

  • typeof

    typeof返回数据类型的字符串表达

    注:可以判断undefined、数值、boolean、字符串,不能判断null与object object与array

  • instanceof

    判断对象的具体类型

  • ===

    注:可以判断undefined,null

判断基本类型

1
2
3
var a
console.log(a,typeof a,typeof a === 'undefined',a === undefined) // undefined 'undefined' true true
console.log(undefined === 'undefined') // false
1
2
3
4
5
6
7
8
9
var a
a = 3
console.log(typeof a === 'number') // true
a = 'Ned'
console.log(typeof a === 'string') // true
a = true
console.log(typeof a === 'boolean') // true
a = null
console.log(typeof a, a=== null) // object

请注意:这里string,s一定要小写,否则会是false,这是因为人家已经设计好的,是固定的。

判断对象类型

1
2
3
4
5
6
var b1 = {
b2: [a,'abc',console.log]
b3: function (){
console.log('b3')
}
}

整体的 b1 是个对象,b2 是数组, b3 是函数。

1
2
3
console.log(b1 instanceof Object, b1 instanceof Array) // true false
console.log(b1.b2 instanceof Array, b1.b2 instanceof Object) // true true
console.log(b1.b3 instanceof Function, b1.b3 instanceof Object) // true true

标注一下 instance of 的用法

[实例] instanceof [类]

如果这个实例是类的实例,就返回true,反之返回false

也就是说,我们判断对象类型,要用instanceof。

另:判断function还可以用typeof

1
console.log(typeof b1.b3 === 'function' // true

不知道大家有没有注意,b2的第三个值我们写了个console.log,下面我们也来判断一下它,应该是个function的。

1
console.log(typeof b1.b2[2] === 'function') // true

所以我们要调用这个函数的时候可以直接b1.b2[2](),这里提醒大家,我们千万不要被b1.b2[2]所迷惑,我们要清楚它的数据类型到底是什么。

就此情况,我们上面b1中的b3改写一下。

1
2
3
4
5
6
7
8
var b1 = {
b3: function (){
console.log(b3)
return function (){
return 'Ned'
}
}
}

我们想要得到'Ned',应该怎么做?

只需要调用这个返回过来的函数即可:b1.b3()(),输出一下:

1
console.log(b1.b3()())

所以不要拘泥于表面现象,一定要看清楚得到的是什么类型的数据,才能进行下一步的操作!

补充

手写instanceof

想要手写,我们首要的就是要了解它的原理。

原理:验证当前类的原型prototype是否会出现在实例的原型链proto上,只要在它的原型链上,则结果都为true。因此,instanceof在查找的过程中会遍历左边变量的原型链,直到找到右边变量的prototype,找到返回true,找不到返回false。

1
2
3
4
5
6
7
8
9
10
11
12
13
function myinstanceOf(left,right){
let proto = left.__proto__
let prototype = right.prototype
while(true){
if(proto == null){
return false
}
if(proto == prototype){
return true
}
proto = proto.__proto__
}
}

constructor(用于引用数据类型)

  • 语法: 被检测数据.constructor === class
  • 特点:
    • 适合使用在引用数据类型上
    • 原型链不会干扰
  • 原理:构造函数原型上有一个 constructor 属性指向构造函数自身的,如果在实例上使用 construtor 时,就会直接使用其构造函数原型的上的该属性,并指向其构造函数。

Object.prototype.toString.call()(对象原型链判断方法)

  • 语法:Object.prototype.toString.call(被检测数据)
  • 特点:适用于所有类型的判断检测
  • 原理:Object.prototype.toString 表示一个返回对象类型的字符串,call()方法可以改变this的指向,那么把Object.prototype.toString()方法指向不同的数据类型上面,返回不同的结果

补充,相关问题(2021.9.23)

undefined与null的区别?

  • undefined表示定义未赋值
  • null表示定义并赋值了,只是值为null
1
2
3
4
var a
console.log(a) // undefined
a = null
console.log(a) // null

什么时候给变量赋值为null呢?

  • 初始赋值,表明将要赋值为对象
  • 结束前,让对象成为垃圾对象,被回收掉。

不知道大家是否还记得,typeof 一个null的时候,返回的是什么?

1
2
var a = null
console.log(typeof a) // object

没错,是object。

所以当我们将一个变量的初始值赋值为null的时候,我们是向其他程序员表明,这个变量将会被赋值为对象。

不这么做行不行? 当然可以。

那为什么还要这么做?

当然是因为,编程也是很严谨的。

1
2
3
var b = null // 初始赋值为null,表明将要赋值为对象
b = ['Ned',20] // 确定对象就赋值
b = null // 最后,让b指向的对象成为垃圾对象(被垃圾回收器回收)

严格区别变量类型与数据类型

  • 数据的类型
    • 基本类型
    • 对象类型
  • 变量的类型(变量内存值的类型)
    • 基本类型:保存就是基本类型的数据
    • 引用类型:保存的是地址值

平时的时候我们不会去区分这个概念(要不是视频里看见了我都不知道:crying_cat_face:)。

简单的了解到这个概念就行吧~。

1
2
3
4
var a = fuction (){
console.log('这是一个函数')
}
console.log(typeof a) // function