JS基础--数据类型
JS介绍
JS作为客户端语言,可以操作界面元素,也可以操作浏览器行为。
JS三大组成部分
JS由三部分组成:
ES+DOM+BOM
其中,ES:定义了JS的基本语法;
DOM文本对象模型:可以对网页界面元素做操作;
BOM浏览器对象模型:可以对浏览器进行操作;
JS变量
1. 定义变量的四种方法
1)ES3: var a=10;
2)ES6:
let b=10;
const c=20; # 常量,不可以更改
var a=10;
undefined
a=15;
15
let b =1;
undefined
b=12;
12
const c = 23;
undefined
c=24; # 如果强制赋值给常量,则报错如下
VM225:1 Uncaught TypeError: Assignment to constant variable.
at <anonymous>:1:2
3) 创建类:
class A {}
4) 导入模块:
import B from ‘./B.js’
5)Symbol: 定义唯一值
使用方法:
let 变量名 = Symbol(值);
通常情况下,数值类型比较大小比较的是变量所指向的值. 加上Symbol表示唯一,即使值相同,两个变量也是不相等的。
var a =10;
> undefined
var b = 10;
> undefined
a==b
> true
let c = Symbol(10)
> undefined
let d = Symbol(10)
> undefined
c==d
> false
2. JS 命名规范
- JS 是区分大小写的语言。
- 命名组成元素: 数字、字母、下划线、$, 其中不能以数字开头。因为八进制和十六进制的表示方法是0o和0x, 为了做区别,不能以数字开头。变量名和变量值不能一样。
变量名不能和变量值内容一样
var hello = hello;
undefined
hello
undefined
不能以数字开头
var 0o10
# VM911:1 Uncaught SyntaxError: Unexpected number
可以以$ 开头,通常用于JQuery元素获取
var $q=10
> undefined
$q
> 10
可以以_ 开头,通常用来定义全局变量
var _e=1
> undefined
_e
> 1
3. JS 数据类型
1. 基本数据类型
- 数值型 number: 数字+NaN
- 字符型 string: 单引号、双引号、反撇(``)包起来的所有内容
- 布尔型 boolean
- 空对象指针 null
- 未定义 undefined
2. 引用数据类型
- 对象数据类型object
1) {} 普通对象
2) [] 数组对象
3)/^$/ 正则表达式
4) Math 数学函数对象
5) 日期对象 - 函数数据类型 function
3. 判断是否是数值
JS中判断是否是非数字使用isNaN(), 是非数值型,返回true;是数值型,返回false。 该方法调用机制:先将括号内的内容调用Number() 进行转换,转换后,再判断是否是数字。
例:
isNaN("12")
false //Number("12")->12
isNaN("true")
true //Number("true")->NaN
isNaN(true)
false//Number(true)->1
isNaN(null)
false//Number(null)->0
isNaN(undefined)
true//Number(undefined)->NaN; isNaN(NaN)->true
isNaN(NaN)
true
4. 非数值类型转换为数值型
- Number([val]): 把引用类型转换为数字时,先将其基于toString()方法转为字符串,然后再转换为数字(parseInt 转为字符串后,直接进行数字查找)。
- 字符串: 看是否包含非有效数字字符,包含结果就是NaN;‘’-》0;
- 布尔:true-》1;false-》0;
- null-》0
- undefined-》NaN
- 引用数据类型都先要转换为字符串,再转换为数字
- {} 正则/函数等-》NaN
- []->‘’->0
- [‘12’]->12
- [‘12’,‘23’]->NaN
Number('true')
NaN
Number(true)
1
Number('')
0
Number(null)
0
Number(undefined)
NaN
Number({})
NaN//{}.toString()-->({}).toString()-->'[object Object]'-->NaN
Number([])
0//[].toString()-->''
Number([12])
12//[12].toString-->12
Number([12,23])
NaN//[12,23].toString-->'12,23'
- parseInt([val],[进制]): 对于字符串来说,从左到右依次查找有效数字字符,直到遇到非有效数字字符,停止查找(不论后面是否还有数字,均不再查找)。将找到的当作数字返回. 与Number不同,Number是底层机制,parseInt是方法
parseInt("12px")
12
parseInt("width:12px")
NaN
parseInt("12px,24px")
12
parseInt() 里的值不是字符串的话,会先转为字符串,再找数字。
Number(true)
1//底层机制规定Number遇到true,则返回1
parseInt(true)
NaN//parseInt遇到非字符串,先将其转为字符串,true-》'true', 然后再找'true'中发现没有数字,所以返回NaN
parseInt(undefined)
NaN//undefined->'undefined'->非数字,所以是NaN
parseInt('')
NaN
- parseFloat(): 转为浮点数
parseFloat("12.5px")
12.5
- == :可能会出现将其他类型值转换为数字
1=='1'
true
0=='0'
true
0==false
true
1=='true'
false
- 减乘除运算:
var a = '12'
undefined
a - '2'
10 //先将'2'调用Number() 转为2, 再做减法运算。
5. 字符串类型
1. toString()
其他数据类型转换为字符串,通过调用.toString(), 调用后,直接在内容外面套上一对引号(除了普通对象)
- 数值型:
不能直接使用 数字.toString() , 会报错:Uncaught SyntaxError: Invalid or unexpected token
12.toString()
> VM94:1 Uncaught SyntaxError: Invalid or unexpected token
var a=12;
undefined
a.toString()
> '12'
- 布尔型: 布尔值外套一层’’
true.toString()
> 'true'
- NaN:
NaN.toString()
'NaN'
- null 和 undefined: 没有toString() 方法
null.toString()
> VM280:1 Uncaught TypeError: Cannot read properties of null (reading 'toString')
at <anonymous>:1:6
(anonymous) @ VM280:1
undefined.toString()
> VM318:1 Uncaught TypeError: Cannot read properties of undefined (reading 'toString')
at <anonymous>:1:11
- 数组:
[].toString()
''
[12].toString()
'12'
[12,23].toString()
'12,23'
[12,23,null].toString()
'12,23,'
[12,23,undefined].toString()
'12,23,'
- 正则:
/^$/.toString()
'/^$/'
- 普通对象: {}
普通对象的toString() 不是用来转换为字符串,而是用来获取数据类型的
({}).toString()
'[object Object]'
2. +
“+ ”在遇到数字时,即为数值运算加法;在遇到字符串时,即为字符串拼接
四则运算符里,只有“+” 是有歧义,需要注意,其他三个运算符都是数值运算,都需要将两端的对象转为数值。
'12' + 10
> '1210'
'12' - 10
> 2 //减号没有字符拼接的作用,所以需要将字符串'12' 调用Number() 转为12, 再进行减法运算
'12px'*10
> NaN // 转换只会调用Number() ,不会调用parseInt()或parseFloat()
'12'/10
> 1.2
true *10
> 10
[12] * 10
> 120
- 面试题测试
问:let a = 10 + null + true + [] + undefined + ‘珠’+ null + [] +10 + false;
析: 考察加号在遇到数值和字符串的处理
10 + null : null 调用Number() 变为0, 10 + null 变成10
10 + true : true 调用 Number() 变为1, 10 + 1 变成11
11+ [] : [] 是引用类型,调用Number() 转换时,先调用toString() 变成"", 此时加号做拼接, 11 + [] 变成 “11”
11 + undefined + ‘珠’ + null + [] +10 + false : “11undefined珠null10false”
let a = 10 + null + true + [] + undefined + '珠' + null + [] +10 + false;
undefined
a
'11undefined珠null10false'
如果转换过程中遇到的是其他运算符,则继续进行转换,而没有拼接的说法
let b = 10 +true -[]
undefined
b
11// [] 调用toString() 转为了"", 再调用Number() 转为空
3. i++/ i+=1/ i=i+1/ i–/i-=1/i=i-1
- i++/ i+=1/ i=i+1
由于+ , 有字符串拼接和数学运算,但是对于i++ , 是完完全全的数学运算,且运算完后i为字符串。而i+=1 和i=i+1 如果i为字符串的话,则是字符串的拼接。 - i–/i-=1/i=i-1
i-- / i-=1 / i=i-1 是纯粹的数学运算,且结果也是Number型。
例:
b++ 是数值操作, b也变成了number
let b ='1'
typeof b //'string'
typeof b++ //'number'
b //2
c+=1和c=c+1操作,字串拼接操作
let c ='2'
c+=1 //'21'
typeof c //'string'
let d = '1'
d=d+1; //'11'
typeof d //'string'
i-- , i-=1 和i=i-1操作,均为数值运算
let e='3'
e-- //3
typeof e // 'number'
let f = '4'
f-=1; //3
typeof f //'number'
6. 布尔值
只有两个值: true 和 false
其他类型转为布尔值
只有0, NaN, “”, null, undefined 这五个值转换后是false, 其他均为true,没有例外。
- Boolean()
Boolean("")
false
Boolean(" ")
true //只有空字符串才是false,空格是非空字符串
Boolean([])
true //空数组不属于五种类型
Boolean({})
true //空对象不属于五种类型
- !/!!
! 取反;
!! 取反再取反,等于直接将值转为bool, 相当于Boolean()
!1
false
!!1
true
- 条件判断
if 括号内如果是单纯的数字或数学运算,而非==/===/!=/>=则转为布尔
if("1px")
console.log("哈哈") //"1px" 为true
VM1843:2 哈哈
undefined
if("1px"+1)
console.log("哈哈") //"1px"+1 字符串拼接,变成"1px1" 为true
VM1854:2 哈哈
undefined
if("1px"-1)
console.log("哈哈")//-只能为减号,"1px" 调用Number() 变成NaN,NaN-1 仍为NaN,故"1px"-1 为false,此处不会输出“哈哈”
undefined
7. null 和 undefined
null : 意料之中, 不占空间。 常用于一开始不知道该对象是啥值和类型,后期赋值的情形;
undefined: 意料之外, 定义变量后,没有赋值,会出现undefined(是由浏览器决定赋值)。
8. 引用类型–普通对象类型
普通对象类型是描述对象的一种方式,由键值对组成(所有对象都是键值对)。其中,键只能是数字或字符串,且键不能重复。每组键值对之间用逗号分隔。其中,键只能是字符串或数字。
1. 定义
使用{} 里面放入键值对,键值对之间用逗号分隔
var dog = {
category: "animal",
skill: "bite"
}
undefined
dog
{category: 'animal', skill: 'bite'}
2. 增
新增属性两种方式:
- 对象名.属性名: 属性名是不存在的属性名,则为新增属性
dog.legs=4
4
dog
{category: 'animal', skill: 'bite', legs: 4}
- 对象名[属性名]:
dog['color']='white'
'white'
dog
{category: 'animal', skill: 'bite', legs: 4, color: 'white'}
使用对象名[属性名]方式时,如果属性名是字符串,则需要加引号新增。如果属性名是数字,则只能使用此方法新增,而不能用. 来调用。
dog[color]='white'
VM2292:1 Uncaught ReferenceError: color is not defined
at <anonymous>:1:5 //color 必须要加引号
对象名[属性名] 中的属性名可以是数字
dog[1]='小白'
'小白'
dog
{1: '小白', category: 'animal', skill: 'bite', legs: 4, color: 'white'}
如果属性名是数字,则不能使用点的方式赋值或调用
dog.2="12kg"
VM2530:1 Uncaught SyntaxError: Unexpected number
如果属性名不存在,则返回undefined. 因为意料之外,未想到会调用。
dog
{category: 'animal', skill: null, legs: 4, color: 'yellow'}
dog['name']
undefined
3. 删
删除分为两种,一种是真删除,一种是假删除。真删除是将属性名和属性值都删除掉,而假删除仅仅删掉属性值。
- 真删除
使用delete
dog
{1: '小白', category: 'animal', skill: 'bite', legs: 4, color: 'white'}
delete dog[1]
true
dog
{category: 'animal', skill: 'bite', legs: 4, color: 'white'} // dog对象中的1及其对应值均被删除
- 假删除
将某个属性名对应的属性值赋值为null
dog
{category: 'animal', skill: 'bite', legs: 4, color: 'white'}
dog['skill']=null //将某个属性值赋值为null,就可以做假删除
null
dog
{category: 'animal', skill: null, legs: 4, color: 'white'}
4. 改
对于某个已存在的属性名直接赋值,就可以覆盖原来的属性值.
dog
{category: 'animal', skill: null, legs: 4, color: 'white'}
dog['color']='black'
'black'
dog
{category: 'animal', skill: null, legs: 4, color: 'black'} //将color 原来的属性值改为black
和新增一样,两种调用属性的方式:
dog.color='yellow' // 使用点调用方式,将值修改,只有属性名为字符串才可以,数值不可以
'yellow'
dog
{category: 'animal', skill: null, legs: 4, color: 'yellow'}
5. 查
对象名.属性名: 仅针对属性名是字符串
对象名[属性名]: 针对属性名是字符串或数值
in : 返回TRUE或FALSE, 判断当前键是否在对象中
let obj ={
name: '戴安娜',
age:24
}
console.log('name' in obj); // true
对象的属性名只能是字符串或数字,所以引用字符串型的键时,必须要加引号:
var name ='札尔斯';
var obj ={
name: '戴安娜',
age:24
}
console.log(obj[name]); // undefined
console.log(obj['name']); //戴安娜
9. 引用数据类型–数组
数组是一个特殊的对象,所以它也由键值对组成,只不过它特殊在,键是默认生成的,不需要手动去定义,而在中括号内我们写的就是值。同一个数组中的值的数据类型可以不同。
let arr1=[12,true,"小白",{}]
undefined
arr1
(4) [12, true, '小白', {…}]
0: 12
1: true
2: "小白"
3: {}
length: 4 // 数组都有一个默认的属性名叫length,所以我们在调用数组长度的时候,可以直接写arr1.length 或arr1['length']
[[Prototype]]: Array(0)
10. 基本数据类型和引用数据类型底层运行机制区别
基本数据类型是对值进行操作,而引用数据类型是对堆内存的地址进行操作
栈内存作用: 1. 存储基本类型变量和值;2. 执行代码
let a = 12;
let b = a;
b = 13;
console.log(a);
let n = {
name: "小白"
};
let m = n;
m.name = '小新';
console.log(n);
结果为:
12
{name: '小新'}
运行原理:
- 浏览器提供空间(内存)
- 浏览器提供主线程来一条条执行代码
练习题1 :
let n = [10, 20];
let m = n;
let x = m;
m[0] = 100;
x = [30, 40];
x[0] = 200;
m = x;
m[1] = 300;
n[2] = 400;
console.log(n, m, x);
输出结果:
[100, 20, 400]
[200, 300]
[200, 300]
解析图解:
此处需要注意x=[30,40] 是指向一个新的数组,需要新开辟一个堆存储空间。
练习题2:阿里面试题1
let a = {
n: 1
};
let b = a;
a.x = a = { n: 2 };
console.log(a.x);
console.log(b);
console.log(b.n);
console.log(b.x.n)
运行结果:
undefined
{n: 1,
x: {n: 2}}
1
2
等于号先处理左边。a.x=a={n:2} ==》 a.x={n:2}, a={n:2}
![在这里插入图片描述](https://img-blog.csdnimg.cn/f6584752d4bd402b810bd966f7dd33af.png#pic_center
练习题3
let a = { n: 1 };
let b = a;
a.x = b;
console.log(a.x);
console.log(b);
执行结果
执行图解
练习题4:
<script>
var a = 0;
var b = a;
b++;
alert(a);
var o = {};
o.a = 0;
var b = o;
b.a = 10;
alert(o.a);
</script>
结果为10;
练习题5:
对于数组,在画图时,需要将堆里面标记上0,1,2,…
11. 数据类型判断
- typeof [val] 运算符
typeof 检测出来的值,两个特点:
- 是个字符串
- 引号中包含对应的数据类型(控制台console里, 黑色代表字符串,蓝色代表数字)
typeof 1
'number'
typeof NaN
'number'
typeof null
'object'
typeof undefined
'undefined'
typeof "1"
'string'
typeof true
'boolean'
typeof {}
'object'
typeof []
'object'
typeof /^$/
'object'
typeof Boolean
'function'
typeof缺点:
- typeof null : 检测出是object,实际是数字;
- typeof 对象: 检测出的全是object,无法做进一步区分;
练习题:
console.log(typeof typeof typeof []);
"string" // typeof []-->"object" , typeof "object"-->"string", typeof "string"-->string
- constructor
- instanceof
- object.prototype.toString.call(): 最好的检测数据类型的方法
JS数据类型基础知识练习
!(!"Number(undefined)");
// !! 是将内容转为布尔型,"xxx" 里面非空,所以结果是true。
// 引申: Number(undefined) --》NaN
isNaN(parseInt(new Date())) + Number([1]) + typeof undefined;
// new Date() 返回的是日期对象,结果是 Wed Aug 17 2022 07:41:29 GMT+0800 (中国标准时间), parseInt(xx)-》NaN
// isNaN(NaN)-->true
// Number([1]) -->1, true+1-->2
// typeof undefined-->返回一个string型,结果是“undefined”, 2+“undefined”->"2undefined"
Boolean(Number("")) + !isNaN(Number(null)) + Boolean("parseInt([])") + typeof !(null);
// Number("")-->0, Boolean(Number(""))-->false
// Number(null)-->0,isNaN(Number(null))-->false, !isNaN(Number(null)) -->true, false+true(数字运算)--》1
// Boolean("parseInt([])") --》 非空,为true, 1+ true =2
// !(null) -> 非空(! 表示布尔型) -》typeof !(null)-> ‘boolean’
// 结果:“2boolean”
// 引申: parseInt([]) --》NaN, 不是0 ([]先转换为字符串"", 再找数字, 没有数字,返回NaN)
parseFloat("1.6px") + parseInt("1.2px") + typeof parseInt(null);
// parseFloat("1.6px")-->1.6
// parseInt("1.2px")-->1
// parseInt(null)-->"null"->NaN, typeof NaN ->'number'
// '2.6number'
isNaN(Number(!!Number(parseInt("0.8"))));
// parseInt("0.8")->0, Number(0)->0, !! -》 false;
// Number(false)->0
// isNaN(0)-->false
console.log(1 + "2" + '2');
//'122'
!typeof parseFloat("0");
// !'number'-->false
Number("");
// 0