0%

基本类型

基本类型

JavaScript中的基本数据类型有:boolean、null、undefined、number、string、symbol、BigInt。

引用类型有:Object、Array、Function、Match、Date、RegExp、Set、WeakSet、Map、WeakMap…

该标题所示基本类型意为 新手初始学习 的一些数据类型。

一、 类型检测

1.1 typeof

typeof 能够正确的返回以下数据类型(在不使用构造函数实例化的前提下,否则返回Object)

  • Number、String、undefined、Object、Boolean、function

    1
    2
    3
    4
    5
    6
    7
    8
    console.log(
    typeof 1, //number
    typeof "", //string
    typeof undefined, //undefined
    typeof {}, //object
    typeof false, //boolean
    typeof function () {} //function
    );

不能正确判断的情况:

—使用构造函数实例化为对象,则返回Object。

1
2
3
let as = "Ashun";
let str = new String("Ashun");
console.log(typeof as, typeof str); //string object

typeof []

1
console.log(typeof []);  //object

—关于typeof null==='object'

首先要说明的是,null**不是!**对象,但为什么返回结果为object呢?

解释: 这是JS的历史遗留bug,在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象然而 null 表示为全零,所以将它错误的判断为 object 。

—如果要正确判断能够使用构造函数实例化的以上数据类型、或Array。可以使用instanceof 👇


1.2 instanceof

instanceof 运算符用于检测构造函数的 prototype 属性(原型对象)是否出现在某个实例对象的原型链上。也可以理解为:判断是否为某个对象的实例,typeof不能区分Array,但instanceof可以。instanceof的返回结果为Boolean。

—判断Array

1
console.log([] instanceof Array);		//true

—检测typeof能够正确返回的数据类型(在不 手动实例化 的情况下)

​ 只有obj、function能够返回正确的结果,其余返回false的数据类型如果通过构造函数实例化,则能够正确判断。

1
2
3
4
5
6
7
console.log("" instanceof String);									//false
console.log(1 instanceof Number); //false
console.log(true instanceof Boolean); //false
console.log(function () {} instanceof Function); //true
console.log({} instanceof Object); //true

//这里undefined不能够判断,因为其没有构造函数。

1.3 值类型与对象

下面是使用字面量与对象方法创建字符串,返回的是不同类型。

1
2
3
let as = "astfn";
let ext = new String(".github.io");
console.log(typeof as, typeof ext); //string object

只有对象才能够调用属性和方法,但在JS中也可以使用值类型调用方法,因为它会在执行时将值类型转为对象。

1
2
3
[].concat(["ashun"]);
"Ashun".length
(1.266).toFixed(2)

二、String

2.1 声明定义

  • 构造函数声明

    1
    2
    let str=new String("ashun");
    console.log(str.length);
  • 字面量声明

    单引号’’、双引号””、模板字面量``。

    1
    2
    3
    4
    let str="ashun";
    let str1='ashun';
    let str2=`ashun`;
    console.log(str.length);

2.2 转义符号

有些字符在js中具有特殊含义,需要进行转义。

1
2
3
let site="site:\"ashuntefannao.com\"";
console.log(site)
//site:"ashuntefannao.com"

常用转义符号列表如下

符号 说明
\t 制表符
\n 换行
\ 斜杠符号
\‘ 单引号
\“ 双引号

—在使用RegExp时,有很多符号都具有特殊含义,如果需要匹配某些字符,也需要进行转义,在RegExp总结中会详解。


2.3 连接运算符

使用 + 可以连接多个内容组合成字符串,经常用于组合输出内容使用。

1
2
3
4
5
let name = "ashun";
age = 18;
console.log(name + '今年' + age + '岁了');
name+="tefannao";
console.log(name);

—使用String的内置方法str.concat(str1,…strN)也能够完成字符串的合并操作。该方法不会改变原字符串

1
2
3
let str = "ashun";
console.log(str.concat("Ashun", "Tefannao"));//ashunAshunTefannao
console.log(str);//ashun

2.4 模板字面量

