JavaScript数据类型及判断

一.JS 中一共有八种数据类型

  • 基本数据类型(值类型):String 字符串、Number 数值、BigInt 大型数值、Boolean 布尔值、Null 空值、Undefined 未定义、Symbol。
  • 引用数据类型(引用类型):Object 对象。

注意:内置对象 Function、Array、Date、RegExp、Error 等都是属于 Object 类型。也就是说,除了那七种基本数据类型之外,其他的,都称之为 Object 类型。

BigInt 和 Symbol 是ES6中新增的类型。

二.栈内存和堆内存

JS 中,所有的变量都是保存在栈内存中的。

基本数据类型

基本数据类型的值,直接保存在栈内存中。值与值之间是独立存在,修改一个变量不会影响其他的变量。

引用数据类型

对象是保存到堆内存中的。每创建一个新的对象,就会在堆内存中开辟出一个新的空间;而变量保存了对象的内存地址(对象的引用),保存在栈内存当中。如果两个变量保存了同一个对象的引用,当一个通过一个变量修改属性时,另一个也会受到影响。

三.基本数据类型:Null 和 Undefined

Null:空对象

null 专门用来定义一个空对象。例如:let a = null,又例如 Object.create(null).

如果你想定义一个变量用来保存引用类型,但是还没想好放什么内容,这个时候,可以在初始化时将其设置为 null。你可以把 null 理解为:null 虽然是一个单独的数据类型,但null 相当于是一个 object,只不过地址为空(空指针)而已

举例:

let myObj = null;
cosole.log(typeof myObj); // 打印结果:object
  • Null 类型的值只有一个,就是 null。比如 let a = null
  • 使用 typeof 检查一个 null 值时,会返回 object。
undefined:未定义类型
case1:变量已声明,未赋值时

声明了一个变量,但没有赋值,此时它的值就是 undefined

举例:

let name;
console.log(name); // 打印结果:undefined
console.log(typeof name); // 打印结果:undefined
  • Undefined 类型的值只有一个,就是 undefind。比如 let a = undefined
  • 使用 typeof 检查一个 undefined 值时,会返回 undefined。
case2:变量未声明(未定义)时

如果你从未声明一个变量,就去使用它,则会报错;此时,如果用 typeof 检查这个变量时,会返回 undefined

举例:

console.log(typeof a); // undefined
console.log(a); // 打印结果:Uncaught ReferenceError: a is not defined
case3:函数无返回值时

如果一个函数没有返回值,那么,这个函数的返回值就是 undefined。

在定义一个函数时,如果末尾没有 return 语句,那么,其实就是 return undefined

举例:

function foo() {}

console.log(foo()); // 打印结果:undefined
case4:调用函数时,未传参

调用函数时,如果没有传参,那么,这个参数的值就是 undefined。

举例:

function foo(name) {
    console.log(name);
}

foo(); // 调用函数时,未传参。执行函数后的打印结果:undefined

实际开发中,如果调用函数时没有传参,我们可以根据需要给形参设置一个默认值:

function foo(name) {
    name = name || 'xiaofeixiaPan';
}

foo();

ES6 的方式:

function foo(name = 'xioafeixiaPan') {}

foo();
Null 和 Undefined的区别

null == undefined 的结果为 true,但是 null === undefined 的结果是 false。

  • 10 + null 结果为 10。
  • 10 + undefined 结果为 NaN。

规律总结:

  • 任何值和 null 运算,null 可看做 0 运算。
  • 任何数据类型和 undefined 运算都是 NaN。

四.基本数据类型:Number

数值范围

由于内存的限制,ECMAScript 并不能保存世界上所有的数值。

  • 最大值:Number.MAX_VALUE,这个值为: 1.7976931348623157e+308
  • 最小值:Number.MIN_VALUE,这个值为: 5e-324

如果使用 Number 表示的变量超过了最大值,则会返回 Infinity。

  • 无穷大(正无穷):Infinity
  • 无穷小(负无穷):-Infinity

