# JavaScript 中的数据类型以及常见的数据处理手段 *JavaScript 技术栏* 文章将介绍 JavaScript 中常见的数据处理手段,包括 操作符、函数、数组 和 对象 等。通过了解这些基本概念,读者将能够更好地理解 JS 语言的核心,并在实际项目中应用这些知识来提高代码质量和效率。 ## 目录 [TOC] ## JS 中的数据类型 JavaScript中的数据类型主要包括基本类型和对象类型。基本类型是指字面量值,如数字、字符串、布尔值、null、undefined和symbol等。这些基本类型可以直接赋值给变量,并且可以参与各种运算符的操作。 JavaScript中的对象类型是由一组键值对组成的集合。对象可以包含其他对象,因此它们可以用来表示复杂的数据结构。  在JavaScript中,可以使用typeof运算符来判断一个值的类型。此外,还可以使用instanceof运算符来判断一个对象是否属于某个类的实例。 在处理数据时,JavaScript提供了许多内置函数和操作符来处理不同类型的数据。例如,可以使用算术操作符来处理数字类型的数据,使用字符串连接操作符来处理字符串类型的数据,使用数组操作符来处理数组类型的数据等。此外,JavaScript还提供了许多内置对象和类,如Math对象、Date对象、Array对象等,这些对象和类提供了许多有用的方法和属性,可以帮助我们更方便地处理数据。  总之,了解JavaScript中的数据类型和处理数据的常用手段是非常重要的,这可以帮助我们更好地理解和使用JavaScript语言,接下来我们先从基本数据类型开始进行演示与讲解。 ### 基本数据类型 #### 一. Undefined and Null Undefined类型只有一个值,即特殊值undefined。在使用var声明变量,但未对其加以初始化时,这个变量值就是undefined。 Null类型是第二个只有一个值的数据类型。其特殊值就是Null。从逻辑角度上看,null是一个空的对象指针。而这也正是使用typeof操作符检测null值,会返回“object”的原因。 ##### 1 创建数据 ```javaScript // 在这里我们创建了 null 以及 undefined 变量 let data1 = null; let data2 = undefined; ``` #### 二. 数值类型 在 JS 中 所有的数值类型统称为 number 类型,number 类型的数据支持运算符,能够进行 加减乘除 取余 位移 等计算,是数据分析中重要的一种数据类型,下面我们来针对此数据类型的使用进行展示。 ##### 1 创建数据 ```javaScript // 在这里我们创建了两个数值类型的变量 一个是浮点型 一个是整形 let data1 = 10.24; let data2 = 10; ``` ##### 2 操作运算符 ```javaScript let data1 = 10.24; let data2 = 10; console.info(data1 + data2) console.info(data1 - data2) console.info(data1 * data2) console.info(data1 / data2) ``` #### 三. 字符串类型 字符串类型就是人类时间中常见的句子,而之所以称之为字符串,其实是因为每个字符串就是很多字符按照一定的顺序传串起来形成的,字符串对象支持 加法 运算符,接下来就是针对字符串类型的使用示例。 ##### 1 创建字符串 ```javaScript let data = "this is a string!" ``` ##### 2 操作运算符 ```javaScript let data = "this is a string!" // 字符串类型支持 加号 运算符,代表追加操作,下面就是一个示例 let newData = data + ' data' // 打印最后的结果newData 最后的结果在 data 的基础上增加了一个新的字符串 console.info(newData) ``` ##### 3 常用的字符串函数 ###### indexOf 返回某个指定的字符串值在字符串中首次出现的位置的索引,如果没有找到则返回-1。 ```javaScript let data = "this is string data!" // 获取到 data 字符串中 第一个 'i' 出现的位置的索引 let indexNumber = data.indexOf('i') // 打印最终的结果 console.info(indexNumber) ``` 下面是运行结果 ``` 2 ``` ###### lastIndexOf 返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。 ```javaScript let data = "this is string data!" // 获取到 data 字符串中 第一个 'i' 出现的位置的索引 let indexNumber = data.lastIndexOf('i') // 打印最终的结果 console.info(indexNumber) ``` 下面是运行结果 ``` 11 ``` ###### substring 提取字符串中两个指定的索引号之间的字符,并在新的字符串中返回被提取的部分,需要注意的是提取规则为左闭右开区间。 ```javaScript let data = "this is string data!" // 获取到 data 字符串中 索引区间为 [3,10) 的子字符串 let subString = data.substring(3, 10) // 打印最终的结果 console.info(subString) ``` 下面是运行结果 ``` s is st ``` ###### toUpperCase 将字符串转换为大写。 ```javaScript let data = "This is String Data!" // 将字符串中所有的字符转换为大写 let res = data.toUpperCase() // 打印最终的结果 console.info(res) ``` 下面是运行结果 ``` THIS IS STRING DATA! ``` ###### toLowerCase 将字符串转换为小写。 ```javaScript let data = "This is String Data!" // 将字符串中所有的字符转换为小写 let res = data.toLowerCase() // 打印最终的结果 console.info(res) ``` 下面是运行结果 ``` this is tring data! ``` ###### replace 替换与正则表达式匹配的子串,相当于是将字符串中所有符合正则表达式的部分替换成为新的字符串,有关正则表达式的知识可以查看文章[《正则表达式 - 基础知识》](http://www.lingyuzhao.top/?/linkController=/articleController&link=-90585683 "《正则表达式 - 基础知识》") ```javaScript let data = "now time is 2023年12月1日 18:03!" // 将字符串中所有的数字转换为 * 在这里的正则表达式是 \d let res = data.replace(/\d/g, '*') // 打印最终的结果 console.info(res) ``` 下面是运行结果 ``` now time is ****年**月*日 **:**! ``` ###### split 把字符串分割为字符串数组,是的没错,返回的是一个数组 `String[]` 在 JS 中也可以任务其是列表; ```javaScript let data = "now time is 2023年12月1日 18:03!" // 将字符串 按照数字进行拆分 这里还是使用正则表达式 表达式为 \d+ let res = data.split(/\d+/g) // 打印最终的结果 console.info(res) ``` 下面是运行结果 ``` [ "now time is ", "年", "月", "日 ", ":", "!" ] ``` ###### trim 移除字符串两侧的空白符或其他预定义字符。 ```javaScript let data = " now time is 2023年12月1日 18:03! " + "\n" + "\n" + "\n" // 将字符串 中的前后的不可见字符去除 let res = data.trim() // 打印最终的结果 console.info(res) ``` 下面是运行结果 ``` now time is 2023年12月1日 18:03! ``` ###### concat 用于连接两个或更多的字符串,并返回新的字符串,相当于是 `+` 运算符。 ```javaScript let data = "1 + 2 = " // 在字符串的结尾拼接一个 3 以及一个 句号 let res = data.concat('3', '。'); // 打印最终的结果 console.info(res) ``` 下面是运行结果 ``` 1 + 2 = 3。 ``` ### 引用数据类型 #### 数组与列表 Array 由于JS是一个弱类型语言,因此在 JS 中 数组内可以存储任意的数据类型,接下来将开始演示如何创建以及使用数组。 ##### 创建数组 ```javaScript // 创建一个空数组 let array1 = [] // 创建具有默认数值的数组 在这里可以看到 其中的前两个是整形元素,第三个是字符串,第四个是整形,这也体现了 JS 的弱类型。 let array2 = [1, 2, 'zhao', 4] ``` ##### 向数组中追加元素 push 函数 通过 push 函数可以向数组中追加元素,需要注意的是此函数并不会返回一个新的数组,而是会作用在原数组上,这也是引用数据类型的一种特点,基本数据类型经过函数处理之后 往往都是会返回一个新的数据,引用数据类型则是直接作用在函数的调用者上,下面就是一个示例。 ```javaScript // 创建一个空数组 let array1 = [] // 追加一些元素 array1.push(1) array1.push(1) array1.push("zhao") // 打印元素 console.info(array1) ``` 下面是运行结果 ``` [ 1, 1, "zhao" ] ``` ##### 删除数组中的元素 在这里的删除操作有两种,但都是基于索引的删除,因此需要先了解什么是索引,如果不了解可以看下文章[《数组 是什么?- Java 版》](http://www.lingyuzhao.top/?/linkController=/articleController&link=55591292 "《数组 是什么?- Java 版》"),两种删除方式中,第一种是删除指定索引处的元素,另一种就是删除指定索引位置之后的元素,后者我们也称之为批量删除,接下来我们先来演示删除指定索引的元素 ```javaScript let arr = ["apple", "banana", "cherry", "dates", "elderberry"]; delete arr[2]; // 删除索引2的元素 会将索引2处的元素变为 undefined console.log(arr); // 输出: ["apple", "banana", undefined, "dates", "elderberry"] ``` 然后我们开始演示删除指定索引之后的元素,在这里我们将索引2以及其之后的元素都删除掉了。 ```javaScript // 删除索引2开始的3个元素 let arr = ["apple", "banana", "cherry", "dates", "elderberry"]; arr.splice(2, 3); // 删除索引2开始的3个元素 console.info(arr); // 输出: ["apple", "banana"] ``` 还有一种方式就是取出元素,通过`pop()`函数可以取出列表中结尾处的元素对象,是的就是字面意义中的取出,取出之后列表中就没有这个元素了,而我们可以将取出之后的元素继续使用,下面是一个示例。 ``` let arr = ["apple", "banana", "cherry", "dates", "elderberry"]; // 取出结尾处的元素 let data = arr.pop() console.info(arr); // 输出: ["apple", "banana", "cherry", "dates"] console.info(data) // 输出 elderberry ``` ##### 修改数组中的元素 修改操作基于索引操作来进行,在集合类的对象中,通过中括号就可以获取到其中元素对应的引用对象,因此我们可以直接针对中括号进行重新赋值,这样就可以实现数据的修改,下面是一个示例。 ```javaScript // 删除索引2开始的3个元素 let arr = ["apple", "banana", "cherry", "dates", "elderberry"]; // 修改其中 索引为 3 的元素 为 zhao arr[3] = 'zhao' // 最后打印数组 console.info(arr) ``` ##### 迭代数组中的元素 迭代操作同样是基于索引的,其本质其实就是一种循环操作,因此在这里我们也将学会循环相关的知识,下面我们来进行示例。 在这个例子中,我们使用for循环遍历数组arr,通过索引i来访问每个元素,并在每次循环中将其打印出来。 ```javaScript let arr = [1, 2, 3, 4, 5]; for (let i = 0; i < arr.length; i++) { console.log(arr[i]); } ``` 然后,如果不基于索引来进行迭代,也是可以进行的,下面就是一个例子,我们使用for...of循环遍历数组arr,直接访问每个元素的值,并在每次循环中将其打印出来。这种方法更简洁,但是不支持遍历对象的属性。 ```javaScript let arr = [1, 2, 3, 4, 5]; for (let value of arr) { console.log(value); } ``` 也可以通过 lambda 函数的方式,使用forEach函数遍历数组arr,并为每个元素传递一个回调函数。回调函数将在每次循环中执行,并将当前元素的值作为参数传递给它。这种方法与for循环类似,但是更易于使用 ```javaScript let arr = [1, 2, 3, 4, 5]; arr.forEach(function(value) { console.log(value); }); ``` ##### 对数组中的元素进行排序 sort 比如你有一个JSON数组,里面是一些人的信息,你想按照人的年龄进行排序。 你可以使用JavaScript的sort()函数,然后提供一个比较函数。 比较函数可以是这样的: ```javascript jsonArray.sort( // 在这个 lambda 中 如果返回负数 则不改变顺序,如果返回正数,则将后面的对象与前面的对象反转位置 (a, b) => a['age'] - b['age'] ) ``` ###### 简单举例 取出 age 最高的2个数据 下面有一个例子 获取到年龄TOP2 ```javascript let jsonArray = [ { "name":"zhao", "age":20 }, { "name":"AnLi Join", "age":45 }, { "name":"yang", "age":21 }, ] // 开始进行排序 jsonArray.sort( // 在这个 lambda 中 如果返回负数 则不改变顺序,如果返回正数,则将后面的对象与前面的对象反转位置 (a, b) => a['age'] - b['age'] ) // 获取到前 2 个对象 let res = []; res.push(jsonArray.pop()) res.push(jsonArray.pop()) // 打印最后的结果 console.info(res) ``` 最后的结果是 ``` [ { "name": "AnLi Join", "age": 45 }, { "name": "yang", "age": 21 } ] ``` 这会将jsonArray按照人的年龄从小到大排序。如果你想从大到小排序,只需要改变比较函数的返回值 ###### 简单举例 取出 销售额最高的 2 个数据 "finalTotalAmount" 是销售额字段 ```javascript let jsonArray = { "allData": [{ "id": "3443", "finalTotalAmount": "1449.00", "outTradeNo": "214537477223728", "provinceName": "青海", "regionName": "西北", "userName": "齐桂娣" }, { "id": "3444", "finalTotalAmount": "17805.00", "outTradeNo": "226551358533723", "provinceName": "江西", "regionName": "华东", "userName": "李斌" }, { "id": "3445", "finalTotalAmount": "16180.00", "outTradeNo": "754426449478474", "provinceName": "广东", "regionName": "华南", "userName": "舒瑾颖" }, { "id": "3446", "finalTotalAmount": "4922.00", "outTradeNo": "262955273144195", "provinceName": "澳门", "regionName": "华南", "userName": "庞怡婵" }] } // 提取出 list jsonArray = jsonArray['allData'] // 开始进行排序 jsonArray.sort( // 在这个 lambda 中 如果返回负数 则不改变顺序,如果返回正数,则将后面的对象与前面的对象反转位置 (a, b) => a['finalTotalAmount'] - b['finalTotalAmount'] ) // 获取到前 2 个对象 let res = []; res.push(jsonArray.pop()) res.push(jsonArray.pop()) // 打印最后的结果 console.info(res) ``` 下面是运行结果 ``` [ { "id": "3444", "finalTotalAmount": "17805.00", "outTradeNo": "226551358533723", "provinceName": "江西", "regionName": "华东", "userName": "李斌" }, { "id": "3445", "finalTotalAmount": "16180.00", "outTradeNo": "754426449478474", "provinceName": "广东", "regionName": "华南", "userName": "舒瑾颖" } ] ``` ##### 对数组中的元素进行聚合 reduce 在 JavaScript 中,我们可以使用数组的reduce方法来实现分组聚合分析。reduce方法会对数组中的每个元素执行一个减少函数,将其减少为单个输出值。通过在reduce函数中指定一个分类函数作为参数,我们只需要在聚合的 lambda 函数中去调用 reduce 即可! ```JavaScript const result = data.reduce((局部聚合结果对象, data中的某一行新的数据对象) => 局部聚合结果) ``` ###### 案例1 将数据集中 男生 与 女生分别存储到两个list中 思路其实就是按照 性别 进行分组,聚合手段就是追加到自己性别对应的 list 中,下面就是实现。 ```javaScript const data = [ { name: 'Alice', age: 25, gender: 'female' }, { name: 'Bob', age: 30, gender: 'male' }, { name: 'Charlie', age: 35, gender: 'male' }, { name: 'David', age: 40, gender: 'male' }, { name: 'Eve', age: 25, gender: 'female' }, ]; const result = data.reduce((accumulator, current) => { // 在这里的两个参数分别是 聚合的累计值 和 当前数值 // 如果我们想要将他们按照性别分组 首先就需要获取到当前人员对象的性别 const gender = current['gender']; // 然后判断当前性别之前是否被聚合过 if (gender in accumulator){ // 代表被聚合过 在这里直接进行累计聚合 由于是简单的分组 不涉及计算 所以在这里我们直接将当前的人追加到结果中的对应性别的数组中 accumulator[gender].push(current); } else { // 如果没有被聚合 过 我们就需要初始化一个容器 用来存储聚合数据 在这里是直接创建一个当前性别的数组 并在数组中追加当前人员 accumulator[gender] = [] accumulator[gender].push(current); } // 最后返回聚合结果 return accumulator; }, {}); console.log(result); ``` 接下来是计算结果 ``` { "female": [ { "name": "Alice", "age": 25, "gender": "female" }, { "name": "Eve", "age": 25, "gender": "female" } ], "male": [ { "name": "Bob", "age": 30, "gender": "male" }, { "name": "Charlie", "age": 35, "gender": "male" }, { "name": "David", "age": 40, "gender": "male" } ] } ``` ###### 案例2 将数据集中 男生 与 女生 的平均年龄计算出来 ``` const data = [ { name: 'Alice', age: 25, gender: 'female' }, { name: 'Bob', age: 30, gender: 'male' }, { name: 'Charlie', age: 35, gender: 'male' }, { name: 'David', age: 40, gender: 'male' }, { name: 'Eve', age: 25, gender: 'female' }, ]; const result = data.reduce((accumulator, current) => { // 在这里的两个参数分别是 聚合的累计值 和 当前数值 // 如果我们想要将他们按照性别分组 首先就需要获取到当前人员对象的性别 const gender = current['gender']; // 然后判断当前性别之前是否被聚合过 let obj = accumulator[gender]; if (obj !== undefined){ // 代表被聚合过 在这里直接进行累计聚合 由于是 age 的均值 所以需要计算人数以及 Σage 所以在这里进行对应的计算 // 我们可以在 结果的 sum 和 count 字段进行计算 obj['sum'] += current['age'] obj['count'] ++ } else { // 如果没有被聚合 过 我们就需要初始化一个容器 用来存储聚合数据 在这里是直接创建一个 包含 sum 和 age 的对象 accumulator[gender] = {} obj = accumulator[gender]; // 然后再赋初始值 obj['sum'] = current['age'] obj['count'] = 1 } // 最后返回聚合结果 return accumulator; }, {}); // 根据聚合结果 计算均值 for (let g in result) { // 获取到每个性别对应的 {sum,age} 对象 const json = result[g]; // 开始进行 avg 计算 以及 取 小数点后2位 json['avg'] = (json['sum'] / json['count']).toFixed(2) } // 打印结果 for (let g in result){ console.info(`性别 ${g} 的平均年龄为 ${result[g]['avg']}`) } ``` 下面是计算结果 ``` 性别 female 的平均年龄为 25.00 性别 male 的平均年龄为 35.00 ``` #### 对象与字典 Obj or Json 这里就是非常常用的 json 数据类型啦,我们可以在文章 [《前端 json 对象数据处理方法汇总》](http://www.lingyuzhao.top/?/linkController=/articleController&link=-28687176 "《前端 json 对象数据处理方法汇总》") 中查看到相关的知识点。 #### 函数引用 function 在之前学习到的 foreach 迭代中,传递给 foreach 的参数是一个 lambda 函数,这就意味着函数也是可以做为一个数据类型存在的,下面就是一个示例。 ``` const numbers = [1, 2, 3, 4, 5]; numbers.forEach(function(number) { console.log(number); }); ``` #### 日期与时间 Date ##### 创建日期对象 在 JavaScript 中,Date对象用于处理日期和时间。可以使用new Date()来创建一个新的Date对象。 ```JavaScript let date = new Date(); // 获取当前日期和时间 console.log(date); // "2023-03-28T14:35:07.876Z" ``` ##### 日期对象的函数 **getFullYear()**:返回4位数的年份(例如:2023)。 **getMonth()**:返回月份(0-11,0代表1月,11代表12月)。 **getDate()**:返回月份中的日期(1-31)。 **getHours()**:返回小时(0-23)。 **getMinutes()**:返回分钟(0-59)。 **getSeconds()**:返回秒数(0-59)。 **getMilliseconds()**:返回毫秒数(0-999)。 **getTime()**:返回自1970年1月1日00:00:00 UTC到该时间的毫秒数。 **getDay()**:返回一周中的第几天(0-6,0代表星期天)。 **getHours()**:返回本地时间的小时数(0-23)。 **setFullYear()**:设置年份。 **setMonth()**:设置月份。 **setDate()**:设置月份中的日期。 **setHours()**:设置小时。 **setMinutes()**:设置分钟。 **setSeconds()**:设置秒数。 **setMilliseconds()**:设置毫秒数。 **toLocaleDateString()**:将日期转换为本地化字符串。 **toLocaleTimeString()**:将时间转换为本地化字符串。 **toLocaleString()**:将日期和时间转换为本地化字符串。 **toISOString()**:将日期和时间转换为ISO 8601格式的字符串。 **toUTCString()**:将日期和时间转换为UTC格式的字符串。 ## 常用的内置库函数 ### 数值类型转换 #### 数值 -> 字符串 (toString) ```javaScript let data1 = 10.24; // 打印出数值类型的 data1 console.info(data1) // 打印出字符串类型的 data1 console.info(data1.toString()) ``` #### 字符串 -> 数值(parseInt(string)) ```javaScript // 定义一个字符串 字符串的内容为 "1024" let str = "1024"; // 将字符串转换为 数值 let number = parseInt(str) // 打印出 1024 + 10 的结果 console.info(number + 10) ``` ### Math 数学库 #### 向下取整 ``` Math.floor(5.12) // 5 ``` #### 向上取整 ``` Math.ceil(5.12) // 6 ``` #### 四舍五入 ``` Math.round(5.12) //5 Math.round(5.55) //6 ``` #### 取绝对值 ``` Math.abs(-5) //5 ``` #### 取极值 ``` Math.max(1,5) //5 Math.min(1,5) //1 ``` #### 随机数,返回 0 ~ 1 之间的小数,包括0,不包括1 ``` Math.random() ``` #### 幂运算 ``` Math.pow(10,2) // 等于10的2次方等于100 ``` #### 保留小数后N位,四舍五入 ``` let num = 5.021314 num.toFixed(2) //5.02 ``` #### 保留小数后N位,向下取整 ``` function toFixedFloor(num,decimal){ return (Math.floor(num * Math.pow(10,decimal))/Math.pow(10,decimal)).toFixed(decimal) } toFixedFloor(52.01314,2) // "52.01" ``` #### 保留小数后N位,向上取整 ``` function toFixedCeil(num,decimal){ return (Math.ceil(num * Math.pow(10,decimal))/Math.pow(10,decimal)).toFixed(decimal) } toFixedCeil(52.01314,2) // "52.02" ``` =未完待续= ---- 相关文章 - [《前端 json 对象数据处理方法汇总》](http://www.lingyuzhao.top/?/linkController=/articleController&link=-28687176 "《JavaScript 中的数据类型以及常见的数据处理手段》") - [《JavaScript 中的数据类型以及常见的数据处理手段》](http://www.lingyuzhao.top/?/linkController=/articleController&link=15581853 "《JavaScript 中的数据类型以及常见的数据处理手段》") - [《Axios与ECharts进行数据可视化案例》](http://www.lingyuzhao.top/?/linkController=/articleController&link=-15471917 "《Axios与ECharts进行数据可视化案例》") ------ ***操作记录*** 作者:[root](http://www.lingyuzhao.top//index.html?search=1 "root") 操作时间:2023-12-03 22:12:21 星期日 事件描述备注:保存/发布 [](如果不需要此记录可以手动删除,每次保存都会自动的追加记录)