(模板字面量`` )可以声明字符串变量,也可拼接String,相比传统方式使用 + 来链接String,字面量更加的灵活和方便。

优点:

  • 可以包含变量和表达式${}
  • 可在模板字面量中换行
  • 可以嵌套使用
1
2
3
let name="ashun";
function getAge(){return 18};
console.log(`${name}今年${getAge()}岁了`)
1
2
3
4
5
6
7
8
9
console.log(`Ashun
Te
FanNao
`);
/*
Ashun
Te
FanNao
*/
1
2
3
4
5
6
let arr=[{title:"ashun"},{title:"Ashun"},{title:"ashuntefannao.com"},];

function template(arr){
return `<ul>${arr.map(v=>`<li>${v.title}</li>`).join("")}</ul>`;
}
document.write(template(arr))

2.5 标签模板

功能:提取出普通字符串变量,交由标签函数处理

使用步骤:

  1. 定义处理标签模板的函数

  2. 调用标签模板函数,处理字符串

    1
    functionName `StringContent`
1
2
3
4
5
6
let obj={name:"阿顺",age:18};
function tagTemplate(str,...argus){
console.log(str); //["info:", "今年", "岁了"]
console.log(argus); //["阿顺", 18]
}
tagTemplate `info:${obj.name}今年${obj.age}岁了`;

—若String开头就使用了变量,那么获取普通字符串Arr的第一个元素为空字符串""

—同理,若String的结尾使用了变量,获取普通字符串Arr的最后一个元素也为""

1
2
3
4
5
6
let name="ashun";
tag `${name}18岁了`;
function tag(str,...argu){
console.log(str); //["", "18岁了"]
console.log(argu) //["ashun"]
}

2.6 String属性

属性 描述
length 字符串的长度
constructor 访问其构造函数
prototype 通过其可扩展String的属性和方法。

2.7 String方法

2.7.1 大小写转换
方法 描述
toLowerCase() 把字符串转换为小写。
toUpperCase() 把字符串转换为大写。
2.7.2 移除空白
方法 描述
trim() 移除字符串左右两侧的空白
trimLeft() 移除字符串左侧的空白
trimRight() 移除字符串右侧的空白
2.7.3 获取单字符
方法 描述
charAt(index) 返回在指定位置的字符。
charCodeAt(index) 返回在指定位置字符的 Unicode 编码。

—使用索引形式,获取单字符

1
console.log("Ashun"[2]);
2.7.4 截取字符串

slice、substr、substring这些操作都不会改变原字符串,而是返回一个新的string。

slice(n1,n2)

参数1:起始位置,参数2:结束位置 相当于区间左闭右开[n1,n2),参数可为负数,意为自后向前的字符。

关于参数:

  • 没有传参时,截取整个sring

  • 只有一个参数

    • 正数:从n1截取到尾部。
    • 负数:自后向前截取n1个字符。
1
2
3
4
5
6
7
8
9
10
11
12
console.log("Ashun".slice(-4));			//shun

console.log("Ashun".slice(1)); //shun

console.log("Ashun".slice(1, 2)); //s

console.log("Ashun".slice(1, -1)); //shu

console.log("Ashun".slice(-1, -5)); //shun

//截取的规则必须是自前向后,n1<n2
console.log("Ashun".slice(-4, -2)); //sh

substr(n1,n2)

参数1:起始位置,参数2:自前向后截取n2个字符(数量包含起始位置字符),因此参数2不可为负数。

关于参数:

  • 没有传参时,截取整个sring

  • 只有一个参数(同slice)。

1
2
3
4
console.log("Ashun".substr(1)); 							//shun
console.log("Ashun".substr(-4)); //shun
console.log("Ashuntefan".substr(1, 3)); //shu
console.log("Ashuntefan".substr(-3, 2)); //fa

substring(n1,n2)

关于参数:对比slice。

  • 相同点
    • 没有传参时,截取整个sring
    • 参数1、2的意义与slice相同区间左闭右开[n1,n2)
  • 不同点
    • 参数不能为负数,否则会视为0
    • 自动将两个参数中较小的参数作为起始位置。