注意:typeof Infinity的返回结果是 number。

如果分子是非0值,分母是有符号0或无符号0,则会返回Infinity-Infinity

console.log(5/0);//Infinity
console.log(5/-0);//-Infinity
NaN

NaN:是一个特殊的数字,表示 Not a Number,非数值。比如:

console.log('abc' / 18); //结果是NaN

console.log('abc' * 'abcd'); //NaN

console.log(0/0);//NaN
console.log(0/-0);//NaN

注意:

  1. typeof NaN的返回结果是 number。

  2. Undefined 和任何数值计算的结果为 NaN。NaN 与任何值都不相等,包括 NaN 本身。

    console.log(NaN==NaN);//false
    
  3. 任何涉及NaN的操作始终返回NaN(如NaN/10)

isNaN()函数

ECMAScript 提供了isNaN()函数。该函数接收一个参数,可以是任意数据类型,然后判断
这个参数是否“不是数值”。把一个值传给isNaN()后,该函数会尝试把它转换为数值。某些非数值的
值可以直接转换成数值,如字符串"10"或布尔值。任何不能转换为数值的值都会导致这个函数返回
true。

举例:

console.log(isNaN(NaN)); // true
console.log(isNaN(10)); // false,10 是数值
console.log(isNaN("10")); // false,可以转换为数值10
console.log(isNaN("blue")); // true,不可以转换为数值
console.log(isNaN(true)); // false,可以转换为数值1
类型转换

Number()、parseInt()、parseFloat()

Number

使用Number函数基本上可以转换所有类型

console.log(Number('xiaofeixiaPan')); //NaN
console.log(Number(true));	//1
console.log(Number(false));	//0
console.log(Number('9'));	//9
console.log(Number([]));	//0
console.log(Number([5]));	//5
console.log(Number([5, 2]));	//NaN
console.log(Number({}));	//NaN

Number()函数基于如下规则执行转换。
 布尔值,true 转换为1,false 转换为0。
 数值,直接返回。
 null,返回0。
 undefined,返回NaN。
 字符串,应用以下规则。
如果字符串包含数值字符,包括数值字符前面带加、减号的情况,则转换为一个十进制数值。因此,Number(“1”)返回1,Number(“123”)返回123,Number(“011”)返回11(忽略前面
的零)。
如果字符串包含有效的浮点值格式如"1.1",则会转换为相应的浮点值(同样,忽略前面的零)。
如果字符串包含有效的十六进制格式如"0xf",则会转换为与该十六进制值对应的十进制整
数值。
如果是空字符串(不包含字符),则返回0。
如果字符串包含除上述情况之外的其他字符,则返回NaN。
 对象,调用valueOf()方法,并按照上述规则转换返回的值。如果转换结果是NaN,则调用
toString()方法,再按照转换字符串的规则转换。

parseInt

空字符串也会返回NaN(这一点跟Number()不一样,它返回0)

parseInt()函数也能识别不同的整数格式(十进制、八进制、十六进制)。

console.log(parseInt('  99xioafeixiaPan'));	//99
console.log(parseInt('18.55'));	//18
let num1 = parseInt("1234blue"); // 1234
let num2 = parseInt(""); // NaN
let num3 = parseInt("0xA"); // 10,解释为十六进制整数
let num4 = parseInt(22.5); // 22
let num5 = parseInt("70"); // 70,解释为十进制值
let num6 = parseInt("0xf"); // 15,解释为十六进制整数


//parseInt()也接收第二个参数
let num = parseInt("0xAF", 16); // 175

parseFloat

parseFloat()只解析十进制值,十六进制数值始终会返回0。

第一次出现的小数点是有效的,但第二次出现的小数点就无效了,此时字符串的剩余字符都会被忽略。

let num1 = parseFloat("1234blue"); // 1234,按整数解析
let num2 = parseFloat("0xA"); // 0
let num3 = parseFloat("22.5"); // 22.5
let num4 = parseFloat("22.34.5"); // 22.34
let num5 = parseFloat("0908.5"); // 908.5
let num6 = parseFloat("3.125e7"); // 31250000
舍入操作

