javascript基础ECMAScript

截图软件: Snipaste
f1:截图(or fn+f1)
f3:定在屏幕上 (or fn+f3)
取色:shift切换
fn+esc:锁定功能键
画笔工具:
Ctrl +1   放大
Ctrl + 2   画图
画图的时候按住ctrl是矩形
画图的时候按住tab是椭圆
画图的时候按字母可以改变颜色:r 红色   b 蓝色    g 绿色   p 粉色   o 橙色
思维导图软件:XMind 8 Update 9
enter 同级
tab  下级
新建:创建
vscode插件:Easy LESS  语法报错检查,比如说同一个变量我用了两次let声明,并赋给不同的值
保存时格式化以及代码缩进两个字符 设置 -> 文本编辑器 -> 格式化   设置-> 常用设置 -> Editor:Tab Size -> 改为2
Live Server插件

基础语法

JavaScript 书写位置

1.内部 JavaScript
规范 :script标签写在</body>上面
我们将 <script> 放在 HTML文件的底部 附近的原因是浏览器会按照代码在文件中的 顺序加载 HTML。
如果先加载的 JavaScript 期望修改其下方的 HTML,那么它可能由于 HTML 尚未被加载而失效。
因此,将 JavaScript 代码放在 HTML页面的底部附近通常是最好的策略
2.外部 JavaScript
语法: 通过script标签,引入到html页面中。
1. script标签中间无需写代码,否则会被忽略!
2. 外部JavaScript会使代码更加有序,更易于复用,且没有了脚本的混合, HTML 也会更加易读,因此这是个好的习惯。
3.代码比较多,就写在外部
3.内联 JavaScript
代码写在标签内部
语法:

注释

单行注释
符号: //
作用: //右边这一行的代码会被忽略
快捷键: ctrl + /
块注释
符号: /* */
作用: 在/* 和 */ 之间的所有内容都会被忽略
快捷键: shift + alt + A
JavaScript结束符( 分号 ; )可写可不写
 

JavaScript 输入输出语法

// 1. 文档输出内容
document.write('我是div标签')
// 2. 控制台打印输出 给 程序员
console.log('看看对不对')
// 弹窗
alert('你好')
// 3. 输入语句
prompt('请输入您的年龄:')

变量

目标:理解变量是计算机存储数据的“ 容器
变量不是数据本身,它们仅仅是一个用于存储数值的容器。可以理解为是一个个用来装东西的纸箱子。
不提倡同时声明多个不同的变量
// 3. 声明的同时直接赋值  变量的初始化
let age = 18
// let 不允许多次声明一个变量。会报错
let num = 20
let num = 23
是通过 变量名 来获得变量里面的数据
// 输出用户名案例
// 1. 用户输入
// prompt('请输入姓名')
// 2. 内部处理保存数据
let uname = prompt('请输入姓名')
// 3. 打印输出
document.write(uname)

    // 交换变量的值
    // let if = 10  // 报错
    let num1 = 'pink老师'
    let num2 = '戚薇'
    let temp
    // 都是把右边给左边
    temp = num1
    num1 = num2
    num2 = temp
    console.log(num1, num2)
变量命名规则与规范
1. 规则:
不能用关键字
关键字:有特殊含义的字符,JavaScript 内置的一些英语词汇。例如:let、var、if、for等
只能用下划线、字母、数字、$组成,且 数字不能开头
字母严格 区分大小写 ,如 Age 和 age 是不同的变量
2. 规范:
起名要有意义
遵守 小驼峰命名法
第一个单词首字母小写,后面每个单词首字母大写。例:userName

  

var 声明:
可以先使用 在声明 (不合理)
var 声明过的变量可以重复声明(不合理)
比如变量提升、全局变量、没有块级作用域等等
!! 不推荐
数组
在数组中,数据的编号也叫 索引或下标
    // 2. 使用数组  数组名[索引号] 从0
    // console.log(arr)
    console.log(arr[0]) // 刘德华
    console.log(arr[4])
    // 3. 数组长度 =  索引号 + 1 
    console.log(arr.length)  // 6

常量

概念: 使用 const 声明的变量称为“常量”。
使用场景: 当某个变量永远 不会改变 的时候,就可以使用 const 来声明,而不是let。
注意: 常量不允许重新赋值,声明的时候必须赋值(初始化)
小技巧: 不需要重新赋值的数据使用const
总结:
let — 现在实际开发变量声明方式。
var — 以前的声明变量的方式,会有很多问题。
const — 类似于 let ,但是变量的值无法被修改。必须初始化(即声明的时候必须赋值), const 声明的变量称为“常量”

数据类型

基本数据类型
number 数字型
string 字符串型
boolean 布尔型
undefined 未定义型
null 空类型