1
2
3
4
5
6
7
8
9
10
11
12
console.log("Ashun".substring(1));					//shun

//二者结果相同
console.log("Ashun".substring(1, 5)); //shun
console.log("Ashun".substring(5, 1)); //shun

//相当于substring(0)
console.log("Ashun".substring(-2)); //Ashun

//相当于substring(1,0)===substring(0,1)
console.log("Ashun".substring(1, -1)); //A
console.log("Ashun".substring(1, 0)); //A

2.7.5 检索字符串
方法 描述
indexOf(str,index) 返回某个指定的字符串值在字符串中首次出现的索引。匹配失败返回-1。参数2(可选)指定开始查找的位置
lastIndexOf(str,index) 自后向前检索字符串,返回结果同indexOf(),参数2(可选)指定开始查找的位置(自后向前)
includes(str,index) 是否包含指定的子字符串,参数2(可选)指定开始查找的位置(自后向前)
match(Regexp) 查找找到一个或多个正则表达式的匹配。
search(str/Regexp) 相对于indexof()可以传入Regexp
startsWith(str,index) 是否以指定的str开头。index:检索的起始位置。
endsWith(str,index) 是否以指定的str结束,index:检索的结束位置。

—indexOf

1
2
3
4
5
6
console.log("Ashun、ashun".indexOf("shun")); 	//1
console.log("Ashun".indexOf("as")); //-1

let str = "ashunashun";
console.log(str.indexOf("a"));//0
console.log(str.indexOf("a", 2));//5

—lastIndexOf

1
2
3
4
5
6
console.log("Ashun、ashun".lastIndexOf("shun")); 	//7
console.log("Ashun".lastIndexOf("as")); //-1

let str = "ashunashun";
console.log(str.lastIndexOf("a"));//5
console.log(str.lastIndexOf("a", 3));//0

—includes

1
2
console.log("Ashun".includes("shun")); 		//true
console.log("Ashun".includes("as")); //false

—match

1
2
3
let reg = new RegExp("shun", "g");
console.log("Ashun、ashun".match(reg)); //["shun", "shun"]
console.log("Ashun、ashun".match(/[0-9]/)); //null

—search

1
2
3
let reg = new RegExp("shun", "g");
console.log("Ashun、shun".search(reg)); //1
console.log("Ashun、shun".search("、")); //5

—startsWith

1
2
console.log("Ashuntefannao".startsWith("A"));				//true
console.log("Ashuntefannao".startsWith("shun", 1)); //true

—endsWith

1
2
console.log("Ashuntefannao".endsWith("fannao")); 		//true
console.log("Ashuntefannao".endsWith("shun", 5)); //true

2.7.6 替换字符串

replace(matchStr,replaceStr) 方法用于字符串的替换操作

1
2
let site = "Ashuntefannao.com";
console.log(site.replace("Ashuntefannao", "ashun"));

默认只替换一次,如果全局替换需要使用正则(更强大的使用会在正则表达式章节介绍)

1
2
let str = "Ashun、shun";
console.log(str.replace(/shun/g, "SHUN"));

使用字符串替换来生成关键词链接

1
2
3
4
5
6
let keys = ["Js", "css"];
let str = "Ashun喜欢Js和css知识";
str = keys.reduce((pre, key) => {
return pre.replace(key, `<a href="?key=${key}">${key}</a>`);
}, str);
document.body.innerHTML = str;

使用正则表达式完成替换

1
2
3
let str = "Ashun喜欢Js和css知识";
str = str.replace(/(css|Js)/g, `<a href="?key=$&">$&</a>`);
document.body.innerHTML = str;

2.7.7 重复生成

repeat(num)完成字符串的重复生成

下例是根据参数重复生成星号

1
2
3
4
5
function repeat(str = "*", num = 3) {
return str.repeat(num);
}
console.log(repeat());
console.log(repeat("8 ", 8));

下面是模糊电话号码

1
2
3
let phone = "89452176335";
console.log(phone.slice(0, 3).concat("*".repeat(5)).concat(phone.slice(-3)));
//894*****335