使用 toFixed 可对数值舍入操作,参数指定保存的小数位

console.log(1.556.toFixed(2)); //1.56
方式(隐式的类型转换):

使用一元的+来进行隐式的类型转换
例子:

var a = "123";  
a = +a;  

原理:和Number()函数一样

五.基本数据类型:Boolean

隐式转换

基本上所有类型都可以隐式转换为 Boolean类型。

数据类型truefalse
String非空字符串空字符串
Number非0的数值0 、NaN
Array数组不参与比较时参与比较的空数组
Object所有对象null
undefinedundefined
nullnull
NaNNaN

在JavaScript中,布尔值为 false的值有如下几个:

  • undefined
  • null
  • false
  • 0
  • NaN
  • ""''(空字符串)

当与boolean类型比较时,会将两边类型统一为数字1或0。

如果使用Boolean与数值比较时,会进行隐式类型转换 true转为1,false 转为0。

console.log(3 == true); //false
console.log(0 == false); //true

字符串在与Boolean比较时,两边都为转换为数值类型后再进行比较。

console.log("1" == true); //true

console.log("houdunren" == true); //false
//Number("houdunren")为NaN
显式转换

(1)使用 !! 转换布尔类型

!!的作用是将值的类型强制转化为布尔类型。

console.log(undefined==false);//false
console.log(null==false);//false
console.log(0==false);//true
console.log(NaN==false);//false
console.log(''==false);//true

console.log("-------------------------");
console.log(!!undefined==false);//true
console.log(!!null==false);//true
console.log(!!0==false);//true
console.log(!!NaN==false);//true
console.log(!!''==false);//true

返回值强制转换

const test=value=> value && true;
console.log(test(0)); // 0
const test=value=> !!value && true;
console.log(test(0)); // false

可以看到,!!value强制转化为布尔值。

(2)使用 Boolean 函数可以显式转换为布尔类型

let hd = '';
console.log(Boolean(hd)); //false
hd = 0;
console.log(Boolean(hd)); //false
hd = null;
console.log(Boolean(hd)); //false
hd = new Date("2020-2-22 10:33");
console.log(Boolean(hd)); //true

六.0, “”, null, false, undefined的区别

console.log(false==undefined);	//false
console.log(false==null);		//false
console.log(undefined==0);		//false
console.log(null==0);		//false
console.log(""==0);			//true
console.log(false==0);		//true
console.log(false=="");		//true
console.log(null==undefined);	//true

观察可发现:0、"“和false是相等的,null和undefined是相等的,而undefined和null并不等于false对象。
可以把0、”"和false归为一类,称之为“假值”,把null和undefined归为一类,称之为“空值”。假值还是一个有效的对象,所以可以对其使用toString等类型相关方法,空值则不行。

console.log(false.toString());    // false
console.log("".length);         // 0
console.log((0).toString());   // 0
console.log(undefined.toString());   
// throw exception "undefined has no properties"
console.log(null.toString());        // "null has no properties"

七.基本数据类型:String

转换为String
方式一(强制类型转换):

调用被转换数据的toString()方法
例子:
var a = 123;
a = a.toString();
注意:这个方法不适用于null和undefined
由于这两个类型的数据中没有方法,所以调用toString()时会报错

方式二(强制类型转换):

调用String()函数
例子:

var a = 123;  
a = String(a);  

原理:对于Number Boolean String都会调用他们的toString()方法来将其转换为字符串,对于null值,直接转换为字符串"null"。对于undefined直接转换为字符串"undefined"

方式三(隐式的类型转换):

为任意的数据类型 +“”
例子:

var a = true;  
a = a + ""; 

原理:和String()函数一样

语法:

字符串型可以是引号中的任意文本,其语法为:双引号 "" 或者单引号 ''

字符串的不可变性:

字符串里面的值不可被改变。虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。

代码举例:

var str = 'hello';

str = 'xiaofeixiaPan';

