1. # js基础
JavaScript是一门世界上最流行的脚本语言
一个合格的后端人员,必须要精通JavaScript
2、历史 ECMAScript可以理解为JavaScript的一个标准
最新版本已经到es6
但是大部分浏览器还只停留在支持es5代码上
3.前端三大件 HTML:超文本标记语言(结构层)
CSS:层叠样式表(样式层)
JavaScript:轻量级弱脚本语言
4.JS的三大核心
BOM-Browser OBjectModel(浏览器对象模型)
私人:提供的一整套操作浏览器相关内容的属性和方法
DOM-Document Object Model (文档对象模型)
私人:提供了一整套操作文档相关内容的属性和方法
ECMAScrpt(简称ES)-JS的语法规范
规定了JS的语法的书写
核心:利用ES 去操作DOM和BOM发生变化
5.js的三种书写方式
行内式 => a 标签 -> 在 href 属性上直接书写 javascript: js代码 ; => 非 a 标签 -> 添加一个行为属性以后, 直接书写 js 代码即可
行内式 js 代码(强烈不推荐)
a 标签行内式
=> 在 标签的 href 属性上进行书写
=> 要求: 书写一个 javascript: js代码 ;
=> 示例: <a href="javascript: js代码 ;"></a>
非 a 标签行内式
=> 首先需要添加一个行为属性(以 onclick 为例)
-> on: 在 ... 上
-> click: 点击/单击
=> 不需要书写 javascript:;, 直接在属性值的位置书写 js 代码即可
=> 示例: <div onclick="js代码"></div>
第一个js代码
+ 语法: alert('文本内容')
+ 注意:
=> 小括号内如果书写的是纯数字, 那么不需要引号包裹
=> 小括号内如果书写的不是纯数字, 那么需要引号包裹(单引号或者双引号无所谓)
+ 作用: 会在浏览器出现一个弹出提示框, 提示框内的内容就是书写在 () 内的内容
如下:
内嵌式 => 把 js 代码书写在 script 标签内 => 打开页面不需要任何行为, 直接就会执行
内嵌式 js 代码 + 在 html 页面书写一个 script 标签 + 把你需要执行的 js 代码书写在 script 标签内 + 注意: => script 标签内的代码不需要行为, 打开页面就会直接执行 => script 标签可以书写在页面任何位置 -> 推荐书写在 head 的末尾或者 body 的末尾 -> 目前推荐书写在 body 的末尾 => script 标签可以书写多个, 会按照从上到下的顺序依次执行每一个 script 标签内的代码
如下:
外链式
=> 把 js 代码书写在 .js 后缀的文件内
=> 在 html 页面以 script 标签的 src 属性引入
=> 不需要任何行为, 打开页面就会直接执行
外链式 js 代码
+ 把 js 代码书写在一个 .js 后缀的文件内
=> 在文件内直接书写你要执行的 js 代码即可
+ 在 html 页面用 script 标签的 src 属性引入该 js 文件
=> 注意: src 属性 src 属性 src 属性 !!!
+ 注意:
=> script 标签内的代码不需要行为, 打开页面就会直接执行
=> script 标签可以书写在页面任何位置
-> 推荐书写在 head 的末尾或者 body 的末尾
-> 目前推荐书写在 body 的末尾
=> script 标签可以书写多个, 会按照从上到下的顺序依次执行每一个 script 标签内的代码
=> script 标签一旦被当做外链式使用的时候, 不能继续被当做内嵌式使用了
-> 此时书写在标签对内的代码没有意义(此处是外链式链接)
alert('我是一段外链式 js 代码, 你好世界 ^_^')
6.JS定义变量 什么是变量? 在程序的运行过程中用来记录中间值的内容
例子: => 饮料: 50 => 打车: 30 => 吃饭: 160 => 看电影: 80 => 计算比例: -> 饮料: 50 / (50 + 30 + 160 + 80) -> 打车: 30 / (50 + 30 + 160 + 80) -> 吃饭: 160 / (50 + 30 + 160 + 80) -> 看电影: 80 / (50 + 30 + 160 + 80) => 假定一个变量 x, 值是 50 + 30 + 160 + 80 => 计算比例: -> 饮料: 50 / x -> 打车: 30 / x -> 吃饭: 160 / x -> 看电影: 80 / x
定义变量
+ 语法: var 变量名 = 值
-> var 定义变量的关键字
-> 变量名 你自定义的一个名字
-> 等于号 赋值符号(把右边的内容给到左边的变量)
-> 值 该变量所保存的内容
一个 var 关键字使用的几种形式
1. 定义变量不赋值
=> var 变量名
2. 定义变量并赋值
=> var 变量名 = 值
3. 一个 var 定义多个变量
=> var 变量名1, 变量名2, ...
4. 一个 var 定义多个变量并赋值
=> var 变量名1 = 值1, 变量名2 = 值2, ...
5. 一个 var 定义多个变量
=> var 变量名1 = 值1, 变量名2, 变量名3 = 值3, ...
变量保存值
+ 一个变量只能保存一个值, 当你第二次给一个变量赋值的时候
+ 会把第一次赋的值覆盖掉
JS的三个输出语法
1. alert()
+ 语法: alert(输出的内容)
+ 形式: 弹出一个提示框显示内容
2. console.log()
+ 语法: console.log(输出的内容)
+ 形式: 在浏览器控制台输出内容
3. document.write()
+ 语法: document.write(输出的内容)
+ 形式: 直接把内容输出在页面上
共同点:
+ 当你的小括号内输出的内容被引号包裹的时候, 表示你输出的是一个普通文本内容
+ 当你的小括号内输出的内容没有引号包裹的时候(纯数字除外), 表示你输出的是一个变量
案例:
交换变量 需求:交换两个变量所保存的值
var n = 11
var m = 33
console.log('n : ', n)
console.log('m : ', m)
console.log('------------------------------')
变量的命名规则和规范
规则(你必须遵守, 不然报错)
1. 一个变量只能由 数字(0-9) 字母(a-zA-Z) 美元符($) 下划线(_) 组成
2. 一个变量不能由 数字开头
3. 严格区分大小写
4. 不要使用关键字和保留字
=> 关键字: JS 语法内正在使用的关键字
=> 保留字: JS 语法将来要使用的关键字
规范(建议你遵守)
1. 变量语义化
=> 尽量使用一些有意义的单词, 或者汉语拼音
2. 驼峰命名法
=> 当变量由多个单词组成的时候, 第二个单词开始, 首字母大写
=> 当变量由多个单词组成的时候, 每个单词之间使用 下划线(_) 分隔
3. 不要用中文
JS 的数据类型
+ 基本数据类型
=> 数值 Number
-> 整数
-> 浮点数
-> 科学记数法
-> 其他进制表示
-> Infinity
-> NaN
=> 字符串 String
-> 所有被引号包裹的内容都是字符串
=> 布尔 Boolean
-> true
-> false
=> 空 Undefined
-> undefined
=> 空 Null
-> null
检测数据类型 目的: 用来检查变量存储的数据是一个什么数据类型
typeof 关键字
只能准确的检测基本数据类型
语法:
typeof 要检测的变量
typeof(要检测的变量)
返回值(结果):
以字符串的形式给出你的检测结果
typeof 返回值必然是一个字符串类型
只要两个及以上 typeof 连用, 得到的结果一定是 string
typeof 的返回值
数值 'number'
字符串 'string'
布尔 'boolean'
Undefined 'undefined'
Null 'Object'
数据类型转换
+ 把其他数据类型转换成 数值类型
1. Number()
=> 强制转换, 整体可以转换就是数字
=> 整体不可以转换就是 NaN
2. parseInt()
=> 一位一位看待
=> 不认识小数点
3. parseFloat()
=> 一位一位看待
=> 认识小数点
4. 非加法的数学运算
=> 和 Number 一样都是强制转换
+ 把其他数据类型转换成 字符串类型
1. String()
=> 什么数据类型都可以转换
2. toString()
=> 语法: 转换的数据.toString()
=> undefined 和 null 不能转换
3. 字符串拼接
=> 使用 加号(+) 运算符进行拼接
+ 把其他数据类型转换成 布尔类型
1. Boolean()
=> 只有五个内容是 false
-> 数值 NaN
-> 数值 0
-> 空字符串 ''
-> undefined
-> null
**** 数据类型转换 - 转数值****
+ 把其他数据类型转换成数值类型
1. Number()
+ 语法: Number(你要转换的数据)
+ 返回值(结果): 转换好的数值类型数据
+ 转换规则:
=> 把你要转换的内容当做一个整体
=> 如果可以转换成一个合法数字, 那么就是这个数字
=> 如果不能转换成一个合法数字, 那么就是 NaN
+ 布尔 true 会转换成 1
+ 布尔 false 会转换成 0
2. parseInt
+ 语法: parseInt(你要转换的数据)
+ 返回值(结果): 转换好的数值类型数据
+ 转换规则:
=> 不管你要转换的是什么, 都一位一位的看待
=> 如果第一位就不能转换成合法数字, 那么直接给出结果 NaN, 停止转换
=> 如果第一位可以, 那么保留, 继续看第二位
=> 以此类推, 直到不能转换或者结束为止
+ 注意: 不认识小数点
3. parseFloat()
+ 语法: parseFloat(你要转换的数据)
+ 返回值(结果): 转换好的数值类型数据
+ 转换规则:
=> 和 parseInt 一模一样
=> 只不过多认识了一个 小数点
4. 非加法的数学运算
+ 转换规则: 和 Number 方法一模一样, 强制转换
数据类型转换 - 转字符串
+ 把其他数据类型转换成字符串类型
1. String()
+ 语法: String(你要转换的数据)
+ 返回值(结果): 转换好的字符串类型数据
+ 所有数据类型都能转换
2. toString()
+ 语法: 你要转换的数据.toString()
+ 返回值(结果): 转换好的字符串类型数据
+ 注意: 不能转换 undefined 和 null
3. 字符串拼接
+ 使用加法(+) 运算符进行运算
+ 在 JS 内加法有两个意义
=> 只要符号任意一边是 字符串, 那么就会进行字符串拼接
=> 只有两边都是数值或者布尔的时候, 才会进行数学运算
数据类型转换 - 转布尔
+ 把其他数据类型转换成布尔类型数据
1. Boolean
+ 语法: Boolean(你要转换的数据)
+ 返回值(结果): 转换好的布尔类型数据
+ 在 JS 内, 只有五个内容转换完毕以后是 false, 其余全是 true
=> 数值 NaN
=> 数值 0
=> 空字符串 ''
=> undefined
=> null
运算符
+ 进行运算的符号
+ 大致分为几类
=> 算数运算
=> 赋值运算
=> 比较运算
=> 逻辑运算
=> 自增自减运算
- 算数运算符
-
+ 主要进行数学运算的符号 1. + => 含义1: 进行字符串拼接, 只要符号任意一边是字符串类型 => 含义2: 进行数学运算, 只有符号两边都是布尔或者数字的时候 2. - 3. * 4. / 5. % => 计算两个数字的余数, 不能整除的一部分内容 6. ** => 底数 ** 指数 => 谁 ** 的多少次方
运算符 - 赋值运算符 + 进行赋值操作的符号
1. =
=> 右边的内容给到左边的变量
2. +=
=> 加号(+) 和 赋值(=) 合作
=> n += 10
=> 等价于
=> n = n + 10
3. -=
4. *=
5. /=
6. %=
运算符 - 比较运算符 + 所有的比较运算符结果都是 布尔值
1. > 大于
2. < 小于
3. >= 大于等于
-> 符号左边 大于或者等于 右边为 true
4. <= 小于等于
-> 符号左边 小于或者等于 右边为 true
5. == 等于
-> 符号两边在不考虑数据类型的情况下, 只要值相等即为 true
6. === 等等于
-> 必须符号两边 值和数据类型 都一样, 才能得到 true
7. != 不等于
-> 比较符号两边的内容在不考虑数据类型的情况下, 值是否不等
8. !== 不等等
-> 比较符号两边的内容是否不全等
逻辑运算符 + 进行逻辑运算的符号
1. && 与(且)
=> 符号两边的表达式都为 true 的时候, 最终结果为 true
=> 只要符号任意一边的结果为 false, 最终结果就是 false
=> 同真为真, 一假则假
配合if判断来决定
&& 与(且)
符号两边的表达式都为ture的时候 最终的结果为true
只要符号任意一边的结果为false 最终的结果就是false
同真为真 一假为假
特殊作用:短路表达式
当运算符左边为ture时候 才会执行右边的代码
如果运算符左边为false 那么右边的代码不会执行
=> 特殊作用: 短路表达式
-> 当运算符左边为 true 的时候, 才会执行右边的代码
-> 如果运算符左边为 false, 那么右边的代码不会执行
2. || 或
=> 符号两边的表达式任意一边是 true 的时候, 最终结果就是 true
=> 只有符号两边都是 false 的时候, 最终结果才是 false
=> 一真为真, 同假则假
=> 特殊作用: 短路表达式
-> 当运算符左边为 true 的时候, 右边的代码不会执行
-> 当左边为 false 的时候, 右边的代码才会执行
3. ! 非(取反
=> 本身如果是 true, 那么结果就是 false
=> 本身如果是 false, 那么结果就是 true
=> 特殊作用: 双取反转布尔
自增自减运算符 + 一元运算符的一种
++(为例)
=> 前置加加: 符号在前面, ++变量
=> 后置加加: 符号在后面, 变量++
=> 共同点:
-> 只要执行了, 一定会让改变的值改变(+1)
=> 区别: 在于参与运算的时候
-> 前置++: 会先把变量本身的值改变(+1), 用改变后的值参与运算
-> 后置++: 会先把变量本身的值参与运算, 然后改变变量本身的值(+1)
--
=> 前置减减: 符号在前面, --变量
=> 后置减减: 符号在后面, 变量--
=> 共同点:
-> 只要执行了, 一定会让改变的值改变(-1)
=> 区别: 在于参与运算的时候
-> 后置--: 会先把变量本身的值参与运算, 然后改变变量本身的值(-1)
条件分支语句 - if
+ 意义: 根据条件来决定是否执行代码, 或者执行哪一段代码
+ 注意: 一个条件分支语句只能执行一次67890
1. if 语句
+ 语法: if (条件) { 代码段 }
+ 意义: 当 条件为 true 的时候, {} 内的代码执行, 条件为 false 的时候, {} 内的代码不执行
2. if else 语句
+ 语法: if (条件) { 代码段 } else { 代码段 }
+ 意义: 当 条件为 true 的时候, if 后面的 {} 执行
当 条件为 false 的时候, else 后面的 {} 执行
+ 注意: 两个 {} 能且只能执行一个
3. if ... else if 语句
+ 语法: if (条件1) { 代码段1 } else if (条件2) { 代码段2 } ...
+ 意义:
=> 按照顺序, 依次判断条件, 哪一个条件为 true, 执行哪一个条件后面的 {}
=> 当任何一个条件满足的时候, 后面的就不在执行了
+ 注意: 多个 {} 内的代码最多只能执行一个
4. if ... else if ... else 语句
+ 语法: if (条件1) { 代码段1 } else if (条件2) { 代码段2 } ... else { 代码段 }
+ 意义:
=> 按照顺序, 依次判断条件, 哪一个条件为 true, 执行哪一个条件后面的 {}
=> 当任何一个条件满足的时候, 后面的就不在执行了
=> 当所有条件都不满足的时候, 执行 else 后面的 {}
+ 注意: 多个 {} 能且只能执行一个
案例:
案例1: 判断一个正整数是不是偶数
+ 能被2整除的就是 偶数
+ 如何判断一个正整数是不是被 2 整除
+ 和 2 进行取余运算
if 语句的 () 里面
+ 不管你写什么内容, 都会按照 布尔值 来进行判断
+ 在书写某些条件的时候, 可以进行适当的简化
var a = 19
if( a % 2===0){
console.log('我是偶数')
}else{ console.log('我是奇数')
}
// 案例2:
// + 根据成绩(0 ~ 100) 在控制台输出内容
// => 90 以上输出 A
// => 80 ~ 89 输出 B
// => 70 ~ 79 输出 C
// => 60 ~ 69 输出 D
// => 60 以下输出 E
// 准备变量
var b = 90
// if 条件判断
if ( b >=90 ) {
console.log('优秀')
} else if (b>=80) {
console.log('B')
} else if (b>=70){
console.log('C')
} else if (b>=60) {
console.log('d')
} else if (b<=50) {
console.log('E')
}
**** 三元表达式(三元运算/三目运算/三目)****
语法:
+ 条件 ? 对 : 不对
意义: 对 if else 语句的简写形式
注意: 执行代码的位置只能执行一句话
作用:
1. 利用三元表达式执行代码
2. 利用三元表达式给给变量赋值
// 1. 利用三元表达式执行代码
// var n = 17
// 条件 ? 条件为 true 执行 : 条件为 false 执行
// n % 2 === 0 ? console.log('偶数') : console.log('奇数')
// 2. 利用三元表达式给给变量赋值
// var gender = 男(女)
// var sex = 1 // => 1
// var gender = sex === 0 ? '女' : '男'
// console.log(gender)
// var gender = ''
// if (sex === 0) {
// gender = '女'
// } else {
// gender = '男'
// }
案例
// prompt()
// 语法: prompt(提示文本)
// 表现: 在浏览器出现一个弹出层
// 包含一个输入框, 包含一个确定, 一个取消按钮
// 返回值:
// 如果用户点击的是 确定, 那么返回值就是 文本框输入的内容
// 如果用户点击的是 取消, 那么就是 null
// 注意: 当你点击确定的时候, 返回值必然是一个 string 类型
// var res = prompt('请填写您的身份证号码')
// console.log(res)
// console.log(typeof res)
// 约定: 因为目前所学技能有限, 我们只考虑用户输入的是 18位数字 或者 点击取消
// 约定: 只输入身份证的后四位
// 1. 利用 prompt 采集用户的身份证号
var res = prompt('请输入身份证号的后四位')
console.log(res)
// 2. 判断他点击的是确定还是取消
// 点击确定的时候, 是一个 18位的数字字符串, 转换为布尔就是 true
// 点击取消的时候, 是一个 null, 转换为布尔就是 false
// 如果是 false, 那么我什么都不需要做
if (res) {
// 代码能执行到这里, 说明 res 被转换为了 true, 用户输入了一个 18位数字字符串, 并点击了确定
// 3. 把 18 位数字的 倒数第二位 拆出来
var sex = parseInt(res % 100 / 10)
var gender = sex % 2 === 0 ? '女士' : '先生'
alert('欢迎光临 xxx ' + gender)
}
if 案例
+ 根据 年月日 三个条件
+ 来判断是当年的第几天
/*
分析:
+ 年: 考虑平年还是闰年, 因为 2 月天数不一样
=> 先不管
=> 全部叠加完毕, 最后决定是否补一天
+ 日: 不用管
+ 月
分析月:
+ 如果 month === 2, 叠加 1 月整月天数
+ 如果 month === 3, 叠加 1 月 2 月 整月天数
+ 如果 month === 4, 叠加 1 月 2 月 3 月 整月天数
问题: 什么样的情况需要叠加 1 月的整月 ?
=> month > 1 就需要叠加
问题: 什么样的情况需要叠加 2 月的整月 ?
=> month > 2 就需要叠加
问题: 如何能让一段代码叠加完 1 月再次叠加 2 月 ?
=> 把代码写成两段
*/
var year = prompt('请输入年份') - 0
var month = prompt('请输入月份') - 0
var date = prompt('请输入日期') - 0
// 准备一个变量, 用于累计结果
var day = date
// 月份叠加完毕
if (month > 1) day += 31
// 当你开始叠加 2 月的整月天数的时候, 不能单纯的叠加 28 天
// 如果是 闰年, 叠加 29 天, 如果是 平年, 叠加 28 天
if (month > 2) day += year % 4 === 0 && year % 100 !== 0 || year % 400 === 0 ? 29 : 28
if (month > 3) day += 31
if (month > 4) day += 30
if (month > 5) day += 31
if (month > 6) day += 30
if (month > 7) day += 31
if (month > 8) day += 31
if (month > 9) day += 30
if (month > 10) day += 31
if (month > 11) day += 30
console.log(`第 ${ day } 天`)
条件分支语句 - switch
基础语法:
switch (要判断的内容) {
case 情况1:
情况1满足的时候执行的代码
break
case 情况2:
情况2满足的时候执行的代码
break
default:
所有情况都不满足的时候执行的代码
}
注意:
1. switch 一般不进行范围的判断, 而是准确某些值的判断
2. switch 语句内, 判断的内容和 case 必须值和数据类型都一样, 才叫做满足
3. switch 可以不写 default
=> 如果不写, 所有 case 都不满足的时候没有代码执行
4. switch 语句可以不写 break
=> 如果不写, 会发生 break 穿透效果
break 穿透
+ 从第一个满足条件的 case 开始
+ 如果没有 break
+ 后面的条件不在判断, 直接执行代码
+ 直到遇到 break 或者 switch 结束为止
* ** 案例: 成绩案例**
+ 根据成绩(0 ~ 100) 在控制台输出内容
=> 90 以上输出 A
=> 80 ~ 89 输出 B
=> 70 ~ 79 输出 C
=> 60 ~ 69 输出 D
=> 60 以下输出 E
*/
var score = 55.56
// 1. 用成绩 / 10
// 2. 保留整数部分
// 剩下的只有 10 9 8 7 6 5 4 3 2 1 0
switch (parseInt(score / 10)) {
case 10:
case 9:
console.log('A')
break
case 8:
console.log('B')
break
case 7:
console.log('C')
break
case 6:
console.log('D')
break
default:
console.log('E')
}
编程思维的 "开端" - 循环
1. 循环的意义:
+ 重复的做一个事情
+ 循环三要素
=> 开始
=> 结束
=> 步长
+ 三个要素都可以控制循环的次数
+ 循环为我们提供的内容
=> 重复执行代码的能力
=> 一组有规律的数字
** while 循环语法**
while (条件) {
重复执行的代码
}
+ 意义: 根据条件来决定 {} 内的代码是否执行
+ 过程:
=> 首先, 进行条件判断
=> 如果条件为 false, 结束这个循环
=> 如果条件为 true, 执行 {} 内的代码
=> {} 内代码执行完毕, 再次条件判断
=> ...
+ 注意: 必须要书写步长
简单的示例
1. 准备循环的开始
var n = 1
// 2. 书写循环, 条件位置就是循环的结束
while (n <= 5) {
console.log('我围着操场跑了一圈', n)
// 3. 改变初始变量(步长的设置)
n++
}
console.log('循环结束后的后续代码')
do while 循环
语法:
do {
重复执行的代码
} while (条件)
+ 过程:
=> 不管条件是否满足, 先执行一遍代码
=> 开始进行条件判断
=> 如果条件为 false, 结束循环
=> 如果条件为 true, 那么再次执行一遍代码
=> 再次进行条件判断
=> ...
区别:
+ 当初始变量在条件以内的时候, while 和 do while 没有区别
+ 当初始变量在条件以外的时候
=> while 一次都不执行
=> do while 循环会执行一次
// 简单的小案例
do {
// 出现一段代码去采集用户输入的内容
var pwd = prompt('请输入密码')
} while (pwd !== '123456')
console.log('页面正常打开了')
for 循环
语法:
for (定义初始变量; 条件判断; 修改初始变量) {
重复执行的代码
}
定义初始变量
for (; 条件判断; ) {
重复执行的代码
修改初始变量
}
案例1:
+ 将 1000 ~ 2000 之间所有的闰年输出在页面上
+ 每四个一换行
分析:
1. 你重复做的事情是什么 ?
=> 在页面上输出一个年份数字
=> document.write('内容')
2. 你是否需要一组有规律的数字支持 ?
=> 1000 ~ 2000 之间的数字
// 每四个一换行
// 换行: document.write('<br>')
// 每当你输出了 4 个年份, 输出一次 br
// 准备变量当做计数器
var count = 0
for (var i = 1000; i <= 2000; i += 4) {
// i 是 1000 ~ 2000 之间的每一个 4 的倍数
// 需要判断 i 是闰年才输出(闰年一定是 4 的倍数, 4 的倍数不一定是闰年)
// 判断是闰年才要
if (i % 100 !== 0 || i % 400 === 0) {
document.write(i + ' ')
// 这里的代码执行一次, 表示我输出了一个 年份, 计数器++
count++
// 当计数器是 4 的倍数的时候, 输出一个换行
if (count % 4 === 0) document.write('<br>')
}
}
console.log(count)
案例2:
+ 求水仙花数字
+ 水仙花数字(三次自幂数)
=> 要求:
-> 是一个三位数
-> 每一位的三次方之和 和 这个数字相等
=> 例子: 153
-> 1 * 1 * 1 + 5 * 5 * 5 + 3 * 3 * 3
-> 1 125 27
-> 153
分析:
1. 你要重复执行的操作 ?
=> 判断一个数字的 每一位的三次方之和 是否和这个数字相当
2. 你是否需要一组有规律的数字 ?
=> 需要, 100 ~ 999
*/
for (var i = 100; i <= 999; i++) {
// i 就是 100 ~ 999 之间的所有数字
// 重复要做的事情
// 1. 把当前这个 i 拆开三位数字
var a = parseInt(i / 100)
var b = parseInt(i % 100 / 10)
var c = i % 10
// 2. 判断是否为三次自幂数, 决定是否输出
if (a ** 3 + b ** 3 + c ** 3 === i) {
console.log(i, ' 是三次自幂数')
}
}
循环嵌套
+ 在一个循环内书写另一个循环
+ 注意: 里外层循环不要用一个控制变量
for (var i = 1; i <= 3; i++) {
// 当 i === 1 的时候, j 循环 3 次
// 当 i === 2 的时候, j 循环 3 次
// 当 i === 3 的时候, j 循环 3 次
for (var j = 1; j <= 3; j++) {
console.log(i, ' ---- ', j)
}
}
/*
九九乘法表
*/
// 写一个三角形
for (var i = 1; i <= 9; i++) {
for (var j = 1; j <= i; j++) {
document.write(`<span>${ j } * ${ i } = ${ i * j }</span>`)
}
document.write('<br>')
}
**函数
什么是函数
+ 是一个 JavaScript 内的数据类型, 叫做 Function
+ 是一个复杂数据类型
+ 私人: 是一个 "盒子", 承载的是一段代码
+ 函数的两个阶段
=> 把 代码 装进 "盒子" 的过程 - 函数定义阶段
=> 把 "盒子" 内的代码执行的过程 - 函数调用阶段
函数的定义阶段(如何定义一个函数)
+ 声明式定义函数
=> 语法: function 函数名() { 代码段 }
-> function 定义函数的关键字
-> 函数名 你给这个函数定义的名字(遵循变量的命名规则和规范)
-> () 必须写, 书写参数的位置(欠着)
-> {} 函数体, 存放的就是代码段
+ 赋值式函数(函数表达式)
=> 语法: var 变量 = function () {}
函数调用阶段(如何将函数内的代码执行)
+ 两种定义函数的方式不一样, 但是调用方式一样
+ 语法: 函数名()
函数调用上的区别
+ 两种定义函数的方式
=> 调用方式一样
=> 调用时机不一样
+ 声明式函数: 可以在声明以前调用, 也可以在声明以后调用
+ 赋值式函数: 只能在声明以后调用, 之前调用会报错 xxx is not a function
// 声明式函数
function fn() {
for (var i = 1; i <= 9; i++) {
for (var j = 1; j <= i; j++) {
document.write(`${ j } * ${ i } = ${ i * j } `)
}
document.write('<br>')
}
}
console.log(fn)
// 赋值式函数
var fn2 = function () {
for (var i = 1; i <= 9; i++) {
for (var j = 1; j <= i; j++) {
document.write(`${ j } * ${ i } = ${ i * j } `)
}
document.write('<br>')
}
}
console.log(fn2)
函数的参数
+ 形参
=> 书写在函数定义阶段的小括号内
=> 就是一个只能在函数内使用的变量(遵循变量命名规则和规范)
=> 可以书写多个, 多个之间使用 逗号(,) 分隔
=> 值由函数调用阶段的实参决定
+ 实参
=> 书写在函数调用阶段的小括号内
=> 就是一个真实的值, **按照顺序** 依次给函数的形参赋值
=> 可以书写多个, 多个之间使用 逗号(,) 分隔
function fn(n) {
for (var i = 1; i <= n; i++) {
for (var j = 1; j <= i; j++) {
document.write(`${ j } * ${ i } = ${ i * j } `)
}
document.write('<br>')
}
}
// 本次调用 n 为 9, 九九乘法表
fn(9)
// 本次调用 n 为 7, 7 * 7
fn(7)
函数的返回值
+ 在函数内使用 return 关键字来给函数定义 返回值
*/
// function fn() {
// // 给 fn 这个函数制作了一个 返回值 叫做 100
// // 将来你只要调用 fn 函数, 就能得到 100 这个结果
// return 100
// }
// // 此时 res 接受的就是 fn 函数调用后的 返回值(结果)
// // fn 函数内 return 的内容就会赋值给 res
// var res = fn()
// console.log(res)
打断函数
+ 在函数内使用 return 关键字打断函数
+ 书写在 return 关键字后面行的内容不再执行了
return 有两个作用
1. 给函数制作一个返回值
2. 打断函数
函数小案例: 封装一个函数, 判断一个数字是不是质数
// 判断一个数字是不是质数的函数
// 是否需要参数: 需要1个, 就是要判断的数字
// 是否需要返回值: 需要, 判断的结果, 最好是一个布尔值
// function isPrime(n) {
// // 判断 n 是否是一个质数
// for (var i = 2; i <= n / 2; i++) {
// if (n % i === 0) break
// }
// // 如果是质数, 返回一个 true
// // 如果不是质数, 返回一个 false
// if (i <= n / 2) {
// // 说明不是质数, 返回 false
// return false
// } else {
// // 说明是质数, 返回 true
// return true
// }
// }
function isPrime(n) {
// 判断 n 是否是一个质数
for (var i = 2; i <= n / 2; i++) {
if (n % i === 0) break
}
// 如果是质数, 返回一个 true
// 如果不是质数, 返回一个 false
// 如果 i > n / 2 的结果是 true, 返回 true
// 如果 i > n / 2 的结果是 false, 返回 false
// 直接返回 i > n / 2 的结果
return i > n / 2
}
var r1 = isPrime(102)
console.log(r1)
/*
函数小案例: 封装一个函数, 求两个数字的最大公约数
*/
// 是否需要参数 : 需要两个
// 是否需要返回值: 需要
function fn(a, b) {
// 1. 求 a 和 b 的最大公约数
var max = a > b ? a : b
var min = a > b ? b : a
while (max % min !== 0) {
var tmp = max % min
max = min
min = tmp
}
// 2. 把计算结果当做该函数的返回值
// 代码执行到这里, 说明 min 就是最大公约数
return min
}
var res = fn(19, 17)
console.log(res)
认识作用域
约定: 作用域相关知识点内, 变量一词表示的是 包含变量名和函数名
作用域
+ 一个变量可以生效使用的范围
作用域分类
+ 全局作用域
=> 一个 html 页面打开, 就是一个全局作用域
=> 叫做 window
+ 私有作用域(函数作用域)
=> **只有函数生成私有作用域**
作用域上下级关系
+ 定义在哪一个作用域内的函数, 就是哪一个作用域的子级作用域
提供了三个机制
+ 变量定义机制
=> 定义在哪一个作用域下的变量就是哪一个作用域的私有变量
=> 只能在该作用域及其后代作用域内使用
=> 不能再父级作用域使用
+ 变量访问机制
=> 当你需要访问一个变量的值的时候
=> 首先在自己作用域内查找, 如果有直接使用, 停止查找
=> 如果没有, 自动去到父级作用域查找, 如果有直接使用, 停止查找
=> 如果还没有, 在去到父级作用域查找
=> 以此类推, 直到全局作用域(window) 都没有, 那么报错 xxx is not defiend
+ 变量赋值机制
=> 当你需要给一个变量赋值的时候
=> 首先在自己作用域内查找, 如果有直接赋值, 停止查找
=> 如果没有, 自动去到父级作用域查找, 如果有直接赋值, 停止查找
=> 如果还没有, 在去到父级作用域查找
=> 以此类推, 直到全局作用域(window) 都没有
=> 把这个变量定义为全局变量, 在进行赋值
认识变量的三个行为
变量定义
+ 带有 var 关键字或者 function 关键字
+ 函数的形参
变量访问
+ 当你需要拿到一个变量的值的时候
+ console.log(num)
变量赋值
+ 有赋值符号
+ 实参和形参的交互
变量定义机制
+ 定义在哪一个作用域的变量, 就是哪一个作用域的私有变量
+ 只能在该作用域及其后代作用域内使用
+ 不能再父级作用域使用
变量访问机制
+ 当你需要访问一个变量的值的时候
+ 首先在自己作用域内查找, 如果有直接使用, 停止查找
+ 如果没有, 去到父级作用域查找, 如果有直接使用, 停止查找
+ 如果还没有, 继续需要父级作用域查找
+ 以此类推, 直到全局作用域(window)都没有, 那么报错 xxx is not defined
** 变量赋值机制**
+ 当你需要给一个变量赋值的时候
+ 首先在自己作用域内查找, 如果有直接赋值, 停止查找
+ 如果没有, 直接去到父级作用域查找, 如果有直接赋值, 停止查找
+ 如果还没有, 在去到父级作用域查找
+ 以此类推, 直到全局作用域(window) 都没有
+ 会把这个变量定义为全局变量在进行赋值
递归函数
+ 是一种函数的调用方式, 一种高阶的函数调用方式
+ 什么是递归函数 ?
=> 一个函数自己调用了自己
=> 并且正确设置了返回条件
递归函数的书写技巧
1. 写一个函数
2. 先写折返点
3. 未到达折返点的样子, 不要忘记 return
认识对象数据类型
对象
+ 一类内容中的真实个例
+ 一种 JS 的数据类型 Object
对象数据类型 Object
+ 是一个复杂数据类型
+ 私人: 是一个 "盒子", 是一个承载 数据 的盒子
+ 是一个无序的数据集合
+ 是一个 键值对 的集合
对象数据类型的创建
1. 字面量方式创建对象
+ 语法:
=> 创建一个空对象: var obj = {}
=> 创建一个带有数据的对象: var obj = { 键值对, 键值对, ... }
-> 键值对 键: 值
2. 内置构造函数方式创建
+ 语法:
=> 创建空对象: var obj = new Object()
对象内对于 键(key) 的要求
1. 推荐使用符合变量命名规则和规范的名字
2. 可以使用纯数字当做 键名
-> 当你的键名是纯数字的时候, 会排列在最前面
3. 可以使用任何特殊符号
-> 要求: 当你使用特殊符号的时候, 在书写的时候需要被引号包裹
** 持续更新中,,,**