2.7.8 类型转换
String->Array

使用split(str)方法:以参数str分割String为Array。

1
2
3
console.log("Ashun".split(""));								//["A", "s", "h", "u", "n"]
console.log("ashun,Ashun".split(",")); //["ashun","Ashun"]
console.log("Ashuntefannao".split("te")); //["Ashun","fannao"]
Number->String
  • +””
  • String(Number)
  • num.toString()
Array->String
  • arr.join(str)

    join(str)方法:以参数str合并Array的每个元素变为String。

    1
    console.log(["2020", "3", "13"].join("-"));			//2020-3-13
  • arr.toString()

js中大部分类型都是对象,可以使用类方法 toString转化为字符串

1
2
3
4
5
let as = 99;
console.log(typeof as.toString()); //string

let arr = ['Ashun', '阿顺'];
console.log(typeof arr.toString()); //string

三、Boolean

隐式转换

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

数据类型 true false
String 非空字符串 空字符串
Number 非0的数值 0 、NaN
Array 不与Boolean比较时 参与比较的空数组
Object 不与Boolean比较时
undefined undefined
null null
NaN NaN

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

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

下面是一个典型的例子,字符串在与Boolean比较时,两边都为转换为数值类型后再进行比较。

1
2
3
4
console.log(Boolean("ashun")); //true
console.log(Number("ashun")); //NaN
console.log("ashun" == true); //false
console.log("1" == true); //true

数组的表现与字符串原理一样,会先转换为数值

1
2
3
4
5
6
console.log(Number([])); //0
console.log(Number([3])); //3
console.log(Number([1, 2, 3])); //NaN
console.log([] == false); //true
console.log([1] == true); //true
console.log([1, 2, 3] == true); //false

—引用类型Object、Array不与Boolean比较时,值为

1
2
if ([]) console.log("true");
if ({}) console.log("true");

显式转换

使用 !!! 转换布尔类型

1
2
3
4
5
6
7
8
let as = '';
console.log(!!as); //false
as = 0;
console.log(!!as); //false
as = null;
console.log(!!as); //false
as = new Date("2021-3-13 16:42");
console.log(!!as); //true

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

1
2
3
4
5
6
7
8
let as = '';
console.log(Boolean(as)); //false
as = 0;
console.log(Boolean(as)); //false
as = null;
console.log(Boolean(as)); //false
as = new Date("2021-3-13 16:42");
console.log(Boolean(as)); //true

实例操作

下面使用Boolean类型判断用户的输入,并给出不同的反馈。

1
2
3
4
5
6
while (true) {
let test = prompt("请输入Ashuntefannao成立年份").trim();
if (!test) continue;
alert(test == 2020 ? "回答正确" : "答案错误!假粉一个");
break;
}

四、Number

声明定义

使用对象方式声明

1
2
let as = new Number(3);
console.log(as+3); //6

Number用于表示整数和浮点数,数字是 Number实例化的对象,可以使用对象提供的丰富方法。

1
2
let num = 99;
console.log(typeof num);

基本函数

Number.isInteger(num):判断是否为整数

1
console.log(Number.isInteger(1.2));	//false

Number.isNaN(message):判断参数是否为无效数值

1
2
let as = "ashun" / 0;
console.log(Number.isNaN(as)); //true

num.toFixed(n):四舍五入保留n位小数。

1
console.log((16.556).toFixed(2)); // 16.56

num.toString():转为String,js中几乎所有类型都具有该方法。

1
console.log(typeof (2).toString())

NaN

表示无效的数值,下例计算将产生NaN结果。

1
2
3
console.log(Number("ashun")); //NaN

console.log(2 / 'ashun'); //NaN

NaN不能使用 == 比较,使用以下代码来判断结果是否正确

1
2
3
4
5
let res = 2 / 'ashun';
if (Number.isNaN(res)) {
console.log('Error');
}
console.log(res == NaN); //false

也可以使用 Object.is 方法判断两个值是否完全相同

1
2
let res = 2 / 'ashun';
console.log(Object.is(res, NaN)); //true