比如上面的代码,当重新给变量 str 赋值时,常量hello不会被修改,依然保存在内存中;str 会改为指向xiaofeixiaPan

字符串的常用方法

字符串的所有方法,都不会改变原字符串(字符串的不可变性),操作完成后会返回一个新的值。

我们也可将字符串常用的操作方法归纳为增、删、改、查,需要知道字符串的特点是一旦创建了,就不可变。

增:

concat

let stringValue = "hello ";
let result = stringValue.concat("world");
console.log(result); // "hello world"
console.log(stringValue); // "hello"
删:

常见的有:

  • slice()
  • substr()
  • substring()

都是字符串截取。

(1)slice( )

语法:

新字符串 = str.slice(开始索引, 结束索引); //两个参数都是索引值。包左不包右。

解释:从字符串中截取指定的内容。不会修改原字符串,而是将截取到的内容返回。

注意:上面的参数,包左不包右。参数举例如下:

  • (2, 5) 截取时,包左不包右。

  • (2) 表示从指定的索引位置开始,截取到最后

  • (-3) 表示从倒数第三个开始,截取到最后。

  • (1, -1) 表示从第一个截取到倒数第一个。

  • (5, 2) 表示前面的大,后面的小,返回值为空。

​ (2).substring( )

语法:

新字符串 = str.substring(开始索引, 结束索引); //两个参数都是索引值。包左不包右。

解释:从字符串中截取指定的内容。和slice()类似。

substring()slice()是类似的。但不同之处在于:

  • substring()不能接受负值作为参数。如果传递了一个负值,则默认使用 0。

  • substring()还会自动调整参数的位置,如果第二个参数小于第一个,则自动交换。比如说, substring(1, 0)相当于截取的是第一个字符。

​ (3).substr( )

语法:

字符串 = str.substr(开始索引, 截取的长度);

解释:从字符串中截取指定的内容。不会修改原字符串,而是将截取到的内容返回。

注意,这个方法的第二个参数截取的长度,不是结束索引。

参数举例:

  • (2,4) 从索引值为 2 的字符开始,截取 4 个字符。

  • (1) 从指定位置开始,截取到最后。

  • (-3) 从倒数第几个开始,截取到最后。

备注:ECMAscript 没有对 substr() 方法进行标准化,因此不建议使用它。

改:

常见的有:

  • trim()、trimLeft()、trimRight()
  • repeat()
  • padStart()、padEnd()
  • toLowerCase()、 toUpperCase()
  • replace()

(1)trim():去除字符串前后的空白。

举例:

//去除字符串前后的空格,trim();
let str = '   a   b   c   ';
console.log(str);//   a   b   c   
console.log(str.length);//15

console.log(str.trim());//a   b   c
console.log(str.trim().length);//9

使用trimLeft删除左边空白,使用trimRight删除右边空白

let name = " xiaofeixiaPan ";
console.log(name);
console.log(name.trimLeft());
console.log(name.trimRight()); 

(2)大小写转换:toLowerCase()、toUpperCase()

举例:

var str = 'abcdEFG';

//转换成小写
console.log(str.toLowerCase());//abcdefg

//转换成大写
console.log(str.toUpperCase());//ABCDEFG

(3) repeat():重复字符串

语法:

newStr = str.repeat(重复的次数);

解释:将字符串重复指定的次数。会返回新的值,不会修改原字符串。

const name = 'xiaofeixiaPan';
console.log(name.repeat(2));//xiaofeixiaPanxiaofeixiaPan

举例2:(模糊字符串的后四位)

const telephone = '13088889999';
const mix_telephone = telephone.slice(0, -4) + '*'.repeat(4); // 模糊电话号码的后四位

console.log(telephone); // 打印结果:13088889999
console.log(mix_telephone); // 打印结果:1308888****

(4)padEnd()

复制字符串,如果小于指定长度,则在相应一边填充字符,直至满足长度条件

let stringValue = "foo";
console.log(stringValue.padStart(6)); // " foo"
console.log(stringValue.padStart(9, ".")); // "......foo"

