续 上次练习作业
- 封装一个函数, 判断一个四位数字是否为 水仙花数 (各个位置的四次方和)
/**
* 1. 封装一个函数
* 2. 需要一个参数
* 3. 可以写一个 return / console
*/
function fn(num) {
// 判断 num 这个 四位数字, 是否为 水仙花数
// 1. 拿到 num 各个位置上的数字
var geW = num % 10
var shiW = parseInt(num / 10) % 10
var baiW = parseInt(num / 100) % 10
var qianW = parseInt(num / 1000)
// 2. 计算各个位置上的 四次方和
var sum = geW ** 4 + shiW ** 4 + baiW ** 4 + qianW ** 4
// 3. 判断 四次方和 是否等于 自身
if (sum === num) {
console.log('是水仙花数')
} else {
console.log('不是水仙花数')
}
}
fn(1634)
- 封装一个函数, 对一个四位数字加密 加密规则: 1. 每一位上的数字 +5 然后使用 10的余数替代 2. 一三交换位置, 二四交换位置 举例: 输入 1234 3. 每一位上的数字 +5 ===> 6789 4. 使用 10 的余数代替 ===> 6789 5. 一三 二四 交换位置 ===> 8967
输入 5655 1. 每一位上的数字 +5 ===> 0100 2. 使用 10 的余数代替 ===> 0100 1. 一三 二四 交换位置 ===> 0001 (这里需要打印0001, 不能打印1)
function fn1(num) {
// 书写 加密逻辑
// 1. 拿到各个位置上的数字
var geW = num % 10
var shiW = parseInt(num / 10) % 10
var baiW = parseInt(num / 100) % 10
var qianW = parseInt(num / 1000)
// 2. 每一位上的数字 +5 然后使用 10的余数替代
// geW = geW + 5
// geW += 5
geW = (geW + 5) % 10
shiW = (shiW + 5) % 10
baiW = (baiW + 5) % 10
qianW = (qianW + 5) % 10
/**
* 3. 一三交换位置, 二四交换位置
*
* 原本 -> qianW + baiW + shiW + geW
* 一三交换 -> shiW + baiW + qianW + geW
* 二四交换 -> shiW + geW + qianW + baiW
*/
var sum = '' + shiW + geW + qianW + baiW
// 4. 加密完毕, 可以 return, 也可以使用 console 代替
console.log(sum)
}
fn1(1234)
fn1(5655)
递归函数
- 在一个函数内, 调用了 自身, 就算是一个递归函数, 只不过这个函数需要再设置一个结束条件
- 小练习
function fn(num) {
if (num === 1) { // 如果 num === 1 代表现在要计算 1 的阶乘
return 1
// 所以这里直接将 1 的阶乘 返回出去, 因为 1 的阶乘还是1, 所以这里 直接 return 1, 如果 1 的阶乘 是 100, 我们就需要 return 100 了
}
// 需要将 num 的阶乘返回出去, 现在假设 num 就是 4
// return fn(4)
// return 4 * fn(4 - 1)
return num * fn(num - 1)
}
// 计算 4 的阶乘
var res = fn(4)
console.log(res)
// 我们现在假设 fn 函数就是求某一个数字的 阶乘
// 如果你要计算 99 的阶乘 -> fn(99)
// 如果你要计算 60 的阶乘 -> fn(60)
// 如果你要计算 4 的阶乘 -> fn(4)
- 小练习
- 前两位是固定的, 从第三位开始, 他的值是 它自身的前两位的和
- 1, 1, 2, 3, 5, 8, 13, 21, 34
- 前两位是固定的, 从第三位开始, 他的值是 它自身的前两位的和
function fn(num) {
if (num === 1 || num === 2) {
// 如果当前分支执行, 说明我们在寻找 数列中 第一位或者第二位的值, 那么固定返回一个 1
return 1
}
// 要计算 第 5 位的数字 === 第 4 位 + 第 3 位
// return fn(4) + fn(3)
return fn(num - 1) + fn(num - 2)
}
console.log(fn(10))
// var res = fn(5)
// console.log(res)
/**
* 现在 假设 fn 函数就是求 这个 某一个位置上的值
*
* fn(5) -> 得到这个数列的第五位的数字
* fn(20) -> 得到这个数列的第 20 位的数字
*/
对象
- 是 JS 中的一种数据类型
- 对象属于 引用数据类型 (复杂数据类型)
- 算是一种数据的集合, 内部可以存储任意的数据类型
// 1. 字面量的方式创建对象 (很常用)
var obj = {
// 这个大括号内部不书写代码, 内部书写数据
}
// 2. 内置构造函数去创建
var obj1 = new Object()
// console.log(obj)
// console.log(obj1)
/**
* 键值对 --- 属性名/属性值 --- key/value
*
* 对象中存储数据的时候, 是按照固定的格式存储的, 这种格式我们叫做 键值对
*
* 拿 obj2 举例子:
* a -> 键/属性名/key
* 冒号后的 数字 1 是 a 对应的 值/属性值/value
*
* 多个键值对之间, 使用 逗号间隔
*/
var obj2 = {
b: 'QF666',
a: 1
}
var users = {
name: '张三',
age: 18,
number: 1340000000,
}
console.log(users)
对象的基本操作
- 前置: 对象内对于 key/属性名/键 的要求 1. 推荐书写 属性名 时, 参考 变量的命名规范 2. 可以使用 纯数字 当成 属性名 3. 可以使用 特殊符号 #@ 但是需要使用 引号包裹
var obj = {
name: 'QF001',
100: 18,
"@": '我是一个特殊符号'
}
console.log(obj)
- 基本操作: 增删改查
- 分为两种语法:
- 点语法
- 中括号语法 (数组语法)
- 分为两种语法:
// 1. 点语法
// var obj = {
// name: 'QF001'
// }
// console.log('源对象: ', obj)
// 增 -> 对象.新属性名 = 对应的属性值
// obj.age = 18
// 删除 -> delete 对象.要删除的属性名
// delete obj.name
// 改 -> 对象.要修改的属性名 = 新的属性值
// obj.name = 'QF002'
// 查 -> 对象.要查询的属性名
// console.log(obj.name)
var obj = {
name: 'QF001',
100: 18,
"@": '我是一个特殊符号'
}
// 2. 中括号语法
// 增 -> 对象['新属性名'] = 对应的属性值
// obj['age'] = 18
// 删除 -> delete 对象[要删除的属性名]
// delete obj['name']
// 改 -> 对象[要修改的属性名] = 新的属性值
// obj['name'] = 'QF002'
// console.log('新对象: ', obj)
// 查 -> 对象[要查询的属性名]
// console.log(obj['name'])
/**
两种语法的差别
如果对象的属性名 是符合变量的命名规范的话, 那么 这两种语法没有任何差异
如果操作一些 不符合变量的命名规范的属性名的时候, 更多的场景需要使用 中括号语法
如果你要 用的是 变量 , 那么也需要使用中括号语法
*/
var str = 'name'
// console.log(obj.name)
// console.log(obj.100)
// console.log(obj.@)
// console.log(obj['name'])
// console.log(obj[100])
// console.log(obj['@'])
console.log(obj.str)
/**
对象的 点语法 后续跟的内容, 会自动转换为 一个 字符串
也就是说, obj.str 他不会将 str 当成一个变量, 而是一个 字符串
所以会去对象 obj 中寻找一个 属性名 位 str 的键值对
但是当前对象中没有这个属性, 所以返回一个 undefined
*/
/**
对象的 中括号语法内可以书写变量
在查找的时候, 会先将 str 转换为 对应的值, 也就是一个 字符串类型 name
所以会去这个对象中, 查找一个 属性名位 name 的键值对
因为对象中有一个 属性名位 name 的键值对, 对应的属性值为 'QF001'
*/
遍历对象
/**
循环遍历对象
for...in
*/
var obj = {
name: 'QF001',
age: 18,
str: 'qwer'
}
for (var k in obj) {
// console.log(k)
console.log(k, obj[k])
// console.log(obj.k)
}
数组
- 一个存放一组数据的集合
- 我们将一组数据, 存放到一个盒子中, 这个盒子就是一个数组
- 数组的创建:
- 字面量的方式 (常用)
- 内置构造函数
- 数组的 length
- 其实就是数组的长度, 由数组内部多少个 成员(数据) 来决定的
- 跟数组每个成员的值, 没有任何关系
- 数组的 索引(下标)
- 下标表示的是 数组当前位置
- 从 0 开始!!! 到 数组.length - 1 结束
- 数组的创建:
// 1. 字面量的方式
// var arr = [] 创建一个空数组
// var arr = [1, 2, 'qwe', 'rty', true, false, undefined, { name: 'QF001' }]
// console.log(arr)
// 2. 内置构造函数
// var arr = new Array() 空数组
// var arr = new Array(5) 创建一个 长度 为 5 的空数组
// var arr = new Array(1, 2, 3, 4, 5) // 创建一个 内容为 1 2 3 4 5 的数组
// console.log(arr)
// length
// var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// var arr1 = [100, 200, 300, 400, 500]
// console.log(arr1)
// console.log(arr1.length)
// 下标
var arr1 = [100, 200, 300, 400, 500]
var arr2 = [100, 300, 400, 500]
// console.log(arr1)
// console.log(arr2)
// 需求: 拿到数组某一个位置的值; 语法: 数组[下标]
console.log(arr1[0])
/**
* 需求:
* 利用 for 循环, 拿到数组的每一项
*/
遍历数组
var arr = [100, 200, 300, 400, 500, 600]
// console.log(arr[0]) // 100
// console.log(arr[1]) // 200
// console.log(arr[2]) // 300
// console.log(arr[3]) // 400
// console.log(arr[4]) // 500
for (var i = 0; i < arr.length; i++) {
// console.log(i)
console.log(arr[i])
}