类型转换

other->Number

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

1
2
3
4
5
6
7
8
console.log(Number('Ashun')); //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

parseInt

提取字符串头部去除空白后的数字转为整数。

1
2
console.log(parseInt('  99houdunren'));	//99
console.log(parseInt('18.55')); //18

parseFloat

提取字符串头部去除空白后的数字转为浮点数。

1
2
console.log(parseFloat('  99houdunren'));	//99
console.log(parseFloat(' 18.55')); //18.55

浮点精度

大部分编程语言在浮点数计算时都会有精度误差问题,下面来看JS中的表现形式

1
2
let num = 0.1 + 0.2
console.log(num)// 结果:0.30000000000000004

这是因为计算机以二进制处理数值类型,上面的0.1与0.2转为二进制后是无穷的

1
2
console.log((0.1).toString(2)) //0.0001100110011001100110011001100110011001100110011001101
console.log((0.2).toString(2)) //0.001100110011001100110011001100110011001100110011001101

处理方式

一种方式使用toFixed 方法进行小数截取

1
2
3
4
console.log((0.1 + 0.2).toFixed(2)) //0.3

console.log(1.0 - 0.9) //0.09999999999999998
console.log((1.0 - 0.9).toFixed(2)) //0.10

将小数转为整数进行计算后,再转为小数也可以解决精度问题

1
2
3
4
5
6
7
8
9
10
11
Number.prototype.add = function (num) {
//取两个数值中小数位最大的
let n1 = this.toString().split('.')[1].length
let n2 = num.toString().split('.')[1].length

//得到10的N次幂
let m = Math.pow(10, Math.max(n1, n2))

return (this * m + num * m) / m
}
console.log((0.1).add(0.2))

推荐做法

市面上已经存在很多针对数学计算的库 mathjsdecimal.js等,我们就不需要自己构建了。下面来演示使用 decimal.js 进行浮点计算。

1
2
3
4
5
<script src="https://cdn.bootcss.com/decimal.js/10.2.0/decimal.min.js"></script>

<script>
console.log(Decimal.add(0.1, 0.2).valueOf())
</script>

五、Math

Math 对象提供了众多方法用来进行数学计算,下面我们介绍常用的方法,更多方法使用请查看 MDN官网了解。

取极限值

使用 minmax 可以取得最小与最大值。

1
2
3
console.log(Math.min(1, 2, 3));

console.log(Math.max(1, 2, 3));

—从数组中取值

1
2
3
let arr = [1, 2, 3];
console.log(Math.max.apply(Math, arr));
console.log(Math.max(...arr));

舍入处理

Math.ceil(num)向上取整

1
console.log(Math.ceil(1.111)); //2

Math.floor(num)向下取整

1
console.log(Math.floor(1.555)); //1

Math.round(num)四舍五入处理

1
console.log(Math.round(1.5)); //2

random

random 方法用于返回[0,1)的随机数。

返回[0,n)的随机数 公式为:Math.floor(Math.random()*n)

1
2
const number = Math.floor(Math.random() * 5);
console.log(number);

返回[0,n]的随机数 公式为:Math.floor(Math.random()*(n+1))

1
2
const number = Math.floor(Math.random() * (5+1));
console.log(number);

下面取[2,5)的随机数 公式为:min+Math.floor(Math.random()*(Max-min))

1
2
const number = Math.floor(Math.random() * (5 - 2)) + 2;
console.log(number);

下面取[2,5]的随机数 公式为:min+Math.floor(Math.random()*(Max-min+1))

1
2
const number = Math.floor(Math.random() * (5 - 2 + 1)) + 2;
console.log(number);

取绝对值

Math.abs(num):取num的绝对值。

1
console.log(Math.abs(-999));//999

次幂运算

Math.pow(x,y):返回 x 的 y 次幂。

1
2
console.log(Math.pow(10, -2)); //0.01
console.log(Math.pow(1, -2)); //1

六、Date

网站中处理日期时间是很常用的功能,通过 Date 类型提供的丰富功能可以非常方便的操作。