(5) replace()

语法:

新的字符串 = str.replace(被替换的字符,新的字符);

解释:将字符串中的指定内容,替换为新的内容并返回。不会修改原字符串。

注意:这个方法,默认只会替换第一个被匹配到的字符。如果要全局替换,需要使用正则。

举例:

//replace()方法:替换
var str2 = 'Today is fine day,today is fine day !';
console.log(str2);

console.log(str2.replace('today', 'tomorrow')); //只能替换第一个today
console.log(str2.replace(/today/gi, 'tomorrow')); //这里用到了正则,才能替换所有的today
查:
  • chatAt()、charCodeAt()
  • indexOf()
  • startsWith()、endsWith()
  • includes()
  • search()

(1)indexOf( )/lastIndexOf( ) :获取字符串中指定内容的索引

语法 1

索引值 = str.indexOf(想要查询的字符串);

备注:indexOf() 是从前向后查找字符串的位置。同理,lastIndexOf()是从后向前寻找。

解释:可以检索一个字符串中是否含有指定内容。如果字符串中含有该内容,则会返回其第一次出现的索引;如果没有找到指定的内容,则返回 -1。

因此可以得出一个重要技巧:

  • 如果获取的索引值为 0,说明字符串是以查询的参数为开头的

  • 如果获取的索引值为-1,说明这个字符串中没有指定的内容。

举例 1:(查找单个字符)

const str = 'abcdea';

//给字符查索引(索引值为0,说明字符串以查询的参数为开头)
console.log(str.indexOf('c'));//2
console.log(str.lastIndexOf('c'));//2

console.log(str.indexOf('a'));//0
console.log(str.lastIndexOf('a'))//5

举例 2:(查找字符串):

const name='xiaofeixiaPan';
console.log(name.indexOf('fei'));//4

语法 2

这个方法还可以指定第二个参数,用来指定查找的起始位置。语法如下:

索引值 = str.indexOf(想要查询的字符串, [起始位置]);

举例 3:(两个参数时,需要特别注意)

const name='xiaofeixiaPan';
let result=name.indexOf('i',2);// 从第二个位置开始查找 'i'这个字符 
console.log(result);//6

案例:查找字符串"xiaofeixiaPan"中,所有 a 出现的位置以及次数。

思路:

​ (1)先查找第一个 a 出现的位置。

​ (2)只要 indexOf 返回的结果不是 -1 就继续往后查找。

​ (3)因为 indexOf 只能查找到第一个,所以后面的查找,可以利用第二个参数,在当前索引加 1,从而继续查找。

const name='xiaofeixiaPan';
var index=name.indexOf('i');
var num=0;
while(index!=-1){
     console.log(index);
     num++;
     index=name.indexOf('i',index+1);
}
console.log('i 出现的次数是:'+num);

打印结果为:

1
6
8
i 出现的次数是:3

(2).search( ):获取字符串中指定内容的索引(参数里一般是正则)

语法:

索引值 = str.search(想要查找的字符串);
索引值 = str.search(正则表达式);

search() 方法里的参数,既可以传字符串,也可以传正则表达式。

解释:可以检索一个字符串中是否含有指定内容。如果字符串中含有该内容,则会返回其第一次出现的索引;如果没有找到指定的内容,则返回 -1。

举例:

const name = 'xiaofeixiaPan';

console.log(name.search('Pan')); // 打印结果:10
console.log(name.search(/Pan/i)); // 打印结果:10

备注:上方的/yi/i采用的是正则表达式的写法,意思是,让 name去匹配字符Pan,忽略大小写。

(3).includes( ):字符串中是否包含指定的内容

语法:

布尔值 = str.includes(想要查找的字符串, [position]);

解释:判断一个字符串中是否含有指定内容。如果字符串中含有该内容,则会返回 true;否则返回 false。

参数中的 position:如果不指定,则默认为0;如果指定,则规定了检索的起始位置。

const name = 'xiaofeixiaPan';

