46、数组遍历的常用方法
①. forEach
* 语法:数组.forEach(function(item, index, origin) {})
* * item:数组的每一项
* * index:数组的每一项 对应的下标
* * origin:原始数组 (了解即可,一般没人使用)
* 作用:遍历数组
* 返回值:该方法永远没有返回值(undefined)
```js
var arr = [100, 200, 300, 400, 500, 600]
console.log('原始的数组',arr)
arr.forEach(function (item, index, origin) {
console.log(item, index)
console.log(origin)
})
```
②.map
* 语法:数组.map(function (item, index, origin) {}) 三个参数的意义与forEach 相同
* 作用:映射数组
* 返回值:返回一个和原数组长度相同的数组,但是内部数据可以经过我们的映射加工
* 映射加工:就是在函数内 以return的形式书写
```js
var arr = [100, 200, 300, 400, 500, 600]
console.log('原始的数组',arr)
var newArr = arr.map(function (item, index, origin) {
// console.log(item, index, origin)
return item * 2
})
var newArr = arr.map(function (item) {
return item * 2
})
console.log('映射出来的数组:' ,newArr)
```
有一道面试题:数组常用的遍历方法中,有一个forEach和一个map,这两个方法有什么区别?
* 1.forEach的作用是用来遍历数组,而map的作用是用来映射数组
* 2.forEach 没有返回值,而 map 是可以有返回值的
!③.filter
* 语法:数组.filter(function (item, index, origin) {})
* 作用:过滤数组
* 返回值:返回一个新数组,内部存储的是原始数组过滤出来的部分内容
* 过滤条件:过滤条件以return 的形式书写
```js
var arr = [100, 200, 300, 400, 500, 600]
console.log('原始的数组',arr)
var newArr = arr.filter(function (item, index, origin) {
return item > 350
})
console.log(newArr)
```
!④.find
* 语法:数组.find(function (item, index, origin) {})
* 作用:在数组内查找满足条件的第一项
* 返回值:找到的数据, 如果没找到返回的是undefined
* 查找条件以return的形式书写
```js
var arr = [100, 200, 300, 400, 500, 600]
console.log('原始的数组',arr)
var newArr = arr.find(function (item, index, origin) {
return item > 350 //在数组中查找第一个符合条件的成员
})
console.log(newArr) //400
var newArr = arr.find(function (item, index, origin) {
return item > 3500 //在数组中查找第一个符合条件的成员
})
console.log(newArr) //undefined
```
⑤.findIndex
* 语法:数组.findIndex(function (item, index, origin) {})
* 作用:在数组内查找满足条件的第一项的下标
* 返回值:找到的数据的下标,如果没找到返回的是-1
* 查找条件以return的形式书写
```js
var arr = [100, 200, 300, 400, 500, 600]
console.log('原始的数组',arr)
var newArr = arr.findIndex(function(item, index, origin) {
return item > 350
})
console.log(newArr)
var newArr = arr.findIndex(function(item, index, origin) {
return item > 3500
})
console.log(newArr)
```
⑥.some
* 语法:数组.some(function (item, index, origin) {})
* 作用:判断数组内是否有一个满足条件
* 返回值:一个布尔值 true/false
* 判断条件以return的形式书写
```js
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log('原始数组:', arr)
var bol = arr.some(function (item, index, origin) {
return item % 2 === 0 //判断数组内是否有一 个满足条 件的
})
console.log(bol) //true
var bol = arr.some(function (item, index, origin) {
return item > 500 //判断数组内是否有一 个满足条 件的
})
console.log(bol) //false
```
⑦.every
* 语法:数组.every(function (item, index, origin) {})
* 作用:判断数组内是否全部满足条件
* 返回值:一个布尔值 true/false
* 判断条件以return的形式书写
```js
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log('原始数组:', arr)
var bol = arr.every(function (item, index, origin) {
return item % 2 === 0 //判断数组内是否全都 满足条件
})
console.log(bol) //false
var bol = arr.every(function (item, index, origin) {
return item > 0 //判断数组内是否全都 满足条件
})
console.log(bol) //true
```
!⑧.reduce
* 语法:数组.reduce(function (prev, item, index, origin) {}, init)
* * prev: 表示初始值或者上一次的运算结果
* * item:数组的每一项 的值
* * index:表示数组的每一项 对应的下标(索引)
* * origin:原始数组
* 作用:用来实现叠加效果
* 返回值:最终叠加效果
* 注意:
* + 叠加条件以return的形式书写
* + prev 第一次的值 如果你传递了init, 就是init 的值,如果没有传递init, 那么就是数组[0]的值
* + 如果传递了init, 循环执行 数组.length 次,如果没有传递init,循环执行 数组.length - 1 次
```js
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log('原始数组:', arr)
var str = arr.reduce(function (prev, item, index, origin) {
return prev + item
}, 0)
console.log(str) //45
```
/**
* 在第 1 轮执行的时候
* prev === 0 ((因为我使用reduce 方法的时候传递了第二个参数,默认给的值为0)
* item === 1 它的值就是数组第一项的值
* 在第一轮代码执行的时候, 运行了return prev + item, 这个结果 会传递给第二轮循环开始的时候的prev
*
* 在第 2 轮执行的时候
* prev === 1 (因为上一轮执行了prev + item 得到的值为1)
* item === 2 因为是第2轮循环, 所以他的值就是 数组第2个元素的值
* 在第2轮代码执行的时候, 运行了return prev + item, 这个结果 会传递给第3轮循环开始的时候的prev
*
* 在第 3 轮执行的时候
* prev === 3 (因为上一轮执行了prev + item 得到的值为3)
* item === 3 因为是第3轮循环, 所以他的值就是 数组第3个元素的值
* 在第3轮代码执行的时候, 运行了return prev + item, 这个结果 会传递给第4轮循环开始的时候的prev
*
* 在第 4 轮执行的时候
* prev === 6 (因为上一轮执行了prev + item 得到的值为6)
* item === 4 因为是第轮循环, 所以他的值就是 数组第个元素的值
* 在第4轮代码执行的时候, 运行了return prev + item, 这个结果 会传递给第5轮循环开始的时候的prev
* ...
*
* 因为后续数组没有元素了,所以循环到此结束,然后将 最后一轮 prev 的值return 出去,外部可以使用一个变量 去接收
*
* */
```js
var str = arr.reduce(function (prev, item, index, origin) {
return prev + item
}, '')
console.log(str) //字符串123456789
```
/**
* 在第 1 轮执行的时候
* prev === '' ((因为我使用reduce 方法的时候传递了第二个参数,默认给的值为0)
* item === 1 它的值就是数组第一项的值
* 在第一轮代码执行的时候, 运行了return prev + item, 这个结果 会传递给第二轮循环开始的时候的prev
*
* 在第 2 轮执行的时候
* prev === '1' (因为上一轮执行了prev + item 得到的值为1)
* item === 2 因为是第2轮循环, 所以他的值就是 数组第2个元素的值
* 在第2轮代码执行的时候, 运行了return prev + item, 这个结果 会传递给第3轮循环开始的时候的prev
*
* 在第 3 轮执行的时候
* prev === '12' (因为上一轮执行了prev + item 得到的值为3)
* item === 3 因为是第3轮循环, 所以他的值就是 数组第3个元素的值
* 在第3轮代码执行的时候, 运行了return prev + item, 这个结果 会传递给第4轮循环开始的时候的prev
*
* 在第 4 轮执行的时候
* prev === '123' (因为上一轮执行了prev + item 得到的值为6)
* item === 4 因为是第轮循环, 所以他的值就是 数组第个元素的值
* 在第4轮代码执行的时候, 运行了return prev + item, 这个结果 会传递给第5轮循环开始的时候的prev
* ...
*
* 因为后续数组没有元素了,所以循环到此结束,然后将 最后一轮 prev 的值return 出去,外部可以使用一个变量 去接收
*
* */
```js
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log('原始数组:', arr)
var str = arr.reduce(function (prev, item, index, origin) {
return prev + item
})
console.log(str) //45
```
/**
* 第1轮
* prev === 1 (因为没传递init,所以prev第一次的值是数组下标0位置上的值)
* item === 2 (因为没传递init,所以prev是下标[0] 的值,然后item就拿到了下标[1] 的值)
* 第1轮运行代码return prev + item 这个结果会传递给下轮循环开始时的prev
*
* 第2轮
* prev === 3 (因为上一轮执行了prev + item 得到的值3)
* item === 3 (因为上一轮item的值是[1],所以本轮的值是[2])
* 第1轮运行代码return prev + item 这个结果会传递给下轮循环开始时的prev
*
* 第3轮
* prev === 6 (因为上一轮执行了prev + item 得到的值3)
* item === 4 (因为上一轮item的值是[2],所以本轮的值是[3])
* 第1轮运行代码return prev + item 这个结果会传递给下轮循环开始时的prev
* ...
* 因为后续数组没有元素了,所以循环到此结束,然后将最后一轮prev的值return出去,外部可以使用一个变量去接收
* */
47、课后练习
```js
// 1.计算数组的和 var arr = [1, 2, 3, 4, 5]
var arr = [1, 2, 3, 4, 5]
// 方法1 reduce 用来实现叠加效果
var sum = arr.reduce(function (prev, item) {
return prev + item
},0)
console.log(sum)
// 方法2 for循环
function fn(arr){
var sum = 0
for(var i = 0
sum += arr[i]
}
return sum
}
console.log(sum)
// 方法3 forEach 遍历数组
var sum = 0
arr.forEach(function (item) {
sum += item
})
console.log(sum)
// 方法4 map 映射数组,一般不会使用
var sum = 0
arr.map(function (item) {
return sum += item
})
console.log(sum)
```
```js
// 3. 将数组的值 放大 10 倍 并返回一个新数组
var newArr = arr.map(function (item, index, origin) {
return item * 10
})
console.log('放大十倍的数组', newArr)
// forEach 有点麻烦
var newArr = []
arr.forEach(function (item, index, origin) {
newArr[newArr.length] = item * 10
})
console.log('放大十倍的数组', newArr)
```
```js
// 4. 过滤数组, 让数组内的值只有偶数 var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -> 新数组: [2, 4, 6, 8, 10]
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var newArr = arr.filter(function (item, index, origin) {
return item % 2 === 0
})
console.log(newArr)
var newArr = []
var newArr = arr.forEach(function (item, index, origin) {
if(item % 2 === 0) {
newArr.push(item)
}
})
console.log(newArr)
```
48、数组塌陷
var arr = [0, 1, 2, 3, 4, 5]
console.log('原始数组', arr)
for(var i = arr.length; i >= 0; i--) {
arr.pop()
}
console.log('删除后的数组', arr)
for(var i = arr.length - 1; i >= 0; i--) {
arr.splice(i, 1)
}
console.log('删除后的数组', arr)
var arr = [0, 1, 2, 3, 4, 5]
console.log('原始数组', arr)
for(var i = 0; i < arr.length; i++) {
arr.splice(i, 1)
i--
}
console.log('删除后的数组', arr)
49、数组的数学方法
数学的方法
*
* 在JS中Math对象给我们提供J操作数据的些方法( 教学的方法)
*
* !1.random
* 语法:Math.random()
* 作用:得到一个随机数,每次生成的数 字都不一样,但一定是0~1之间的,
包含0,不包含1, 也就是 说最大值可能是0. 99999...
```js
var num = Math.random()
console.log(num)
```
* 2.round
* * 语法:Math.round(数字)
* * 作用:将这个数字(小数),按照四舍五入的形式变成整数
```js
var num1 = Math.round(4.499999)
var num2 = Math.round(4.5)
console.log(num1)
console.log(num2)
```
* !3.ceil
* * 语法:Math.cei- l(数字)
* * 作用:将这个数字(小数)向上取整
```js
var num1 = Math.ceil(1.00001)
var num2 = Math.ceil(1.99999)
console.log(num1)
console.log(num2)
```
* !4.floor
* 语法:Math.floor(数字)
* 作用:将这个数字(小数)向下取整
```js
var num1 = Math.floor(1.00001)
var num2 = Math.floor(1.99999)
console.log(num1)
console.log(num2)
```
* 5.abs
* 语法:Math.abs(数字)
* 作用:返回这个数字的绝对值
```js
var num1 = Math.abs(1.23)
var num2 = Math.abs(-1.23)
console.log(num1)
console.log(num2)
```
* 6.sqrt
* 语法:Math.sqrt(数字)
* 作用:求平方根
```js
var num = Math.sqrt(16)
console.log(num)
```
* 7.pow
* 语法:Math.pow(基数, 幂)
* 作用:返回基数的几次幂
```js
var num = Math.pow(2, 3)
console.log(num)
```
* 8.max
* 语法:Math.max(数字1,数字2...)
* 作用:返回传入的数字中最大的那一个
```js
var num = Math.max(100, 500, 123, 87, 9)
console.log(num) //500
```
* 9.min
* 语法:Math.min(数字1,数字2...)
* 作用:返回传入的数字中最小的哪一个
```js
var num = Math.min(100, 500, 123, 87, 9)
console.log(num) //9
```
* 10.PI
* 语法:Math.PI
* 作用:返回π
```js
var num = Math.PI
console.log(num) //3.141592653589793
```
50、数组的数学方法课堂案例
```js
var arr = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]
for (var i = 0; i < arr.length; i++) {
if(arr.indexOf(arr[i], i + 1) !== -1) {
arr.splice(i, 1)
i--
}
}
console.log(arr)
function fn() {
var fnNum3 = Math.floor(Math.random() * (10 + 1))
return fnNum3
}
var num = fn()
console.log('num是一个随机数:' , num)
var obj = {}
for(var i = 0; i <= 10000; i++) {
var sum = fn()
if(obj[sum] === undefined) {
obj[sum] = 1
} else {
obj[sum]++
}
}
console.log(obj)
```
51、JS的严格模式
* JS的严格模式
* JS是一个相对不是很严谨的语言,在开发的时候 写代码也不是很严格
* 换句话说严格模式就是对开发的时候 ,你写的代码做了一些要求
* 严格模式的规则
* 1.声明变量必须要 var 关键字
* 2.函数的形参不可以重复
* JS中默认是没有开启严格模式, 如果想要开启严格模式,需要手动在代码最开始的位置(script标签内第一行), 写一个字符串'use strict'
*
* 现在的公司的项目中,基本都是按照严格模式开发的
```js
'use strict'//开启严格模式
var a = 100
console.log(a)
// b = 200 //b is not defined
// console.log(b)
for (var i = 0; i < 3; i++) {
console.log('for循环1开始执行')
}
function fn(a, b) {
console.log(a, b)
}
fn(100, 200)
```
52、字符集(了解)
* 字符集
* 计算机只能存储二进制数据0101010
* 我们的大写字母小写字母符号之类的内容都是由 二进制数字组成
* 或者说我们在敲一个字符的时候,都有个对应的编号,计算机存储的时候存储的是这些编号,
* 只不过我们看到的时候,是通过这些编号解析成我们看到的内容
* 前身:ASCII as key (128) 只够 美国人用英语的使用
* 国内推出了一个属于中国的GBK国标码 前128位ASCII码,后边从129 位开始就是汉字
* unicode(万国码) 前128 位还是ASCII码, 后边开始是各个国家的文字码
* 八位十六进制编码 容量小,但是占用内存也小 UTF-8
* 十六位的十六进制编码 容量大,但是占用内存也大
53、创建字符串
* 创建字符串的方式
* 1.字面量的形式创建字符串
* var str = 'abc'
* 2.内置构造函数的形式创建字符串
```js
var str = new String()
console.log(str)
var str = new String('abc')
console.log(str)
```
54、字符串的索引与下标
* 字符串的length与下标
*
* length与下标的含义与数组中的一样
* length: 长度
* 索引(下标):获取到字符串中指定位置的值
* 注意:字符串中通过索引能够获取到指定位置的值,只不过获取到的值是只读的
换句话说 获取到的值,能看不能改
```js
var str = 'abc'
console.log(str.length)
console.log(str[1])
str[1] = 'Q'
console.log(str)
```
55、字符串的方法
(1).charAt
* 语法:字符串.charAt(索引)
* 作用:查询指定下标的值
* 返回值:查询到的值,如果没有查询到就是一个空字符串
```js
var str = 'abcd'
var str1 = str.charAt(0)
console.log(str1) //a
var str2 = str.charAt(50)
console.log(str2) //因为没有查询到,返回的是空字符串
```
(2).charCodeAt
* 语法:字符串.charCodeAt(索引)
* 作用:查询指定下标的值 对应的 十进制码
* 返回值:查询到的值对应的十进制码 如果没有查询到会返回一个NaN
```js
var str = 'abcd'
var str1 = str.charCodeAt(0)
console.log(str1) //字符串a的十进制码 97
var str2 = str.charCodeAt(50)
console.log(str2) //因为没有查询到 返回一个NaN
```
(3).toLowerCase
* 语法:字符串.toLowerCase()
* 作用:将这个字符串转换为小写
* 返回值:转换后的字符串
```js
var str1 = 'abcDEF'
var str2 = 'QWER'
var str3 = 'asdf'
console.log(str1.toLowerCase())
console.log(str2.toLowerCase())
console.log(str3.toLowerCase())
```
(4).toUpperCase
* 语法:字符串.toUpperCase
* 作用:将这个字符串转换为大写
* 返回值:转换后的字符串
```js
var str1 = 'abcDEF'
var str2 = 'QWER'
var str3 = 'asdf'
console.log(str1.toUpperCase())
console.log(str2.toUpperCase())
console.log(str3.toUpperCase())
```
*
(5).substr
* 语法:字符串.substr(开始索引, 多少个)
* 作用:截取指定的字符串
* 返回值:截取到的字符串
* 注意:mnd说明这个方法将来某一天可能会删除,所以建议我们使用substring
```js
var str = 'qwertyuiop'
var str1 = str.substr(0, 3)
console.log(str1)
var str1 = str.substr(3, 2)
console.log(str1)
```
(6).substring
* 语法:字符串.substring(开始索引, 结束下标)
* 作用:截取指定的字符串
* 返回值:截取到的字符串
* 注意:
* 1.参数包前不包后
* 2.结束索引可以不写,相当于写了length(字符串的总长度)
```js
var str = 'qwertyuiop'
var str1 = str.substring(0, 3)
console.log(str1)
var str2 = str.substring(0)
console.log(str2)
```
(7).slice
* 语法:字符串.slice(开始索引, 结束索引)
* 作用:截取指定字符串
* 返回值:截取到的字符串
* 注意:
* 1.参数包前不包后
* 2.结束索引可以不写,相当于写了length(字符串的总长度)
* 3.开始索引可以不写,相当于写了0
* 4.结束索引支持写负数,相当于length +负数
```js
var str = 'qwertyuiop'
var str1 = str.slice(0, 3)
console.log(str1)
var str2 = str.slice(0)
console.log(str2)
var str3 = arr.slice()
console.log(str3)
var str4 = str.slice(0, -3)
console.log(str4)
```
(8).concat
* 语法:字符串.concat(数据1, 数据2, 数据3...)
* 作用:将字符串和参数传递的数据 进行拼接
* 返回值:拼接后的字符串
```js
var str = 'qwer'
var str1 = str.concat('@', '+', '!')
console.log(str1) //qwer@+!
```
*
(9).indexOf
* 语法:字符串.indexOf(数据, 开始下标)
* 作用:寻找数据在字符串中的位置
* 返回值:找到的时候返回下标,找不到返回-1
* 注意:第二个参数可以不传递,默认为0
```js
var str = 'qwer'
var str1 = str.indexOf('q', 1)
console.log(str1)
var str1 = str.indexOf('q', 0)
console.log(str1)
var str1 = str.indexOf('q')
console.log(str1)
```
*
(10).lastIndexOf
* 语法:字符串.lastIndexOf(数据, 开始索引)
* 作用:寻找数据在字符串中的位置(从后往前/从右向左)
* 返回值:找到的时候返回下标,找不到返回-1
* 注意:第二个参数可以不传递,默认为length - 1
```js
var str = 'qwer'
var str1 = str.lastIndexOf('e', 1)
console.log(str1)
var str1 = str.lastIndexOf('e')
console.log(str1)
```
*
(11).split
* 语法:字符串.split('符号')
* 作用:在字符串中找到'符号' 然后将这个字符串分隔,并放在一个数组内
* 返回值:一个数组
* 注意:参数如果传递的是 空字符串('') 会将字符串全部分隔开
```js
var str = 'qwer, tyui, asdf, ghjk'
console.log('原始字符:', str)
var str1 = str.split(',')
// 通过, 将字符串str分隔到一个数组中
console.log(str1) //['qwer', ' tyui', ' asdf', ' ghjk']
var str2 = str.split('i')
// 通过i 将字符串str分隔到一个数组中
console.log(str2) //['qwer, tyu', ', asdf, ghjk']
var str3 = str.split(' ')
// 通过一个空格 将字符串str分隔到一个数组中
console.log(str3) //['qwer,', 'tyui,', 'asdf,', 'ghjk']
var str4 = str.split('')// 通过一个空字符串 将字符串str分隔到一个数组中
console.log(str4)
// ['q', 'w', 'e', 'r', ',', ' ', 't', 'y', 'u', 'i', ',', ' ', 'a', 's', 'd', 'f', ',', ' ', 'g', 'h', 'j', 'k']
var str5 = str.split('@')// 通过一个@ 将字符串str分隔到一个数组中
console.log(str5) //['qwer, tyui, asdf, ghjk']
```
!(12).trim
* 语法:字符串.trim()
* 作用:去掉字符串两侧的空格
* 返回值:去掉空格后的字符串
```js
var str = ' a b c '
console.log('原始的字符串:', str)
var str1 = str.trim()
console.log(str1) //a b c
```
(13).trimStart / trimLeft
* 语法:字符串.trimStart() / 字符串.trimLeft()
* 作用:去掉字符串开始(左侧)的空格
* 返回值:去掉空格后的字符串
```js
var str = ' a b c '
console.log('原始的字符串:', str)
var str1 = str.trimStart()
var str2 = str.trimLeft()
console.log(str1)
console.log(str2)
```
*
(14).trimEnd / trimRight
* 语法:字符串.trimEnd() / 字符串.trimRight()
* 作用:去掉字符串结束(右侧)的空格
* 返回值:去掉空格后的字符串
```js
var str = ' a b c '
console.log('原始的字符串:', str)
var str1 = str.trimEnd()
var str2 = str.trimRight()
console.log(str1)
console.log(str2)
```
!(15).includes
* 语法:字符串.includes(字符串片段)
* 作用:判断 当前字符串中,是否拥有指定字符串片段
* 返回值:一个布尔值
* true -> 拥有
* false -> 没有
```js
var str = 'qwertyuiop'
var str1 = str.includes('tyui')
console.log(str1)
var str2 = str.includes('tyuip')
console.log(str2)
```
(16).startsWith
* 语法:字符串.startsWith(字符串片段)
* 作用:判断 字符串开头 是不是指定的字符串片段
* 返回值:一个布尔值
* true -> 是开头
* false -> 不是开头
```js
var str = 'qwertyuiop'
var str1 = str.startsWith('qwer')
console.log(str1)
var str2 = str.startsWith('wer')
console.log(str2)
```
(17).endsWith
* 语法:字符串.endsWith(字符串片段)
* 作用:判断 字符串结尾 是不是指定的字符串片段
* 返回值:一个布尔值
* true -> 是结尾
* false -> 不是结尾
```js
var str1 = str.endsWith('op')
console.log(str1)
var str2 = str.endsWith('qwer')
console.log(str2)
```
(18).replace
* 语法:字符串.replace('要被替换的字符', '替换的字符')
* 作用:找到当前字符串中第一个参数对应的值,然后将其替换为第二个参数
* 返回值:替换完成的字符串
```js
var str = 'abcdefg'
var str1 = str.replace('abc', '@@!!##')
console.log(str1)
var str2 = str.replace('qwer', '@@!!##')
console.log(str2)
```
56、课堂案例(面试题)
* 一道面试题
* 统计字符串中每个字符串出现的次数(以对象的形式存储)
var str = 'aaabbbccddeeeea'
var obj = {}
for(var i = 0; i <= str.length; i++) {
var key = str[i]
if(obj[key] === undefined) {
obj[key] = 1
}
}
console.log(obj)
var str = 'aaabbbccddeeeea'
var obj = {}
for(var i = 0; i <= str.length; i++) {
var key = str[i]
if(obj[key] === undefined) {
obj[key] = 1
} else {
obj[key]++
}
}
console.log(obj)
var str = 'aaabbbccddeeeea'
var obj = {}
for(var i = 0; i <= str.length; i++) {
if(!obj[str[i]]) {
obj[str[i]] = 1
} else {
obj[str[i]]++
}
}
console.log(obj)
var str = 'aaabbbccddeeeea'
var obj = {}
for(var i = 0; i <= str.length; i++) {
if(!obj[str[i]]) {
obj[str[i]] = 1
} else {
obj[str[i]]++
}
}
console.log(obj)
57、课后练习
* ①. 反转字符串
* var str = 'abcdef'
* 代码处理后的 str === fedcba
```js
// 方法1
var str = 'abcdef'
// var newStr = str.split('')
// var newStr2 = newStr.reverse()
// var newStr3 = newStr2.join('')
var newStr = str.split('').reverse().join('')
console.log(newStr3)
// 方法2
var newStr = ''
for(var i = 0
var s = str.charAt(str.length-i-1)
newStr += s
}
console.log(newStr)
```
* ②.查询字符串
JS 中内把字符串分为几种类型(约定)
1. 普通字符串: '123asd阿松大'
2. 数字字符串: '123123123123123'
3. html格式字符串: '<p></p>'
4. 查询字符串: 'key=value&key2=value2&key3=value3'
* 一条数据: key=value
* 多条数据: & 符间隔
假设 str 存储的是后端反馈给我们的一个信息
var str = 'username=靓仔&age=18&qq=88888888'
需求1:
将'username=靓仔&age=18&qq=88888888'
更改为
{
username: '靓仔',
age: 18,
qq: 88888888
}
需求2:
将
{
username: '靓仔',
age: 18,
qq: 88888888
}
更改为
'username=靓仔&age=18&qq=88888888'
```js
var str = 'username=靓仔&age=18&qq=88888888'
var obj = {}
var arr = str.split('&')
arr.forEach(function(item) {
var itemInfo = item.split('=')
obj[itemInfo[0]] = itemInfo[1]
})
console.log(obj)
var newStr = ''
for (var k in obj) {
newStr += k + '=' + obj[k] + '&'
}
console.log(newStr)
newStr = newStr.slice(0, -1)
console.log(newStr)
```
58、进制转换与保留小数
1.进制转换(了解)
1.1十进制转换为其他进制
语法:十进制数字.toSting(几进制)
var num = 100
var num1 = num.toString(2)
console.log(num1)
1.2其他进制转换为十进制
语法:parseInt(数字,将数字视为几进制的数字转换为10进制的数字)
var num = parseInt(100, 2)
console.log(num)
!2.保留小数(掌握)
语法:toFixed(保留几位小数), 保留小数的时候四舍五入,并且返回的是字符串
var num = 100.123456789
var num1 = num.toFixed(2)
console.log(num1)
var num2 = num.toFixed(4)
console.log(num2)
59、定时器
* 两种定时器的介绍
①.setInterval 计时器,每间隔固定的时间执行一次
* 语法:setInterval(函数, 数字/时间)
* 函数:每间隔固定的时间要执行的代码
* 数字:问隔的时问,注意单位是毫秒 ,最小值为4~20
```js
setInterval(function() {
console.log('我是一个定时器~~~')
}, 1000)
```
②.setTimeout 倒计时器,在指定时间到达后,执行一次
* 语法:setTimeout(函数, 数字)
* 函数:在指定时间到达后要执行的代码
* 数字:间隔时间,单位也是毫秒
```js
setTimeout(function() {
console.log('我是一个倒定时器~~~')
}, 3000)
```
* 两个定时器的返回值与意义
* + 返回值不区分定时器种类,用于表示你这个定时器是页面中第几个定时器
* + 作用:用来关闭定时器
```js
var timeId1 = setInterval(function() {
console.log('我是一个定时器~~~')
}, 1000)
var timeId2 = setTimeout(function() {
console.log('我是一个倒定时器~~~')
}, 3000)
console.log('计时器ID', timeId1)
console.log('倒计时器ID', timeId2)
```
* 关闭定时器
* + 不区分定时器种类,只要给出正确的定时器返回值就可以关闭
* + 语法:
* clearTimeout(定时器返回值)
* 注意:能够关闭计时器也能关闭倒计时器
* 开发人员的约定:这个定时器只用来关闭倒计时器
* 目的就是为了让其他开发人员看到这个行代码之后,知道你关闭了一个倒计时器
* clearInterval(定时器返回值)
* 注意:能够关闭计时器也能关闭倒计时器,
* 开发人员的约定:这个定时器只用来关闭计时器
* 目的就是为了让其他开发人员看到这个行代码之后,知道你关闭了一个计时器
* */
```js
var timeId1 = setInterval(function() {
console.log('我是一个定时器~~~')
}, 1000)
clearInterval(timeId1)
var timeId2 = setTimeout(function() {
console.log('我是一个倒定时器~~~')
}, 3000)
clearTimeout(timeId2)
```
60、异步代码
* 简单的代码异步执行机制(并不是详细的,详细的内容后期还会讲)
*
* 这是一道面试题,请熟读并背诵全文
*
* 什么是非异步代码
* 按照从上往下的顺序,从左到右的顺序,依次执行每一行代码
* 如果上一行代码没有执行完毕,不会执行下一行代码
*
* 什么是异步代码
* 当代码遇到异步任务的时候,会把这个代码放在'异步队列'内等待
* 所有的同步代码全都执行完毕之后,在开始执行“异步队列”内的代码
* 简单来说:代码在执行的时候如果遇到异步任务,会先放在‘异步队列’内等着,然后继续往下执行,直到把所有的同步代码执行完毕后,在开始执行异步任务
*
* 什么是异步任务
* 两种定时器都是异步任务
* 可以理解:先执行定时器外面的代码然后执行定时器里边的代码
```js
console.log('开始')
setTimeout(function() {
console.log('倒计时器执行了~~~')
}, 3000)
console.log('结束')
/**
* 运行顺序
* 1.开始
* 2.结束
* 3.倒计时器执行了~~~
* */
```
```js
console.log('1')
setTimeout(function() {
console.log('2')
}, 3000)
console.log('3')
setTimeout(function() {
console.log('4')
}, 4000)
console.log('5')
setTimeout(function() {
console.log('6')
}, 2000)
console.log('7')
// 执行顺序 1 3 5 7 6 2 4
```
#### **61、创建时间对象**
在Js中 Date 给我们提供了操作时间的一些方法,是JS内置的一个对象
var timer = new Date()
console.log(timer)
62、时间对象的参数
* 创建时间对象的时候,可以选择传递参数,也可以不传递参数
* 如果需要传递参数,分为两种方式
①.数字
* 最少要传递两个值,年 和 月(JS中0-11代表了1-12月)
```js
var timer = new Date(2020, 00, 31, 23, 59, 59)
console.log(timer)
```
②.字符串
* 最少只需要传递一个参数年份即可(字符串的形式传递时月份从1开始)
```js
var timer = new Date('2019-02-13 13:14:15')
console.log(timer)
```
63、获取时间对象
var timer = new Date()
①.得到时间对象中的年份
var year = timer.getFullYear()
console.log(year)
②.得到时间对象中的月份
var month = timer.getMonth()
console.log(month)
③.得到时间对象中的那一天/日
var day = timer.getDate()
console.log(day)
④.得到时间对象中的小时
var hours = timer.getHours()
console.log(hours)
⑤.得到时间对象中的分钟
var minutes = timer.getMinutes()
console.log(minutes)
⑥.得到时间对象中的秒
var seconds = timer.getSeconds()
console.log(seconds)
⑦.得到时间对象中的一周的第几天(用0-6表示周一到周日,但是周日为0)
var days = timer.getDay()
console.log(days)
⑧.getTime 按照格林威治时间计算 从1970年1月1日0时0分0秒 到 现在(或指定日期)的毫秒数
var getTime = timer.getTime()
console.log(getTime)
64、设置时间对象
var timer = new Date()
①设置 年
timer.setFullYear(2008)
console.log(timer.getFullYear())
②设置 月
timer.setMonth(11)
console.log(timer.getMonth())
③设置 当月的第几天
timer.setDate(20)
console.log(timer.getDate())
⑤注意:没有设置 本周的第几天
⑥设置 时
timer.setHours(16)
console.log(timer.getHours())
⑦设置分
timer.setMinutes(30)
console.log(timer.getMinutes())
⑧设置秒
timer.setSeconds(40)
console.log(timer.getSeconds())
⑨设置毫秒(0-999)
timer.setMilliseconds(888)
console.log(timer.getMilliseconds())
⑩直接设置到1970 的总毫秒
timer.setTime(123456789)
console.log(timer.getTime())
65、认识BOM
* BOM
* 浏览器对象模型,其实就是操作浏览器的一些能力
*
* 我们可以操作那些内容?
* +获取浏览器的相关信息(窗口大小)
* + 操作浏览器进行页面的跳转
* + 获取浏览器地址栏的信息
* + 操作浏览器的滚动条
* + 获取浏览器的版本
* + 让浏览器出现一个弹出框
* + ...
*
* BOM 的核心就是 window 对象
* window 是JS内置的一个对象,里面包含着操作浏览器的方法
66、体验BOM
* ①.获取浏览器窗口的尺寸
* innerHeight / innerWidth
* + 作用:获取浏览器窗口的高度和宽度(包含滚动条)
* + 语法:window.innerHeight / window.innerWidth
console.log('浏览器窗口的高度', window.innerHeight)
console.log('浏览器窗口的宽度', window.innerWidth)
* ②.浏览器的弹出框 (学习的时候会用,实际工作中不会使用)
* alert
* prompt
* confirm
* * 有一个询问信息和两个按钮
* * 点击确定按钮 返回 true
* * 点击取消按钮 返回 false
var boo = confirm('请问您确定进入页面吗?')
console.log(boo)
* ③.浏览器的地址信息
* + 在 window 中,有一个 对象 叫做 location,他是专门用来存储浏览器地址栏内的信息
* 3.1 location 这个对象中,有一个属性叫做href
* 这个属性是专门存储浏览器地址栏内的 url 地址的信息
* 我们也可以给这个属性赋值,这样就会跳转到我们赋值的地址了
<body><button>点击跳转到百度</button></body>
setTimeout(function() {
window.location.href = 'https://www.baidu.com/'
}, 3000)
* 3.2 reload 这个对象中,有一个方法叫做reload
* 这个方法调用时会重新加载页面,相当于刷新
* 注意!!!不要直接写在代码中,否则浏览器会一直刷新
var count = 0
setInterval(function() {
count++
console.log(count)
if(count === 5) {
window.location.reload()
}
}, 1000)
* ④.浏览器的历史记录
* + window对象中有一个叫做history他专门用来存储历史记录信息
* 4.1 history.back
* 专门用来回退历史记录,就是回到前一个页面,相当于浏览器左上角的←按钮
* 注意:我们需要有上一条记录,否则不能使用这个方法
* 语法:window.history.back()
* 4.2 history.forward
* 是去到下一个历史记录里面,也就是去到下一个也买你,相当于浏览器左上角的→按钮
* 注意:我们需要之前有过回退操作,不然无法使用这个方法
* 语法:window.history.forward()
67、BOM的事件
* ①.浏览器的版本信息(了解)
* window 中的 navigator 可以获取到浏览器的信息
*
* ②.浏览器的onload事件
* 这个事件会在页面所有资源加载完毕后执行
* window.onload = function() {
* 我们的 Js 代码全部书写在这个函数内部
* }
*
* 在浏览器中,把JS 写在 head 中,在S加载时,下边的body标签还没来得及加载
* 可能会导致我们获取body内部的标签,比如说div或者img,出现问题获取不到
* 如果把代码放在onload 中,则不会出现这个问题
* 如果把Js写在body底部,写不写onload都无所谓
* ③.浏览器的onscroll 事件
* 当浏览器的滚动条滚动时会触发该事件,或者鼠标滚轮滚动时触发(前提是有滚动条)
*
* ④.浏览器的滚动距离
* + 浏览器的内容可以滚动,那么我们就能获取到浏览器的滚动距离
*
* 思考:
* 浏览器真的滚动了吗?
* 其实浏览器并没有滚动,而是浏览器内部的页面在滚动
* 换句话说:湖览器没动,页面向上或者向下走了
* 所以这个不能单纯的说是湖览器的内容了,而是页面的内容
* 那么我们这里就不能再使用window对象,而是使用document对象
*
* scrollTop
* 获取的是向上滚动的距离
* 语法1:document.body.scrollTop
* 语法2:document.documentElement.scrollTop
```js
window.onscroll = function() {
//console.log('浏览器滚动了~~~')
console.log('body:', document.body.scrollTop) //没有DOCTYPE声明的时候
console.log('documentElement:', document.documentElement.scrollTop) //有DOCTYPE声明的时候
}
```
* 两种语法的区别:
* IE浏览器(了解)
* 没有DOCTYPE声明的时候,两种语法没有差别用哪个都无所谓
* 有DOCTYPE 声明的时候,只能使用语法2 documentELement
*
* Chorme 和 FireFox
* 没有DOCTYPE声明的时候, 用语法1 body
* 有DOCTYPE声明的时候,用语法2 documentELement
* Safari
* 这两个语法都不用,使用一个单独的方法window.pageYoffset
*
* scrollLeft
* 获取的是向左滚动的距离
* 语法1:document.body.scrollLeft
* 语法2:document.documentELement.scrollLeft
* 区别参考 scrollTop
```js
window.onscroll = function() {
// console.log('浏览器滚动了~~~')
console.log('body:', document.body.scrollLeft) //没有DOCTYPE声明的时候
console.log('documentElement:', document.documentElement.scrollLeft) //有DOCTYPE声明的时候
}
```