数字类型(Number)

JavaScript 中的正数、负数、小数等 统一称为 数字类型
总结
1. 算术运算符有那几个常见的?
+ - * / %      ------  开发中经常作为某个数字是否被整除
2. 算术运算符优先级怎么记忆?
先乘除取余,后加减,有小括号先算小括号里面的
3. 取余运算符开发中的使用场景是?
来判断某个数字是否能被整除
对NaN做加减乘除的操作结果都是NaN

字符串类型(string)

通过单引号( '') 、双引号( "")或反引号( ` ) 包裹的数据都叫字符串 ,单引号和双引号没有本质上的区别,推荐使用 单引号 。可以互相嵌套(单引号/双引号),必要时可以使用转义符 \,输出单引号或双引号
    console.log('pink老师讲课非常有"基情"')
    console.log("pink老师讲课非常有'基情'")
    console.log('pink老师讲课非常有\'基情\'')

对应结果均是:
pink老师讲课非常有"基情"

拼接字符串和变量
内容拼接变量时,用 ${ 变量名 }(模板字符串)  包住变量,反引号``包含数据
    // let age = 20
    // // 模板字符串 外面用`` 里面 ${变量名}
    // document.write(`我今年${age}岁了`)
    let uname = prompt('请输入您的姓名:')
    let age = prompt('请输入您的年龄:')
    // 输出
    document.write(`大家好,我叫${uname}, 我今年贵庚${age}岁了`)

布尔类型(boolean)

有两个固定的值 true 和 false,表示肯定的数据用 true(真),表示否定的数据用 false(假)

未定义类型(undefined)

只声明变量,不赋值的情况下,变量的默认值为 undefined,不知道是什么类型 
工作中的使用场景:
我们开发中经常声明一个变量,等待传送过来的数据。
如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,来判断用户是否有数据传递过来

null(空类型)

JavaScript 中的 null 仅仅是一个代表“无”、“空”或“值未知”的特殊值
null 和 undefined 区别:
undefined 表示没有赋值
null 表示赋值了,但是内容为空
null 开发中的使用场景:
官方解释:把 null 作为尚未创建的对象
大白话: 将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null
    // 计算有区别
    console.log(undefined + 1)  // NaN
    console.log(null + 1) // 1

检测数据类型

通过 typeof 关键字检测数据类型
1. 作为运算符: typeof x (常用的写法)
2. 函数形式: typeof(x)
    let num = 10
    console.log(typeof num) // number
    let str = 'pink'
    console.log(typeof str) // string
    let str1 = '10'
    console.log(typeof str1) // string
    let flag = false
    console.log(typeof flag) // boolean
    let un
    console.log(typeof (un))  // undefined
    let obj = null 
    console.log(typeof obj) // object


    let num1 = prompt('请输入第一个数:')
    console.log(typeof num1)

类型转换

JavaScript是弱数据类型: JavaScript也不知道变量到底属于那种数据类型,只有赋值了才清楚。
坑: 使用表单、prompt 获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算。
此时需要转换变量的数据类型。
通俗来说,就是 把一种数据类型的变量转换成我们需要的数据类型

隐式转换

规则:
+ 号两边只要有一个是字符串,都会把另外一个转成字符串
除了+以外 的算术运算符 比如 - * / 等都会把数据转成数字类型
+号作为正号解析可以转换成数字型
任何数据和字符串相加结果都是字符串
  

显式转换

转换为数字型
  Number(数据)
转成数字类型
如果字符串内容里有 非数字 ,转换失败时结果为 NaN(Not a Number)即不是一个数字
NaN也是number类型的数据,代表非数字
console.log(Number(NaN), '5555')   // NaN
  parseInt(数据)
只保留整数
  parseFloat(数据)
可以保留小数
    // 1. 用户输入   prompt 得到是字符串类型 要转换为 数字型
    // 用+将prompt当中的输入结果字符串类型转化成数字型类型的
    let num1 = +prompt('请输入第一个数字:')
    let num2 = +prompt('请输入第二个数字:')
    // 2. 输出
    alert(`两个数相加的和是:${num1 + num2}`)
转换为字符型:
   String(数据)
   变量.toString(进制)

流程控制

运算符

= 赋值运算符
执行过程:将等号右边的值赋予给左边, 要求左边必须是一个容器
其他赋值运算符:
+=
-=
*=
/=
%=

一元运算符

自增:
符号:++
作用:让变量的值 +1
自减:
符号:--
作用:让变量的值 -1
通常用来计数
<script>
    // let num = 10
    // num = num + 1
    // num += 1
    // // 1. 前置自增
    // let i = 1
    // ++i
    // console.log(i)

    // let i = 1
    // console.log(++i + 1)  // 3 i先自加1,变成2之后,在和后面的1相加,所以结果是3
    // 2. 后置自增
    // let i = 1
    // i++
    // console.log(i)
    // let i = 1
    // console.log(i++ + 1) // 2,先运算,后面i在自增,此时的i值是2

    // 了解 
    let i = 1
    console.log(i++ + ++i + i) // 7  1 + 3 + 3 = 7
  </script>
1.只需要一个表达式就可以运算的运算符叫一元运算符

比较运算符

比较运算符:
  > : 左边是否大于右边
  <: 左边是否小于右边
  >=: 左边是否大于或等于右边
  <=: 左边是否小于或等于右边
  ==: 左右两边值是否相等
  ===: 左右两边是否类型和值都相等
  !==: 左右两边是否不全等
  比较结果为boolean类型,即只会得到 true 或 false
对比:
  = 单等是赋值
 == 是判断  只要求值相等,不要求数据类型一样即可返回true
 === 是全等  要求值和数据类型都一样返回的才是true
开发中判断是否相等,强烈推荐使用 ===
注意点:
字符串比较,是比较的字符对应的ASCII码,从左往右依次比较
NaN不等于任何值,包括它本身,涉及到"NaN“ 都是false
尽量不要比较小数,因为小数有精度问题
不同类型之间比较会发生隐式转换
   最终把数据隐式转换转成number类型再比较
   所以开发中,如果进行准确的比较我们 更喜欢 === 或者 !==
    console.log(3 > 5)
    console.log(3 >= 3)
    console.log(2 == 2)
    // 比较运算符有隐式转换 把'2' 转换为 2  双等号 只判断值
    console.log(2 == '2')  // true
    // console.log(undefined === null)
    // === 全等 判断 值 和 数据类型都一样才行
    // 以后判断是否相等 请用 ===  
    console.log(2 === '2') // false
    console.log(NaN === NaN) // NaN 不等于任何人,包括他自己
    console.log(2 !== '2')  // true  
    console.log(2 != '2') // false  只比较值,值都是2,类型一个是数值,一个是字符串
    console.log('-------------------------')
    console.log('a' < 'b') // true
    console.log('aa' < 'ab') // true
    console.log('aa' < 'aac') // true
    console.log('-------------------------')

逻辑运算符

使用场景: 逻辑运算符用来解决多重条件判断
判断一个变量 num 是否大于5且小于10
正确写法: num > 5 && num < 10
需求:用户输入一个,判断这个数能被4整除,但是不能被100整除,满足条件,页面弹出true,否则弹出 false(重点是判断语句,以及判断语句得出的是true还是false)
    // 1. 用户输入
    let num = +prompt('请输入一个数字:')
    // 2. 弹出结果
    alert(num % 4 === 0 && num % 100 !== 0)

运算符优先级

一元运算符里面的 逻辑非优先级很高
逻辑与比逻辑或优先级高

语句

表达式和语句的区别
因为表达式可被求值,所以它可以写在赋值语句的右侧。
而语句不一定有值,所以比如 alert() for和break 等语句就
不能被用于赋值。
分支语句包含:
If分支语句
单分支使用语法:
括号内的条件为 true 时,进入大括号里执行代码
小括号内的结果若不是布尔类型时,会发生隐式转换转为布尔类型
如果大括号只有一个语句,大括号可以省略,但是,俺们不提倡这么做
    // 单分支语句
    // if (false) {
    //   console.log('执行语句') // 不执行
    // }
    // if (3 > 5) {
    //   console.log('执行语句') // 不执行
    // }
    // if (2 === '2') {
    //   console.log('执行语句')  // 不执行
    // }
    //  1. 除了0 所有的数字都为真
    //   if (0) {
    //     console.log('执行语句') // 不执行
    //   }
    // 2.除了 '' 所有的字符串都为真 true
    // if ('pink老师') {
    //   console.log('执行语句')
    // }
    // if ('') {
    //   console.log('执行语句') // 不执行
    // }
    // // if ('') console.log('执行语句') // 不执行,不推荐这样写

    // 1. 用户输入
    let score = +prompt('请输入成绩')
    // 2. 进行判断输出
    if (score >= 700) {
      alert('恭喜考入黑马程序员')
    }
    console.log('-----------------')

双分支if语法:
多分支if语法:
三元运算符
符号: ? 与 : 配合使用
判断2个数的最大值
    // 1. 用户输入
    let num1 = +prompt('请您输入第一个数:')
    let num2 = +prompt('请您输入第二个数:')
    // 2. 判断输出-三元运算符
    // if (num1 > num2) {
    //   alert(num1)
    // } else {
    //   alert(num2)
    // }
    num1 > num2 ? alert(`最大值是: ${num1}`) : alert(`最大值是: ${num2}`)

数字补0案例

需求:用户输入1个数,如果数字小于10,则前面进行补0, 比如 09 03 等

    // let age = 18 
    // age = age + 1
    //  age++

    // 1. 用户输入 
    let num = prompt('请您输入一个数字:')
    // 2. 判断输出- 小于10才补0
    // num = num < 10 ? 0 + num : num
    // 此时的num是一个字符串,任何与字符串做加运算的,都会被转换成字符串
    // num = num >= 10 ? num : 0 + num
    num = num < 10 ? 0 + num : num
    alert(num)
switch 语句
用于等值判断
需求:用户输入2个数字,然后输入 + - * / 任何一个,可以计算结果
    // 1.用户输入  2个数字 +  操作符号  + - *  / 
    let num1 = +prompt('请您输入第一个数字:')
    let num2 = +prompt('请您输入第二个数字:')
    let sp = prompt('请您输入 + - * / 其中一个:')
    // 2. 判断输出 sp输入的运算符
    switch (sp) {
      case '+':
        alert(`两个数的加法操作是${num1 + num2}`)
        break
      case '-':
        alert(`两个数的减法操作是${num1 - num2}`)
        break
      case '*':
        alert(`两个数的乘法操作是${num1 * num2}`)
        break
      case '/':
        alert(`两个数的除法操作是${num1 / num2}`)
        break
      default:
        alert(`请输入+-*/`)

    } 
循环结构

断点调试

断点:在某句代码上加的标记就叫断点,当程序执行到这句有标记的代码时会暂停下来
while 循环
小括号里的条件为true才会进入 循环体 执行代码
while大括号里代码执行完毕后不会跳出 ,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到 小括号判断条件,直到括号内条件不满足,即跳出,所以需要这个终止条件,否则的话就会导致一直循环下去,造成死循环
while循环三要素是什么?
变量起始值
终止条件(没有终止条件,循环会一直执行(因为大括号里面的值一直为true),造成死循环)
变量变化量(用自增或者自减)
    // // 1. 变量的起始值
    // let i = 1
    // // 2. 终止条件
    // while (i <= 3) {
    //   document.write('我要循环三次 <br>')
    //   // 3. 变量的变化量
    //   i++
    // }
    // 1. 变量的起始值
    let end = +prompt('请输入次数:')
    let i = 1
    // 2. 终止条件
    while (i <= end) {
      // 加了换行<br>
      document.write('我要循环end次 <br>')
      // 3. 变量的变化量
      i++
    }
循环退出
break:退出循环, 一般用于结果已经得到, 后续的循环不需要的时候可以使用
continue:结束本次循环,继续下次循环,  一般用于排除或者跳过某一个选项的时候,比如我跳过条件等于3的这个选项
简易ATM取款机案例
需求:用户可以选择存钱、取钱、查看余额和退出功能
    // 1. 开始循环 输入框写到 循环里面
    // 3. 准备一个总的金额
    // 这个money的声明必须写在外面,否则的话,每次循环都会重新进行赋值
    let money = 100
    while (true) {
      let re = +prompt(`
        请您选择操作:
        1.存钱
        2.取钱
        3.查看余额
        4.退出
        `)
      // 2. 如果用户输入的 4 则退出循环, break  写到if 里面,没有写到switch里面, 因为4需要break退出循环
      // 只要在这个 while循环当中,不输入4,那就不退出,继续执行语句
      if (re === 4) {
        break
      }
      // 4. 根据输入做操作
      switch (re) {
        case 1:
          // 存钱
          let cun = +prompt('请输入存款金额')
          money = money + cun
          break
        case 2:
          // 存钱
          let qu = +prompt('请输入取款金额')
          money = money - qu
          break
        case 3:
          // 存钱
          alert(`您的银行卡余额是${money}`)
          break
      }
    }

数组

for循环语法

作用: 重复执行代码
好处: 把声明起始值、循环条件、变化值写到一起,让人一目了然 它是最常使用的循环形式
了解
1.while(true) 来构造“无限”循环,需要使用break退出循环。
2. for(;;) 也可以来 构造“无限”循环,同样需要使用break退出循环
    // 无限循环
    for (; ;) {
      console.log(11)
    }

总结
for循环和while循环有什么区别呢:
  当如果明确了循环的次数的时候推荐使用for循环
  不明确循环的次数的时候推荐使用while循环
for循环和while循环有什么区别呢:
Ø 当如果明确了循环的次数的时候推荐使用for循环
Ø 当不明确循环的次数的时候推荐使用while循环
for 循环嵌套
九九乘法表
 <style>
    span {
      display: inline-block;
      width: 100px;
      padding: 5px 10px;
      border: 1px solid pink;
      margin: 2px;
      border-radius: 5px;
      box-shadow: 2px 2px 2px rgba(255, 192, 203, .4);
      background-color: rgba(255, 192, 203, .1);
      text-align: center;
      color: hotpink;
    }
  </style>
</head>

<body>

  <script>
    // 1. 外层循环控制行数
    for (let i = 1; i <= 9; i++) {
      // 2. 里层循环控制列数
      for (let j = 1; j <= i; j++) {
        document.write(`<span>${j} X ${i} = ${i * j}</span>`)
      }
      // 换行
      document.write('<br>')
    }

  </script>
</body>

数组

为什么要数组?
思考:如果我想保存一个班里所有同学的姓名怎么办?放入到一个数组当中
场景:如果有多个数据可以用数组保存起来,然后放到一个变量中,
数组的基本使用

    // 1. 字面量声明数组
    // let arr = [1, 2, 'pink', true]
    // 2. 使用new Array 构造函数声明   了解
    // let arr = new Array(1, 2, 3, 4)
    // console.log(arr)
数组是按顺序保存,所以每个数据都有自己的编号
计算机中的编号从0开始,所以小明的编号为0,小刚编号为1,以此类推
在数组中,数据的编号也叫 索引或下标
数组可以存储任意类型的数据
长度:数组中数据的个数,通过数组的length属性获得(arr.length)
数组求最大值和最小值
    let arr = [2, 6, 1, 7, 400, 55, 88, 100]
    // max里面要存的是最大值
    let max = arr[0]
    // min 要存放的是最小值
    let min = arr[0]
    // 遍历数组
    for (let i = 1; i < arr.length; i++) {
      // 如果max 比 数组元素里面的值小,我们就需要把这元素赋值给 max
      // if (max < arr[i]) max = arr[i]
      max < arr[i] ? max = arr[i] : max
      // 如果min 比 数组元素大, 我们就需要把数组元素给min
      // if (min > arr[i]) {
      //   min = arr[i]
      // }
      min > arr[i] ? min = arr[i] : min
    }
    // 输出 max
    console.log(`最大值是: ${max}`)
    console.log(`最小值是: ${min}`)

操作数组

数组.push() 方法将一个或多个元素添加到 数组的末尾 ,并返回该数组的新长度 (重点)
arr.unshift(新增的内容) 方法将一个或多个元素添加到 数组的开头 ,并返回该数组的新长度
数组. pop() 方法从数组中 删除最后一个元素 ,并返回该元素的值
数组. shift() 方法从数组中 删除第一个元素 ,并返回该元素的值
arr.splice(起,始位置, 删除的个数),指定删除数组元素
案例
根据数据生成柱形图
        // 1. 四次弹框效果
        // 声明一个新的数组
        let arr = []
        // 首先通过循环来得到每个盒子当中的数据,并且存入到数组当中
        for (let i = 1; i <= 4; i++) {
            // let num = prompt(`请输入第${i}季度的数据:`)
            // arr.push(num)
            arr.push(prompt(`请输入第${i}季度的数据:`))
            // push记得加小括号,不是等号赋值的形式
        }
        // console.log(arr)  ['123','135','345','234'] // 得到的就是字符串,因为prompt的返回值就是字符串
        // 盒子开头
        document.write(` <div class="box">`)

        // 盒子中间 利用循环的形式  跟数组有关系
        // 根据之前的到的数组,来渲染柱状图
        for (let i = 0; i < arr.length; i++) {
            document.write(`
              <div style="height: ${arr[i]}px;">
                <span>${arr[i]}</span>
                <h4>第${i + 1}季度</h4>
              </div>          
            `)
        }
        // 盒子结尾
        document.write(` </div>`)

冒泡排序

数组. sort() 方法可以排序

    // let arr = [5, 4, 3, 2, 1]
    let arr = [2, 4, 3, 5, 1]
    // for嵌套循环实现
    // for (let i = 0; i < arr.length - 1; i++) {
    //   for (let j = 0; j < arr.length - i - 1; j++) {
    //     // 开始交换 但是前提 第一个数大于第二个数才交换
    //     if (arr[j] > arr[j + 1]) {
    //       // 交换2个变量
    //       let temp = arr[j]
    //       arr[j] = arr[j + 1]
    //       arr[j + 1] = temp
    //     }
    //   }
    // }

    // arr.sort()  // 排序
    // sort 升序排列,看返回的值是什么,a-b(前面的值减去后面的值)为true的话,说明前面的值更大,就交换数据,为false就不交换
    // arr.sort(function (a, b) {
    //   return a - b
    // })
    // console.log(arr) //[1, 2, 3, 4, 5]

    // sort() 降序排列,b-a(后面的值减去前面的值)为true的话,说明后面的值更大,就交换数据,为false就不交换
    arr.sort(function (a, b) {
      return b - a
    })
    console.log(arr) // [5, 4, 3, 2, 1]

函数

函数名命名规范
  和变量命名基本一致
  尽量小驼峰式命名法
 前缀应该为动词
  命名建议:常用动词约定

alert() 、 prompt() 和 console.log() 都是一些 js 函数 ,只不过已经封装好了,直接使用

函数调用

调用方式: 函数名()

注意:声明(定义)的函数必须调用才会真正被执行,使用 () 调用函数
随时调用,随时执行,可重复调用

函数传参

-参数默认值

函数封装

-求学生总分
    // 1. 封装函数
    // 给一个参数的默认值,这个地方给形参arr默认值为一个数组
    function getArrSum(arr = []) {
      // console.log(arr)
      let sum = 0
      for (let i = 0; i < arr.length; i++) {
        sum += arr[i]
      }
      console.log(sum)
    }
    getArrSum([1, 2, 3, 4, 5])
    getArrSum([11, 22, 33])
    getArrSum()  // 0

函数返回值

有返回值的函数
return 后面代码不会再被执行,会立即结束当前函数,所以 return 后面的数据不要换行写
return函数可以没有 return,这种情况函数默认返回值为 undefined
return后面不接数据或者函数内不写return,函数的返回值是 undefined
    // // 函数的返回值
    // function fn() {
    //   return 20
    // }
    // // fn() 调用者 相当于执行了    fn()   = 20
    // // return 的值返回给调用者
    // // console.log(fn())
    // // let num = prompt('请输入数字')
    // let re = fn()
    // console.log(re)

    function fn() {
      // return //这个地方有没有return都返回undefined
    }
    let re = fn()
    console.log(re)  // undefined
函数返回值练习
    //  3. 求任意数组的最大值和最小值,并且返回
    function getArrValue(arr = []) {
      // (1)先准备一个max变量存放数组的第一个值
      let max = arr[0]
      let min = arr[0]  // 最小值
      // (2) 遍历比较
      for (let i = 1; i < arr.length; i++) {
        // 最大值
        if (max < arr[i]) {
          max = arr[i]
        }
        // 最小值
        if (min > arr[i]) {
          min = arr[i]
        }
      }
      // (3) 返回值  返回的是数组,注意一下这个地方,返回的是数组
      return [max, min]
      // return min
    }
    let newArr = getArrValue([11, 3, 55, 7, 29])
    console.log(`数组的最大值是: ${newArr[0]}`)
在Javascript中 实参的个数和形参的个数可以不一致
  如果形参过多 会自动填上undefined (了解即可)
 如果实参过多 那么多余的实参会被忽略 (函数内部有一个arguments,里面装着所有的实参)

作用域

  全局作用域。函数外部或者整个script 有效
 局部作用域。也称为函数作用域,函数内部有效
变量有一个坑, 特殊情况:
(也即是局部作用域当中用到的变量)局部变量或者块级变量,没有let 声明,直接赋值的,也当 全局变量 看,但是强烈不推荐
但是有一种情况,函数内部的形参可以看做是局部变量。

变量的访问原则

只要是代码,就至少有一个作用域
l 写在函数内部的局部作用域
l 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
l 访问原则: 在能够访问到的情况下 先局部, 局部没有在找全局, 采取 就近原则 的方式来查找变量最终的值

匿名函数

匿名函数
没有名字的函数, 无法直接使用。
使用方式:

1.函数表达式

将匿名函数赋值给一个 变量 ,并且通过 变量名称 进行调用,我们将这个称为 函数表达式
    // console.log(num)
    // let num = 10

    // 3 + 4
    // num = 10
    // 1. 函数表达式
    fn(1, 2)  //错误 函数表达式提前调用了
    let fn = function (x, y) {
      // console.log('我是函数表达式')
      console.log(x + y)
    }

    // 函数表达式和 具名函数的不同   function fn() {}
    // 1. 具名函数的调用可以写到任何位置
    // 2. 函数表达式,必须先声明函数表达式,后调用
    // function fun() {
    //   console.log(1)
    // }
    // fun()

2.立即执行函数

场景介绍: 避免全局变量之间的污染
注意: 多个立即执行函数要用 ; 隔开(;可以写在函数前面,也可以写在函数后面),要不然会报错
立即执行函数 无需调用,立即执行,其实本质已经调用了
<script>
    // flexible.js当中就是立即执行函数的写法,用这个立即执行函数把里面的代码包起来的原因是:因为这个是作为第三方的文件(插件)引进来的,如果不加这个立即执行函数,就会造成这里面代码的一些变量名和我们的一些变量名冲突
    // let num = 10
    // let num = 20
    // (function () {
    //   console.log(11) // 11
    // })()

    // (function () {
    //   let num = 10
    // })();
    // (function () {
    //   let num = 20
    // })();
    // 1. 第一种写法
    (function (x, y) {
      console.log(x + y) // 3
      let num = 10
      let arr = []
    })(1, 2);
    // (function(){})();
    // 2.第二种写法
    // (function () { }());
    (function (x, y) {
      let arr = []
      console.log(x + y) // 4
    }(1, 3));
    // 这样也是立即执行函数写法,给立即执行函数命名了的方式
    (function zzz(x, y) {
      let arr = []
      console.log(x + y) // 4
    }(1, 3));


    // (function(){})()
    // (function(){}())
  </script>
转换时间案例
计算公式:计算时分秒
小时: h = parseInt(总秒数 / 60 / 60 % 24)
分钟: m = parseInt(总秒数 / 60 % 60 )
秒数: s = parseInt(总秒数 % 60)
    // age = age + 1
    // 1. 用户输入
    let second = +prompt('请输入秒数:')
    // 2.封装函数
    function getTime(t) {
      // console.log(t)  // 总的秒数
      // 3. 转换
      // 小时:  h = parseInt(总秒数 / 60 / 60 % 24)
      // 分钟:  m = parseInt(总秒数 / 60 % 60)
      // 秒数: s = parseInt(总秒数 % 60) 
      let h = parseInt(t / 60 / 60 % 24)
      let m = parseInt(t / 60 % 60)
      let s = parseInt(t % 60)
      h = h < 10 ? '0' + h : h
      m = m < 10 ? '0' + m : m
      s = s < 10 ? '0' + s : s
      // console.log(h, m, s)
      return `转换完毕之后是${h}小时${m}分${s}秒`
    }
    let str = getTime(second)
    document.write(str)
    console.log(h)

3.逻辑中断

1.逻辑运算符里的短路
&&逻辑与与||逻辑或左右也可以写表达式
    function fn(x, y) {
      x = x || 0
      y = y || 0
      console.log(x + y)
    }
    fn(1, 2)
    // fn()

    // console.log(false && 22) // false
    // console.log(false && 3 + 5) // false 一假则假
    // let age = 18
    // console.log(false && age++) // age++ 不执行  一假则假
    // console.log(age) // 18

    // console.log(true || age++) // true,逻辑或,一真得真,只要前面一个是真值那后面就不判断了
    // console.log(age)


    // console.log(11 && 22)  // 都是真,这返回最后一个真值,逻辑与,两个都为真值的话,返回后面的一个值
    // console.log(11 || 22)  //  输出第一个真值

思考拓展:

2. 转换为Boolean型
显示转换:
1.Boolean(内容)
记忆 ‘’ 、0、undefined、null、false、NaN 转换为布尔值后都是false, 其余则为 true

代码测验:

    console.log(Boolean('pink')) // true
    console.log(Boolean('')) // false
    console.log(Boolean(0)) // false
    console.log(Boolean(90)) // true
    console.log(Boolean(-1)) // true 除了0之外都为真true,小数也是
    console.log(Boolean(undefined)) // false
    console.log(Boolean(null)) // false
    console.log(Boolean(NaN)) // false

    console.log('--------------------------')
    let age
    if (age) {
      console.log(11) // 不执行 age为undefined
    }
隐式转换:

对象

对象有属性和方法组成
属性:信息或叫特征(名词)。 比如 手机尺寸、颜色、重量等…
方法:功能或叫行为(动词)。 比如 手机打电话、发短信、玩游戏…

语法一样,判断标准就是对象有没有这个属性, 没有就是新增,有就是改
属性-查的另外一种写法
对于多词属性或则 - 等属性,点操作就不能用了。
我们可以采取: 对象[‘属性’] 方式, 单引号和双引号都阔以
总结:
1. 对象访问属性有哪两种方式?
  点形式 对象.属性
  [] 形式 对象[‘属性’]
2. 两种方式有什么区别?
  点后面的属性名一定不要加引号
  [] 里面的属性名一定加引号
  后期不同使用场景会用到不同的写法

对象中的方法

方法的调用与对象的调用是一样的,都可以用.与['']来调用

遍历对象
一般不用这种方式遍历数组、主要是用来遍历对象
for in语法中的 k 是一个变量, 在循环的过程中依次代表对象的属性名
由于 k 是变量, 所以必须使用 [ ] 语法解析
一定记住: k 是获得对象的 属性名 对象名[k] 是获得 属性值
    // for in 我们不推荐遍历数组,因为k是字符串
    // let arr = ['pink', 'red', 'blue']
    // for (let k in arr) {
    //   console.log(k)  // 数组的下标 索引号  但是是字符串 '0',所以不提倡
    //   console.log(arr[k])  // arr[k]
    // }
    // 1. 遍历对象 for in   
    let obj = {
      uname: 'pink老师',
      age: 18,
      gender: '男'
    }
    // 2. 遍历对象
    for (let k in obj) {
      console.log(k) // 属性名  'uname'   'age'
      // console.log(obj.uname)
      // console.log(obj.k)
      // console.log(obj.'uname')
      // console.log(obj['uname'])   'uname'  === k
      console.log(obj[k])  // 输出属性值  obj[k]
    }

内置对象-Math

介绍: Math对象是JavaScript提供的一个“数学”对象
作用: 提供了一系列做数学运算的方法
Math对象包含的方法有:
random:生成0-1之间的随机数(包含0不包括1)
ceil:向上取整
floor:向下取整
max:找最大数
min:找最小数
pow:幂运算
abs:绝对值
console.log(Math.round(-1.5))  // -1
// 取整函数 parseInt('12px')   // 12
// null  类似 let obj = {} 
let obj = null  // 这个变量要存一个对象,但是这个对象还没有准备好,就可以用null先替代一下,所以null叫空对象,用typeof检测就是object
内置对象-生成任意范围随机数
Math.random() 随机数函数, 返回一个0 - 1之间,并且包括0不包括1的随机小数 [0, 1)
如何生成0-10的随机数呢?
Math.floor(Math.random() * (10 + 1))
如何生成5-10的随机数?
Math.floor(Math.random() * (5 + 1)) + 5
l如何生成N-M之间的随机数
Math.floor(Math.random() * (M - N + 1)) + N
案例
猜数字游戏
    // 1. 随机生成一个数字 1~10
    // 取到 N ~ M 的随机整数
    function getRandom(N, M) {
      return Math.floor(Math.random() * (M - N + 1)) + N
    }
    let random = getRandom(1, 10)
    // 2. 设定三次  三次没猜对就直接退出
    let flag = true  // 开关变量 
    for (let i = 1; i <= 3; i++) {
      let num = +prompt('请输入1~10之间的一个数字:')
      if (num > random) {
        alert('您猜大了,继续')
      } else if (num < random) {
        alert('您猜小了,继续')
      } else {
        flag = false
        alert('猜对了,真厉害')
        break
      }
    }
    // 写到for的外面来
    if (flag) {
      alert('次数已经用完')
    }
生成随机颜色
    // 1. 自定义一个随机颜色函数
    function getRandomColor(flag = true) {
      if (flag) {
        // 3. 如果是true 则返回 #ffffff
        let str = '#'
        let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
        // 利用for循环随机抽6次 累加到 str里面
        for (let i = 1; i <= 6; i++) {
          // 每次要随机从数组里面抽取一个  
          // random 是数组的索引号 是随机的
          let random = Math.floor(Math.random() * arr.length)
          // str = str + arr[random]
          str += arr[random]
        }
        return str

      } else {
        // 4. 否则是 false 则返回 rgb(255,255,255)
        let r = Math.floor(Math.random() * 256)  // 55
        let g = Math.floor(Math.random() * 256)  // 89
        let b = Math.floor(Math.random() * 256)  // 255
        return `rgb(${r},${g},${b})`
      }

    }
    // 2. 调用函数 getRandomColor(布尔值)
    // 会随机更改,但是格式是这样
    console.log(getRandomColor(false)) // rgb(170,53,77)
    console.log(getRandomColor(true)) // #472bd8
    console.log(getRandomColor())  // #65a558


    // let str = '#'
    // str = str + 'f'
拓展-术语解释
目标:了解基本数据类型和引用数据类型的存储方式
简单类型又叫做基本数据类型或者 值类型 ,复杂类型又叫做 引用类型
l 值类型:简单数据类型/基本数据类型,在存储时变量中 存储的是值本身 ,因此叫做值类型
string ,number,boolean,undefined,null
l 引用类型:复杂数据类型,在存储时变量中 存储的仅仅是地址(引用) ,因此叫做引用数据类型
通过 new 关键字创建的对象 (系统对象、自定义对象),如 Object、Array、Date等

堆栈空间分配区别:
1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的
栈;
简单数据类型存放到栈里面
2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
引用数据类型存放到堆里面

1. 简单类型的内存分配
l 值类型(简单数据类型): string ,number,boolean,undefined,null
l 值类型变量的数据直接存放在变量(栈空间)中
2. 复杂类型的内存分配
l 引用类型(复杂数据类型):通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
l 引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中

以上为学习时记的笔记,后期可能会改进!!!

  • 17
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值