console.log(name.includes('fei')); // 打印结果:true
console.log(name.includes('haha')); // 打印结果:false

console.log(name.includes('yi',7)); // 打印结果:false

(4).startsWith( ):字符串是否以指定的内容开头

语法:

布尔值 = str.startsWith(想要查找的内容, [position]);

解释:判断一个字符串是否以指定的子字符串开头。如果是,则返回 true;否则返回 false。

参数中的position

  • 如果不指定,则默认为0。

  • 如果指定,则规定了检索的起始位置。检索的范围包括:这个指定位置开始,直到字符串的末尾。即:[position, str.length)

举例:

const name = 'abcdefg';

console.log(name.startsWith('a')); // 打印结果:true
console.log(name.startsWith('b')); // 打印结果:false

// 因为指定了起始位置为3,所以是在 defg 这个字符串中检索。
console.log(name.startsWith('d',3)); // 打印结果:true
console.log(name.startsWith('c',3)); // 打印结果:false

(5).endsWith():字符串是否以指定的内容结尾

语法:

布尔值 = str.endsWith(想要查找的内容, [position]);

解释:判断一个字符串是否以指定的子字符串结尾。如果是,则返回 true;否则返回 false。

参数中的position

  • 如果不指定,则默认为 str.length。

  • 如果指定,则规定了检索的结束位置。检索的范围包括:从第一个字符串开始,直到这个指定的位置。即:[0, position)

  • 或者你可以这样简单理解:endsWith() 方法里的position,表示检索的长度

注意:startsWith() 和 endsWith()这两个方法,他们的 position 的含义是不同的。

举例:

const name = 'abcdefg';

console.log(name.endsWith('g')); // 打印结果:true
console.log(name.endsWith('f')); // 打印结果:false

// 因为指定了截止位置为3,所以是在 abc 这个长度为3字符串中检索
console.log(name.endsWith('c', 3)); // 打印结果:true
console.log(name.endsWith('d', 3)); // 打印结果:false

(6).获取指定位置的字符

​ (1)charAt(index)

语法:

字符 = str.charAt(index);

解释:返回字符串指定位置的字符。这里的 str.charAt(index)str[index]的效果是一样的。

注意:字符串中第一个字符的下标是 0。如果参数 index 不在 [0, string.length) 之间,该方法将返回一个空字符串。

举例:

const name = 'xiaofeixiaPan';

console.log(name.charAt(3)); // 打印结果:o

​ (2) str[index]

str.charAt(index)str[index]的效果是一样的,不再赘述。区别在于:str[index]是 H5 标准里新增的特性。

​ (3) charCodeAt(index)

语法:

字符 = str.charCodeAt(index);

解释:返回字符串指定位置的字符的 Unicode 编码。不会修改原字符串。

在实际应用中,通过这个方法,我们可以判断用户按下了哪个按键。

代码举例:打印字符串的占位长度

提示:一个英文占一个位置,一个中文占两个位置。

思路:判断该字符是否在 0-127 之间(在的话是英文,不在是非英文)。

const name = 'xiaofeixiaPan';
var a=name.charCodeAt(3);
console.log(a);//111
转换方法
split():字符串转换为数组 【重要】

语法:

新的数组 = str.split(分隔符);

解释:通过指定的分隔符,将一个字符串拆分成一个数组。不会改变原字符串。

备注:split()这个方法在实际开发中用得非常多。一般来说,从接口拿到的 json 数据中,经常会收到类似于"q, i, a, n"这样的字符串,前端需要将这个字符串拆分成['q', 'i', 'a', 'n']数组,这个时候split()方法就派上用场了。

代码举例 1

var str='xiao,fei,xia,Pan';
var arr=str.split(',');
console.log(arr);//(4) ['xiao', 'fei', 'xia', 'Pan']

八.=====

I.==

==!= 都会先进行类型转换,再确定操作数是否相等

如果任一操作数是布尔值,则将其转换为数值再比较是否相等

let result1 = (true == 1); // true