声明日期

获取当前日期时间

1
2
3
4
5
6
7
8
9
let now = new Date();
console.log(now);
console.log(typeof date); //object (由构造函数实例化为Object)


//直接使用函数获取当前时间
console.log(Date());
console.log(typeof Date()); //string (直接使用Date()方法)

根据指定的日期与时间定义日期对象

1
2
3
4
5
let now = new Date('2028-02-22 03:25:02');
console.log(now);

now = new Date(2028, 4, 5, 1, 22, 16);
console.log(now);

使用展示运算符处理更方便

1
2
3
let info = [2021, 3, 14, 10, 51, 19];
let date = new Date(...info);
console.dir(date);

时间戳

js内的时间戳指的是当前时间1970年1月1日00:00:00之间的毫秒数

获取时间戳

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*	获取指定时间对象的时间戳,可通过内置方法来获取。
*/
let as = new Date(2021,3,14,11,06,23);
console.log(as); //w3c标准时间
console.log(as.getTime()); //getTime()获取as的时间戳
console.log(as.valueOf()); //valueOf()获取as的时间戳
console.log(as*1); //转为数字即时间戳

/* 获取当前时间戳
*/
console.log(Date.now());
console.log(new Date().getTime());
console.log(new Date().valueOf());
console.log(new Date()*1); //转为数字即时间戳

计算脚本执行时间Date.now()

1
2
3
4
const start = Date.now();
for (let i = 0; i < 2000000; i++) {}
const end = Date.now();
console.log(end - start);

当然也可以使用控制台测试console.time("name") && console.timeEnd("name")

1
2
3
console.time("testFor");
for (let i = 0; i < 20000000; i++) {}
console.timeEnd("testFor");

类型转换

w3c->时间戳

  • 内置方法获取getTime()\valueOf()
  • 将日期转为数值类型就是转为时间戳,单位是毫秒。
1
2
3
4
5
6
7
8
let as = new Date("2020-2-22 10:33:12");
console.log(as * 1);

console.log(Number(as));

console.log(as.valueOf())

console.log(date.getTime());

时间戳->w3c

  • 实例化Date,并将时间戳作为参数传入。

有时后台提供的日期为时间戳格式,下面是将时间戳转换为标准日期的方法

1
2
3
const date = new Date().getTime();
console.log(date);
console.log(new Date(date));

封装时间函数

封装函数用于复用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function getCurrentTime(date = new Date(),modle = "YYYY/MM/DD/HH/mm/ss") {
let newDate = {
YYYY: date.getFullYear(),
MM: date.getMonth() + 1,
DD: date.getDate(),
HH: date.getHours(),
mm: date.getMinutes(),
ss: date.getSeconds(),
};
for (let key in newDate) {
modle = modle.replace(key, newDate[key]);
}
return modle;
}
console.log(getCurrentTime());
console.log(getCurrentTime(new Date(), "YYYY-MM-DD"));

下面是系统提供的日期时间方法,更多方法请查看 MDN官网

方法 描述
Date() 返回当日的日期和时间。
getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。
getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6)。
getMonth() 从 Date 对象返回月份 (0 ~ 11)。
getFullYear() 从 Date 对象以四位数字返回年份。
getHours() 返回 Date 对象的小时 (0 ~ 23)。
getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。
getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。
parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。
getTime() 返回 时间戳
valueOf() 返回 Date 对象的原始值。(时间戳)
toString() 把 Date 对象转换为字符串

moment.js

Moment.js是一个轻量级的JavaScript时间库,它方便了日常开发中对时间的操作,提高了开发效率。

更多使用方法请访问中文官网 http://momentjs.cn或 英文官网 https://momentjs.com

1
<script src="https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js"></script>

获取当前时间

1
console.log(moment().format("YYYY-MM-DD HH:mm:ss"));

设置时间

1
console.log(moment("2020-02-18 09:22:15").format("YYYY-MM-DD HH:mm:ss"));

十天后的日期

1
console.log(moment().add(10, "days").format("YYYY-MM-DD hh:mm:ss"));