如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转换为数值,再比较是否相等

let result1 = ("55" == 55); // true

如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf()方法取得其原始值,再根据前面的规则进行比较

let obj = {valueOf:function(){return 1}}
let result1 = (obj == 1); // true

nullundefined相等

let result1 = (null == undefined ); // true

如果有任一操作数是 NaN ,则相等操作符返回 false

let result1 = (NaN == NaN ); // false

如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true

let obj1 = {name:"xxx"}
let obj2 = {name:"xxx"}
let result1 = (obj1 == obj2 ); // false

总结:

  • 两个都为简单类型,字符串和布尔值都会转换成数值,再比较
  • 简单类型与引用类型比较,对象转化成其原始类型的值,再比较
  • 两个都为引用类型,则比较它们是否指向同一个对象
  • null 和 undefined 相等
  • 存在 NaN 则返回 false
II. ===

全等操作符由 3 个等于号( === )表示,只有两个操作数在不转换的前提下相等才返回 true。即类型相同,值也需相同

let result1 = ("55" === 55); // false,不相等,因为数据类型不同
let result2 = (55 === 55); // true,相等,因为数据类型相同值也相同

undefinednull 与自身严格相等

let result1 = (null === null)  //true
let result2 = (undefined === undefined)  //true

虽然null == undefined 是true(因为这两个值类似),但null === undefined 是
false,因为它们不是相同的数据类型。

总结:

除了在比较对象属性为null或者undefined的情况下,我们可以使用相等操作符(),其他情况建议一律使用全等操作符(=)

九.typeof和instanceof

typeof

typeof 操作符返回一个字符串,表示未经计算的操作数的类型。

  • 可以判断: undefined/ 数值 / 字符串 / 布尔值 / function
  • 不能判断: null与object object与array
  • 注意: 运行console.log(typeof undefined)时,得到的的也是一个字符串,同时为小写!!–> 'undefined'
// typeof返回数据类型的字符串表达
   var a

   //注意:typeof返回的是字符串
   console.log(a, typeof a, typeof a==='undefined',a===undefined )  
// undefined 'undefined' true true
   console.log(undefined === 'undefined') //false
   a = 4
   console.log(typeof a==='number') //true
   a = 'xiaofeixia'
   console.log(typeof a==='string') //true
   console.log(typeof a==='String') //false  -->注意,返回的类型为小写
   a = true
   console.log(typeof a==='boolean') //true
   a = null
   console.log(typeof a, a===null) // 'object'  true
  let b={}
   console.log(typeof b,typeof null) 
// 'object' 'object'  -->所以Typeof不能判断null与object

typeof nullobject

如果你需要在 if 语句中判断是否为 null,直接通过===null来判断就好

引用类型数据,用typeof来判断的话,除了function会被识别出来之外,其余的都输出object

typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof console.log // 'function'
instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

 var b1 = {
     b2: [1, 'abc', console.log],
     b3: function () {
       return  () =>{  return   'hello'}
     }
   }
  /**使用instanceof进行对象判断*/
   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

   /**使用typeof进行对象中某属性的判断*/
  console.log(typeof b1.b2, typeof null) // 'object' 'object'  
   console.log(typeof b1.b3==='function') // true
   console.log(typeof b1.b2[2]==='function') //true

   /**调用对象与数组中某函数示例*/
   b1.b2[2]('调用console.log打印hello')    //调用console.log打印hello
   console.log(b1.b3()()) // hello

构造函数通过new可以实例对象,instanceof能判断这个对象是否是之前那个构造函数生成的对象

// 定义构建函数
let Car = function() {}
let benz = new Car()
benz instanceof Car // true
let car = new String('xxx')
car instanceof String // true
let str = 'xxx'
str instanceof String // false

typeofinstanceof都是判断数据类型的方法,区别如下:

  • typeof会返回一个变量的基本类型(是一个字符串),instanceof返回的是一个布尔值
  • instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
  • typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了function 类型以外,其他的也无法判断
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序媛小y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值