JS基础笔记

71 阅读37分钟

1.JavaScript是什么?

  是一种运行在客户端(浏览器)的编程语言,实现人机互动效果。

  作用:1.网页特效(监听用户的一些行为让网页作出对应的反馈)
        2.表单验证(针对表单数据的合法性进行判断)
        3.数据交互(获取后台的数据,渲染到前端)
        4.服务端编程(node.Js)

2.Js组成有什么?

  1.ECMAScript:规定了js基础语法核心知识。   比如:变量、分支语句、循环语句、对象等

  2.Web APIs:1.DOM 操作文档,比如对页面元素进行移动、大小、添加删除等操作
              2.BOM 操作浏览器,比如页面弹窗,检查窗宽度、存储数据到浏览器等
注:查资料去mdn网站,比较权威

3.js书写位置

  和css一样可以有:1.行内  2.内部  3.外部
      1.内部:直接写在html文件里的,用script标签包住    规范:script标签写在</body>上面
          拓展:alert('你好,js')

  2.外部:代码写在.js结尾的文件里
      语法:通过script标签,引入到html页面中。<script scr="~.js"></script>   此时不要在<script>标签中间写代码,否则会被忽略
          优点:会使代码更加有序,更易于复用,且没有了脚本的混合,html也更加易读。

  3.内联js:代码写在标签内部(vue框架会用到这种写法)

4.js怎么写?

  1.注释
    单行注释:符号://
              作用://右边这一行的代码会被忽略、
              快捷键:ctrl+/
    多行注释(块注释):符号/* */
            作用:在/* */之间的所有内容都会被忽略
            快捷键:shift+alt+a

  2.结束符(是可以省略的)
      作用:使用英文的“;”代表语句的结束
      实际情况:实际开发中,可写可不写,浏览器可以自动推断出语句的结束位置
      现状:在实际的开发中,越来越多的人主张,书写js时省略结束符
      约定:为了风格统一,结束符要么都写,要么都不写(按照团队要求)

5.js语法:

人和计算机打交道的规则约定,我们要按照这个规则去写,想要操控计算机,需要计算机能看懂
  目标:能写出常见js输入输出语法
输入和输出:输入和输出可以理解为人和计算机的交互,用户通过键盘、鼠标等向计算机输入信息,计算机处理后再展示结果给用户,便是一次输入和输出的过程。
  输出语法:
    1.document.write('要出的内容')   作用:向body内输出内容   注:如果输出的内容是标签(document.write('<h1>要出的内容</h1>')),也会被解析成网页元素
    2.alert('要出的内容')   作用:页面弹出警告对话框
    3.console.log('控制台打印')    作用:控制台输出语法,程序员调试使用

  输入语法:
    1.prompt('请输入您的姓名:')  作用:显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字

6.代码执行顺序:

html文档顺序执行js代码,alert()和prompt()他们会跳过也页面渲染先被执行(后期再详细了解

7.字面量:

在计算机科学中,字面量(literal)是在计算机中描述  事/物
目标:能说出什么是字面量
比如:1.我们工资是 1000   此时1000就是数字  字面量
      2.‘黑马程序员’ 字符串字面量
      3.[]  数组字面量    {}  对象字面量  等

8.变量是什么?

白话:就是一个装东西的盒子
通俗:就是计算机中用来存储数据的‘容器’,它可以让计算机变得有记忆
注:变量不是数据本身,仅仅是一个用于存储数值的容器,可以理解为一个装东西的纸箱子。

基本使用:
  1.声明变量:要想使用变量,首先需要创建变量(也称为声明变量或者定义变量)
    语法:let 变量名  例如:let age
    构成:声明关键字、变量名(标识)  let即关键字,age即变量的名称,也叫标识符
  2.变量赋值:定义了一个变量后,你就能初始化它(赋值)。在变量名之后跟上一个‘=’(=在这里叫赋值号),然后是数值。

  变量初始化:声明的同时直接赋值,例如:let age = 18

  3.更新变量:变量赋值后,还可以通过简单地给它一个不同的值来更新它。
      例如 let age = 18   age=19let age = 18   let age = 19       x

  4.声明多个变量:多个变量中间用逗号隔开   例如:let age = 18,uname = 'pink'    console.log(age,uname)
注:更提倡于分开写,为了更好的可读性,建议一行只声明一个变量

变量本质:是程序在内存中申请的一块用来存放数据的小空间
变量的命名规则与规范:
  1.规则:必须遵守,不遵守报错(相当于法律层面)
  2.规范:建议,不遵守不会报错,但不符合业内通识(相当于道德层面)
  规则:1.不能用的变量名:有特殊含义的字符,js内置的一些英语词汇。例如:letvariffor2.变量名只能用下划线_、字母、数字、$组成,且数字不能开头
        3.变量名字母严格区分大小写,如Age和age是两个不同的变量

  规范:1.起名要有意义
        2.遵守小驼峰命名法:第一个单词首字母小写,后面每个单词首字母大写。例如:userName

变量拓展:  
  1.letvar 区别:在较旧的lavaScript,使用关键字 var 来声明变量 ,而不是 letvar现在开发中一般不再使用它,只是我们可能再老版程序中看到它,let 为了解决 var 的一些问题。
      var 声明:1.可以先使用 在声明(不合理)
              2.var 声明过的变量可以重复声明(不合理)
              3.比如变量提升、全局变量、没有块级作用域等等
结论:var 就是个bug,别迷恋它了,以后声明变量我们统一使用let2.数组(Array):一种将一组数据存储在单个变量名下的优雅方式。     let arr/数组名 = [数据1,数据2,...,数据n](字面量)
      1.数组是按顺序保存,所以每个数据都有自己的编号。      2.计算机中的编号从0开始,所以数据1是编号0,数据2是编号1,以此类推
      3.在数组中,数据的编号也叫索引或下标                 4.数组可以存储任意类型的数据,例如:数据1是文字,数据2是数字

  数组的基本使用:语法:数组名[下标]   例如:let names = ['小明','小刚'...]    names [0] (取了“小明”值)   names [1]  (取了“小刚”值)
    元素:数组中保存的每个数据都叫数组元素
    下标:数组中数据的编号
    长度:数组中数据的个数,通过数组的length属性获得     例如:console.log(names.length)就会在控制台中看到有多少

9.常量的基本使用

概念:使用const声明的变量称为: “常量”
使用场景:当某个变量永远不会改变的时候,就可以使用const来声明,而不是let
命名规范:和变量一致
常量使用:const G = 9.8    console.log(G)
注:常量不允许重新赋值,声明的时候必须赋值(初始化)   小技巧:不需要重新赋值的数据使用const
对比:let  现在实际开发变量声明方式
      var  以前的声明变量方式,会有很多问题
      const   类似于let,但是变量的值无法被修改

10.数据类型

  目标:能说出js中基本数据类型有哪些?
  为什么要给数据分类:1.更加充分和高效的利用内存  2.更加方便程序员的使用数据
    js数据主要分为两大类
      基本数据类型:1.number 数字信息 2.string 字符串型 3.boolean 布尔型 4.undefined 未定义型 5.null 空类型 .........
      引用数据类型:object 对象

数字类型(number):即我们数学中学习到的数字,可以是整数、小数、正数、负数。js里面的数字统称为 数字类型
注:js是弱数据类型,变量到底是属于那种类型,只有赋值之后,我们才能确认 例如:let number = '汉字'  可以不一定是数字,这就是字符串类型
    java是强数据类型  例如:int a =3 是数字且必须是整数
      1.数字可以有很多操作,经常和算术运算一起,数学运算符也叫算术运算符,主要包括加+、减-、乘*、除/、求余数%(例如:5/3 余数为2)。
注:先乘除取余,后加减,有括号先算括号里的,取余符号使用场景:判断某个数字能不能被整除
补充:NaN代表一个计算错误,它一个不正确的或者一个未定义的数学操作所得到的结果(例如:console.log('老师'-2),浏览器中会显示NaN),任何对NaN的操作都会得到NaN。

字符串类型(string):通过单引号''、双引号""或者反引号包裹的数据叫字符串,单引号和双引号本质上没有区别,推荐单引号。只要被单、双、反引号包裹上的东西,哪怕是数字,也会变成字符串。当引号内没有内容时,叫空字符串
注:1.无论是单引号还是双引号必须成对使用,单、双引号可以互相嵌套,但是不能自己嵌套自己(口诀:外双内单,外单内双)。
    2.必要时可以使用转义符\,(例如:console.logh('老\'师\'')) \后的符号会被略过
        字符串拼接:利用“+”运算符,可以实现字符串的拼接  
            例如:前提:let age = 18
            document.write('我今年18岁了')  =  document.write('我今年' + age + '岁了') = document.write('我今年' + age + '岁了')

模板字符串:
  使用场景:拼接字符串和变量,在没有它之前,要拼接变量比较麻烦,如上例
  语法:``反引号:在英文输入模式下按键盘的tab键上方那个键(1左边那个键)
          内容拼接变量时,外面用``包裹,里面用 ${}包住变量
          例如:document.write(`大家好,我叫${name},今年${age}岁`)

布尔类型(boolean):在计算机中表示肯定或否定,它有两个固定的布尔字面量:true/false,表示肯定的数据和否定的数据
  写法:let isCool = true/false
          console.log(isCool)
  
未定义类型(undefin):未定义是比较特殊的类型,只有一个值 undefined。
  什么情况出现未定义类型?
  只声明变量,不赋值的情况下,变量的默认值为 undefined,一般很少【直接】为某个变量赋值为 undefined。
    例如: let age     //声明变量但是未赋值
          document.write(age)   //输出undefined
  工作中的使用场景:
  我们开发中经常声明一个变量,等待传送过来的数据。
  如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,就判断用户是否有数据传递过来。

null(空类型):js中的null仅仅是一个代表 无、空或值未知的特殊值    null是空类型的一个固定的字面量
    写法:let obj = null
          console.log(obj)    //null
    nullundefined的区别:undefined表示没有赋值,null表示赋值了,但是内容为空。
    使用场景:把null作为尚未创建的对象,就是将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null

检测数据类型:通过typeof关键字检测数据类型。    写法:typeof x或typeof(x) 结果都一样,常用前者。    具体效果:看练习

类型转换:为什么需要类型转换?       
  1.JavaScript是弱数据类型:JavaScript也不知道变量到底属于那种数据类型,只有赋值了才清楚。
  2.使用表单、prompt 获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算。
  例如:console.log('10000' + '2800')   //输出结果  100002000
  此时需要转换变量的数据类型,通俗来说,就是把一种数据类型的变量转换成我们需要的数据类型。
    隐式转换:某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换,
      例如:+号两边只要有一个是字符串,都会把另外一个转成字符串,除了+以外的算术运算符 比如-*/等都会把数据转成数字类型。
      看下面例子的输出结果帮助理解
        <script>
          console.log(11 + 11)      //22
          console.log('11'+ 11)     //1111
          console.log(11 - 11)      //0
          console.log('11'- 11)     //0
          console.log(1*1)          //1
          console.log('1'*1)        //1
          console.log(typeof '123')    //string
          console.log(typeof +'123')   //number
          console.log(+'11'+ 11)       //22
        </script>
      由上可得: +号放在前面可以将字符串类型转换成数字类型,任何数据和字符串相加结果都是字符串

    显示转换:编写程序时过度依靠系统内部的隐式转换是不严谨的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。那我们自己写代码告诉系统该转成什么类型转换为数字型
     方法:使用Number(数据) 转成数字类型,看例子
        如果字符串内容里有非数字,转换失败时结果为NaN(NotaNumber)即不是一个数字,NaN也是number类型的数据,代表非数字,NaN不等于任何人,包括它自己
        
         parselnt(数据):只保留整数,parseFloat(数据):可以保留小数
        下面的例子帮助理解
          let str = '123'
          console.log(Number(str))                    //数字类型

          let num = Number(prompt('输入年薪'))        
          let num = +prompt('输入年薪')     隐式转化  
          console.log(Number(num))                   //数字类型
          console.log(num)                           //数字类型

          console.log(parseInt('12px'))               //12
          console.log(parseInt('12.34px'))            //12
          console.log(parseInt('12.94px'))            //12
          console.log(parseInt('abc12.94px'))         //NaN

          console.log(parseFloat('12px'))             // 12
          console.log(parseFloat('12.34px'))          // 12.34
          console.log(parseFloat('12.94px'))          //12.94
          console.log(parseFloat('abc12.94px'))       //NaN

11.运算符

1.赋值运算符:对变量进行赋值的运算符,把右边的值给左边,要求左边必须是一个容器
  目标:能够使用赋值运算符简化代码
    已经学过的运算符:=   其他的运算符:+= -= *= /= %=
    示例:let num = 1
        num = num + 1      等价于      num += 1   剩下的以此类推

2.一元运算符:根据所需表达式的个数,分为 一元/二元/三元 运算符
  目标:能够使用一元运算符做自增运算
    示例:let num = +'123'          此时 + 叫一元运算符  (也就是正负号)
          let num = 10 + 10         此时 + 叫二元运算符
          let num = 10 + 10 + 10    此时 + 叫三元运算符
      自增运算符:++  作用:让变量的值+1
      自减运算符:--  作用:让变量的值-1
        使用场景:经常用于计数来使用。比如进行10此操作,用它来计算进行了多少次了
      前置自增与后置自增:
        示例:let num = 1
            ++num(前置自增) 或 num++(后置自增)
          作用:每执行一次,相当于 num += 1
        区别:(如果参与运算就有区别,比较难,了解即可,但是两者在独立使用时,没有区别)
          示例:let i = 1
                console.log(++i + 1)    //结果是3
                console.log(i++ + 1)    //结果是2
              前置~:先自加再使用运算   后置~:先使用运算再自加
        注:后置自增使用相对较多,一般都是独立使用
    自减运算符同理!
  拓展:面试题:let i = 1
                console.log(i++ + ++i + i)   //7     实际上就是 1+3+3


3.比较运算符:比较结果为boolean类型,即只会得到truefalse。具有隐式转换,会把字符串类型转换成数字类型
    目标:能使用常见的比较运算符进行比较运算
      >(左边是否大于右边)  <(左边是否小于右边)  >=(左边是否大于或等于右边) <=(左边是否小于或等于右边)
        ==(左右两边值是否相等) ===(左右两边是否类型和值都相等) !=(左右两边是否不等) !==(左右两边是否不全等)
      对比:= == ===  赋值、只判断值、判断值和数据类型是否全等    开发中判断是否相等,强烈推荐使用===
    使用场景:比较两个数据大小、是否相等。比如购买东西时,筛选价格区间时
    拓展:字符串比较,是比较字符对应的ASCII码,从左往右依次比较,如果第一位一样再比较第二位,以此类推,了解即可。
  注:NaN和谁比较都是 false。  尽量不要比较小数,因为小数有精度问题

4.逻辑运算符:
    &&(逻辑与):读法:并且   特点:符号两边都为true,结果才为true   口诀:一假则假
    ||(逻辑或):读法:或者   特点:符号两边有一个true,结果就为true 口诀:一真则真
    ! (逻辑非):读法:取反   特点:truefalsefalsetrue        口诀:真变假,假变真
  拓展:错误写法: 5< num <10   正确写法: num > 5 && num < 10
    使用场景:逻辑运算符用来解决多重条件判断

5.运算符优先级:
运算符
1          小括号                         ()
2          一元运算符                     ++  --  !
3          算数运算符                     先* / % 后+ -  
4          关系(比较)运算符              >  >==  <  <==
5          相等运算符                     ==  !==  ===  !==
6          逻辑运算符                     先&&  后||
7          赋值运算符                     =
8          逗号运算符                     ,            
练习:let a =3 > 5 && 2 < 7 && 3 == 4
      console.log(a);           //a=false
      let b = 3 <= 4 || 3 > 1 || 3 != 2
      console.log(b);           //b=true
      let C = 2 === "2"
      console.log(c);            //c=false
      let d = !c || b && a
      console.log(d);            //d=true

12.语句

1.表达式和语句
  目标:能说出表达式和语句的区别
    表达式:表达式是可以被求值的代码,js引擎会将其计算出一个结果。比如x = 7    3 + 4    num++
    语句:一段可以被执行的代码。 比如:prompt()可以弹出一个输入框,还有if语句  for循环语句等
      区别:表达式:因为表达式可被求值,所以它可以写在赋值语句的右侧。 num = 3 + 4
            语句:而语句不一定有值,所以比如alert() forbreak 等语句就不能被用于赋值

2.分支语句:可以让我们有选择性的执行想要的代码
    前提:程序三大流程控制语句:
          ·以前我们写的代码,写几句就从上往下执行几句,这种叫顺序结构
          ·有的时候要根据条件选择执行代码,这种就叫分支结构
          ·某段代码被重复执行,就叫循环结构
    1.if分支语句:三种使用:单分支、双分支、多分支
        单分支使用语法:if(条件) {                                  
                          满足条件要执行的代码
                        }
            注:1.括号内的条件为true时,进入大括号里执行代码。
                2.小括号内的结果若不是布尔类型时,会发生隐式转换为布尔类型
                3.如果大括号只有一个语句,大括号可以省略,但是不提倡
          拓展:所有数字除了0 都为真,除了空字符串,所有字符串都为真。
    
        双分支if语法:if(条件){
                        满足条件要执行的代码
                      }else{
                        不满足条件执行的代码
                      }
        使用场景:适合于有多个结果的时候,比如学习成绩可以分为:优 良 中 差
        多分支if语法:if(条件1){
                        代码1
                      }else if(条件2){
                        代码2
                      }else if(条件3){
                        代码3
                      }else{}
                      ......
            不满足,就一直往下推,可以写n个,最后一个只写else,中间的写else if

    2.三元运算符:? 和 : 配合使用
    使用场景:其实是比if双支更简单的写法,一般用来取值
      语法:条件 ? 代码1(满足条件时) : 代码2(不满足条件时)

    3.switch语句:
        目标:能利用switch执行满足条件的语句
        switch(数据){
          case1:     //注意格式
              代码1
              break     //代表如果满足此值,这里就退出此算法
          case2:
              代码2
              break
          ......
          default:
          代码n
          }
        释义:找到跟小括号里数据全等的case值,并执行里面对应的代码若没有全等 === 的则执行default里的代码
        例:数据若跟值2全等,则执行代码2
      注:1.switch case语句一般用于等值判断,不适合于区间判断
          2.switch case一般需要配合break关键字使用 没有break会造成case穿透

3.循环语句:
    目标:掌握循环结构,实现一段代码重复执行
    学习路径:
      1.断点调试:
          作用:学习时可以帮助更好的理解代码运行,工作时可以更快找到bug
            用法:1.浏览器打开调试界面
                  2.按F12打开开发者工具
                  3.点到sources一栏
                  4.选择代码文件
                  5.点击想要选中的代码前面的数字,取消也是
                  6.刷新页面
      2.while循环:
          语法:while(循环条件){
              要重复执行的代码(循环体)
              }
            释义:1.if语句很像,都要满足小括号里的条件为true才会进入循环体 执行代码。
                 2.while大括号里代码执行完毕后不会跳出,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到小括号判断条件,直到括号内条件不满足,即跳出。
          while 循环三要素: 循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。
          所以,while循环需要具备三要素:1.变量起始值 2.终止条件(没有终止条件,循环会一直执行,造成死循环) 3.变量变化量(用自增或自减)、
            例如:let i = 1 
                  while (i <= 3){
                    document.write('我会循环三次<br>')
                    i++
                    }
          小技巧:利用while(true)来构造“无限”循环,需要使用break退出循环
          循环退出:
            目标:能说出continuebreak的区别
            break:退出循环
            continue:结束本次循环,继续下次循环
            区别:
            continue:退出本次循环,一般用于排除或者跳过某一个选项的时候,可以使用continue
            break:退出整个循环,一般用于结果已经得到,后续的循环不需要的时候可以使用

        if多分支语句和 switch的区别:
          1.共同点
          都能实现多分支选择,多选1
          大部分情况下可以互换
          2.区别:
          switch...case语句通常处理case为比较确定值的情况,而if...slse...语句更加灵活,通常用于范围判断(大于,等于某个范围)。
          switch 语句进行判断后直接执行到程序的语句,效率更高,而if...slse语句有几种判断条件,就得判断多少次。
          switch 一定要注意 必须是 === 全等,一定注意 数据类型,同时注意break否则会有穿透效果
          结论:
          当分支比较少时,if..else语句执行效率高。
          当分支比较多时,switch语句执行效率高,而且结构更清晰

13. 1.for循环:

  目标:掌握for循环重复执行某些代码
  1.for循环语法
  作用:重复执行代码
  好处:把声明起始值、循环条件、变化值写到一起,让人一目了然,它是最常使用的循环形式
  语法:for(变量起始值;终止条件;变量变化量){
          // 循环体 
          }
  技巧:for(;;)也可以来构造“无限”循环,需要使用break退出循环
  for循环和while循环有什么区别呢:
    1.当如果明确了循环的次数的时候推荐使用for循环
    2.当不明确循环的次数的时候推荐使用while循环
  2.循环嵌套:
    for 循环嵌套语法:
      for(外部声明记录循环次数的变量;循环条件;变化值) {
        for(内部声明记录循环次数的变量;循环条件;变化值){
              循环体
          }
        }
      一个循环里再套一个循环,一般用在for循环里

2.数组:(Array)是一种可以按顺序保存数据的数据类型
    目标:能说出数组是什么
    为什么要数组?
      如果有多个数据可以用数组保存起来,然后放到一个变量中,管理非常方便
    1.基本使用
        目标:能够声明数组并且能够获取里面的数据
      1.声明语法
      let 数组名 =[数据1,数据2,...,数据n]
      let arr = new Array(数据1,数据2,..数据n)
        例:let names =['小明','小刚','小红','小丽','小米']
          由上可得:
            数组是按顺序保存,所以每个数据都有自己的编号
            计算机中的编号从0开始,所以小明的编号为0,小刚编号为1,以此类推
            在数组中,数据的编号也叫索引或下标
            数组可以存储任意类型的数据      
      2.取值语法:数组名[下标]
          例:let names =['小明','小刚','小红','小丽','小米']
              names[0]     //小明
              names[1]     //小刚
              通过下标取数据,取出来是什么类型的,就根据这种类型特点来访问        
      3.一些术语:
          元素:数组中保存的每个数据都叫数组元素
          下标:数组中数据的编号
          长度:数组中数据的个数,通过数组的length属性获得
      4.遍历数组(重点)
          目标:能够遍历输出数组里面的元素
              用循环把数组中每个元素都访问到,一般会用for循环遍历
                语法:for(let i = 0; i < 数组名.length; i++){
                        数组名[i]
                      }
                    let nums =[10,20,30,40,50]
                    for(let i = 0i < nums.lengthi++){
                      fordocument.write(nums[i])
                      }
      5.操作数组
        1.数组本质是数据集合,操作数据无非就是 增 删 改 查 语法。  为了更好的理解,请搭配13.查改增删练习
            1.查
            查询数组数据
            数组[下标]
            或者我们称为访问数组数据
            2.改
            重新赋值
            数组[下标]=新值
            3.增
            数组添加新的数据
            arr.push(新增的内容)
            arr.unshift(新增的内容)
            目标:掌握利用push向数组添加元素(数据)
                1.数组.push()方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度(重点).
                  语法:arr.push(元素1,...,元素n)
                例如:let arr = ['red','green']
                      arr.push('pink','sao')
                      consoie.log(arr)                    //['red','green','pink','sao']
                      console.log(arr.push())            // 4    验证了上面 返回该数组的新长度 这句话
                2.arr.unshift(新增的内容)方法将一个或多个元素添加到数组的开头,并返回该数组的新长度
                  语法:同上
            4.删
            删除数组中数据
            arr.pop()
            arr.shift()
            arr.splice(操作的下标,删除的个数)
            目标:能够删除数组元素(数据)
              1.数组.pop()方法从数组中删除最后一个元素,并返回该元素的值。
                  语法:arr.pop()
                    例如:let arr =['red','green']
                        arr.pop()
                        console.log(arr)                //['red'] 
                        consoie.log(arr.pop())           //green     会告诉你删除的是什么   验证了上面 返回该元素 这句话
              2.数组.shift()方法从数组中删除第一个元素,并返回该元素的值。
                  语法:arr.shift()
                    例如:同上
              3.数组.splice()方法 删除指定元素
                  语法:arr.splice(start, deletecount)
                      arr.splice(起始位置,删除几个元素)    //如果不填删几个,会从起始位置删到最后
                    解释:start 起始位置:
                        指定修改的开始位置(从0计数)
                        deletecount:
                        表示要移除的数组元素的个数
                        可选的。如果省略则默认从指定的起始位置删除
                        到最后
                      使用场景举例:随机抽奖,中奖的用户就需要从数组里面删除,不允许重复抽奖

3.拓展1.冒泡排序:是一种简单的排序算法。
                  它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
                  这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
            比如数组 [2,3,1,4,5]经过排序成为了[1,2,3,4,5]或者[5,4,3,2,1]
      2.数组排序 数组.sort() 方法可以排序
          语法:
            let arr =[4,2,5,1,3]
            1.升序排列写法
                arr.sort(function(a,b){
                  return a-b
                    })
                   console,log(arr)          //[1,2,3,4,5]
            2.降序排列写法
                arr.sort(function(a,b){
                   return b-a
                     })
                   console.log(arr)          //[5,4,3,2,1]
  参考案例:13.拓展.冒泡排序和数组排序案例

14.函数

目标: 能说出为什么需要函数
  函数:
  函数(function),是被设计为执行特定任务的代码块
    说明:
    函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用。
    比如我们前面使用的 alert()、prompt()和 console.log()都是一些js 函数,只不过已经封装好了,我们直接使用的。

  1.函数使用
  目标:掌握函数语法,把代码封装起来
    1.函数的声明语法
      function 函数名(){
        函数体
      }
    例:function sayHi(){
      document.write('hai~~')
    }
      2.函数名命名规范
        1.和变量命名基本一致
        2.尽量小驼峰式命名法
        3.前缀应该为动词
        4.命名建议:常用动词约定
          动词                    含义
          can                   判断是否可执行某个动作
          has                   判断是否含义某个值
          is                    判断是否为某个值
          get                   获取某个值
          set                   设置某个值
          load                  加载某些数据 
        3.函数的调用语法
            函数调用,:这些函数体内的代码逻辑会被执行
              函数名()
            注意:声明(定义)的函数必须调用才会真正被执行,使用()调用函数
              例:
              函数一次声明可以多次调用,每一次函数调用函数体里面的代码会重新执行一次
               sayHi()
                sayHi()
              我们曾经使用的 alert(),parseInt()这种名字后面跟小括号的本质都是函数的调用
            小结:1.函数是用那个关键字声明的?
                    function
                  2.函数不调用会执行吗?如何调用函数?
                    函数不调用自己不执行
                    调用方式:函数名()
                  3.函数的复用代码和循环重复代码有什么不同?
                    循环代码写完即执行,不能很方便控制执行位置
                    随时调用,随时执行,可重复调用

  2.函数传参
     1.声明语法
      function 函数名(参数列表){
      函数体
      }
      function getsquare(num1){
        document.write(num1 * num1)
        }
      function getSum(num1, num2){
        document.write(num1 + num2)
      }
        参数列表
          传入数据列表
          声明这个函数需要传入几个数据上
          多个数据用逗号隔开              
     2.调用语法
      函数名(传递的参数列表)
      例:getSquare(8)
          getsum(10, 20)
      调用函数时,需要传入几个数据就写几个,用逗号隔开
      function getSum(numl,num2){               //num1 和 num2 是形参
          document.write(num1 + num2)           //10 和 20 是实参
      }getSum(10,20) 
        1.形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
        2.实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
        3.形参可以理解为是在这个函数内声明的变量(比如 num1=10)实参可以理解为是给这个变量赋值
        4.开发中尽量保持形参和实参个数一致
        5.我们曾经使用过的 alert('打印’),parseInt('11'),Number('11)本质上都是函数调用的传参
     3.小结
        1.函数传递参数的好处是?
            可以极大的提高了函数的灵活性
        2.函数参数可以分为那两类?怎么判断他们是那种参数?
            函数可以分为形参和实参
            函数声明时,小括号里面的是形参,形式上的参数
            函数调用时,小括号里面的是实参,实际的参数 
            尽量保持形参和实参的个数一致
        3.参数中间用什么符号隔开?
            逗号
     4.参数默认值
          形参:可以看做变量,但是如果一个变量不给值,默认是什么?     undefined
          但是如果做用户不输入实参,刚才的案例,则出现 undefined+undefined 结果是什么?     NaN
          我们可以改进下,用户不输入实参,可以给 形参默认值,可以默认为 0,这样程序更严谨,可以如下操作:
          function getSum(x=0,y=0){
            document.write(x + y)
          }
          getSum()        //结果是0,而不是NaN
          getSum(1, 2)    //结果是3
          说明:这个默认值只会在缺少实参参数传递时 才会被执行,所以有参数会优先执行传递过来的实参,否则默认为undefined

  3.函数返回值
      提问:什么是函数?
        函数是被设计为执行特定任务的代码块
      提问:执行完特定任务之后,然后呢?
        把任务的结果给我们
        缺点:把计算后的结果处理方式写死了,内部处理了
          解决:把处理结果返回给调用者
        有返回值函数的概念:
          当调用某个函数,这个函数会返回一个结果出来
          这就是有返回值的函数 
      1.函数返回值
          其实我们前面已经接触了很多的函数具备返回值:
              let result = prompt('请输入你的年龄?')
              let result2 = parseInt('111')
            只是这些函数是JS底层内置的.我们直接就可以使用
              当然有些函数,则没有返回值
                  alert('我是弹框,不需要返回值')
                所以要根据需求,来设定需不需要返回值。 
        当函数需要返回数据出去时,用return关键字
          语法:return 数据
            怎么使用呢?
              function getsum(x,y){
               return x+y
             }
             let num = getsum(10,30)
             document.write(num)
          细节:
            1.在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用
            2.return后面代码不会再被执行,会立即结束当前函数,所以return后面的数据不要换行写
            3.return函数可以没有return,这种情况函数默认返回值为 undefined
            4.两个相同的函数后面的会覆盖前面的函数
            5.Javascript中 实参的个数和形参的个数可以不一致。
              1.如果形参过多 会自动填上undefined(了解即可)
              2.如果实参过多 那么多余的实参会被忽略(函数内部有一个arguments,里面装着所有的实参)
            6.函数一旦碰到return就不会在往下执行了 函数的结束用return
      2.小结
        1.为什么要让函数有返回值
          1.函数执行后得到结果,结果是调用者想要拿到的(一句话,函数内部不需要输出结果,而是返回结果)
          2.对执行结果的扩展性更高,可以让其他的程序使用这个结果
        2.函数有返回值用那个关键字?有什么注意事项呢?
          1.语法:return 数据
          2.return后面不接数据或者函数内不写return,函数的返回值是undefined
          3.return能立即结束当前函数,所以return 后面的数据不要换行写
        思考:1.如何返回多个数据? 使用数组: return arr = [max, min]
             2.break的结束和return结束有什么区别? 前者结束for循环或switch,后者结束的是函数

  4.作用域:通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
      作用:作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
        1.全局作用域:全局有效
            作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件
        2.局部作用域:局部有效
            作用于函数内的代码环境,就是局部作用域。 因为跟函数有关系,所以也称为函数作用域。
            在JavaScript中,根据作用域的不同,变量可以分为:
        3.全局变量:函数外部let 的变量
            全局变量在任何区域都可以访问和修改
        4.局部变量:函数内部let的变量
            局部变量只能在当前函数内部访问和修改
        5.变量的访问原则
            1.只要是代码,就至少有一个作用域。
            2.写在函数内部的局部作用域
            3.如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。
            4.访问原则:在能够访问到的情况下 先局部,局部没有在找全局
        6.小结
          1.JS 中作用域分为哪2种?
              1.全局作用域。函数外部或者整个script有效
              2.局部作用域。也称为函数作用域,函数内部有效
          2根据作用域不同,变量分为哪2种?
              1.全局变量
              2.局部变量
          3.有一种特殊情况是全局变量是那种?我们提倡吗?
              1.局部变量或者块级变量 没有let声明直接赋值的当全局变量看
              2.我们强烈不提倡
              3.还有一种特殊情况,函数内部的形参可以当做局部变量看
          4.变量访问原则是什么?
              采取就近原则的方式来查找变量最终的值
  5.匿名函数
      目标:了解匿名函数的使用方式
        函数可以分为:1.具名函数:
                        声明:function fn(){}
                        调用:fn()
                    2.匿名函数:function(){}      
                        没有名字的函数,无法直接使用。
                        使用方式:1.函数表达式 2.立即执行函数
        1.函数表达式:将匿名函数赋值给一个变量,并且通过变量名称进行调用 我们将这个称为函数表达式
        语法:let fn =function(){
                  //函数体
            }
        调用: fn()   // 函数名()
              其中函数的形参和实参使用跟具名函数一致。
            函数表达式和具名函数的不同:
              1.具名函数的调用可以写到任何位置
              2.函数表达式,必须先声明函数表达式,后调用
        2.立即执行函数
            场景介绍:避免全局变量之间的污染语法:
              方式1:(function(形参){ })(实参);
              方式2:(function(形参){ }(实参));       //本质上  (实参)  就是调用
                注意: 多个立即执行函数要用 ;隔开,要不然会报错
            小结:1.立即执行函数有什么作用?
                    防止变量污染
                  2.立即执行函数需要调用吗? 有什么注意事项呢?
                    1.无需调用,立即执行,其实本质已经调用了
                    2.多个立即执行函数之间用分号隔开
  6.逻辑中断
       1.逻辑运算符里的短路
          短路:只存在于 && 和 || 中,当满足一定条件会让右边代码不执行
            符号                 短路条件
            &&                 左边为false就短路                都是真,则返回最后一个真值
            ||                 左边为true就短路                 输出第一个真值
      原因:通过左边能得到整个式子的结果,因此没必要再判断右边
        运算结果:无论 && 还是‖,运算结果都是最后被执行的表达式值,一般用在变量赋值
       2.转换为Boolean1.显示转换:1.Boolean(内容)
            记忆:''(空字符串)、0undefinednullfalseNaN 转换为布尔值后都是false,其余则为 true
              console.log(false && 20)                  // false
              onsole.log(5<3 && 20)                     // flase
              console.log(undefined && 20)              //undefined
              console.log(null && 20)                   // null
              console.log(0 && 20)                      //0
              console.log(10 && 20)                     //20
              console.log(false || 20)                  // 20                 
              console.log(5<3 || 20)                    // 20
              console.log(undefined || 20)              //20
              console.log(null || 20)                   //20
              console.log(0 || 20)                      //20
              console.1og(10 || 20)                     //10
          2.隐式转换:
              1.有字符串的加法“ ”+ 1,结果是 “12. 减法-(像大多数数学运算一样)只能用于数字,它会使空字符串 " " 转换为 0
              3.null 经过数字转换之后会变为 0
              4.undefined 经过数字转换之后会变为NaN
                console.log('' - 1)                 //-1
                console.log('pink老师' - 1)         //NaN
                onsole.log(null + 1)                //1
                console.log(undefined + 1)          //NaN
                console.log(NaN + 1)                //NaN
                  '' - 2                  //-2
                  null + 3                //3
                  undefined + 3           //NaN
                  null == undefined       //true
                  null=== undefined       //false

15.对象

1.对象是什么?
    1.对象(object):JavaScript里的一种数据类型
    2.可以理解为是一种无序的数据集合,注意数组是有序的数据集合
    3.用来描述某个事物,例如描述一个人。
        1.人有姓名、年龄、性别等信息、还有吃饭睡觉打代码等功能
        2.如果用多个变量保存则比较散,用对象比较统一
    4.比如描述 班主任 信息:
        1.静态特征(姓名,年龄,身高,性别,爱好) => 可以使用数字,字符串,数组,布尔类型等表示
        2.动态行为(点名,唱,跳,rap) => 使用函数表示
    5.小结
      1.对象是什么?
        1.对象是一种数据类型
        2.无序的数据的集合
      2.对象有什么特点?
        1.无序的数据的集合
        2.可以详细的描述描述某个事物
2.对象使用
    目标:掌握对象语法,用它保存多个数据
      1.对象声明语法
          let 对象名 = {}
          let 对象名 = new object()
        例如:let person={}             //声明了一个person的对象         
            实际开发中,我们多用花括号。{}是对象字面量
      2.对象有属性和方法组成
          1.属性:信息或叫特征(名词)。比如 手机尺寸、颜色、重量等...
          2.方法:功能或叫行为(动词)。比如 手机打电话、发短信、玩游戏..              
                let 对象名 = {
                   属性名:属性值,
                   方法名:函数
                }
      3.属性:数据描述性的信息称为属性,如人的姓名、身高、年龄、性别等,一般是名词性的
                let obj = {
                  uname:'pink老师'
                  age: 18,
                  gender:'女'
                }
          属性都是成 对出现的,包括属性名和值,它们之间使用英文 : 分隔
          多个属性之间使用英文 ,分隔
          属性就是依附在对象上的变量(外面是变量,对象内是属性)
          属性名可以使用 ""'' ,一般情况下省略,除非名称遇到特殊符号如空格、中横线等      
      4.小结         
          1.对象属性有顺序吗?
              没有
          2.属性和值用什么符号隔开?多个属性用什么隔开?
              1.属性和值用 ;隔开
              2.多个属性用 , 逗号隔开
      5.对象本质是无序的数据集合,操作数据无非就是 增 删 改 查 语法
            1.查:对象.属性
              查的另外一种写法
                对于多词属性或则 - 等属性,点操作就不能用了
                我们可以采取: 对象['属性']方式,单引号和双引号都阔以
            2.改:对象.属性 = 新值
            3.增:对象名.新属性名 = 新值
            4.删:delete 对象名.属性名
      6.小结
        1.对象查语法如何写?
          对象名.属性
        2.对象访问属性有哪两种方式?
          1.点形式   对象.属性
          2.[]形式   对象['属性']
        3.两种方式有什么区别?
          1.点后面的属性名一定不要加引号
          2.[]里面的属性名一定加引号
          3.后期不同使用场景会用到不同的写法
        4.对象改语法如何写:
          对象名.属性 = 新值
        5.对象增语法如何写:
          对象名.新属性名 = 新值
      改和增语法一样,判断标准就是对象有没有这个属性,没有就是新增,有就是改
          let person ={
          name:'pink老师',
          age: 18,
          gender:'女'
          }
          console.log(person.age)                    //查语法
          person.gender='男'                         //改语法
          person.address='武汉黑马'                  //增语法b 
      7.对象中的方法
          1.数据行为性的信息称为方法,如跑步、唱歌等,一般是动词性的,其本质是函数。
              let person ={
                name: 'andy',
                sayHi: function(){
                document.write('hi~~')
                  }
              }
              1.方法是由方法名和函数两部分构成,它们之间使用 : 分隔
              2.多个属性之间使用英文 , 分隔
              3.方法是依附在对象中的函数
              4.方法名可以使用 " "'',一般情况下省略,除非名称遇到特殊符号如空格、中横线等。
          2.声明对象,并添加了若干方法后,可以使用 . 调用对象中函数,我称之为方法调用。
              也可以添加形参和实参
                let person = {
                  name: 'andy'
                  sayHi:function(){
                  document.write('hi~~')
                  }
                }
                person.sayHi()              // 对象名.方法名()    
                  注意: 千万别忘了给方法名后面加小括号
3.遍历对象
    目标:能够遍历输出对象里面的元素
        1.for 遍历对象的问题:
            1.对象没有像数组一样的length属性,所以无法确定长度
            2.对象里面是无序的键值对,没有规律.不像数组里面有规律的下标
          语法:let obj = {
              uname: 'andy'
              age: 18,
              sex: '男'
            }
              for(let k in obj){
              console.log(k)            // 打印属性名
              console.log(obj[k])       // 打印属性值
            }
            1.一般不用这种方式遍历数组、主要是用来遍历对象
            2.for in语法中的 k 是一个变量,在循环的过程中依次代表对象的属性名
            3.由于k是变量,所以必须使用[]语法解析
            4.一定记住:k 是获得对象的 属性名,对象名[k] 是获得 属性值
          小结
            1.遍历对象用那个语句?
              for in
            2.遍历对象中,for kin obj,获得对象属性是那个,获得值是那个?
              1.获得对象属性是 k
              2.获得对象值是 obj[k]
4.内置对象
    内置对象是什么?
        JavaScript内部提供的对象,包含各种属性和方法给开发者调用
      1.思考:我们之前用过内置对象吗?
          document.write()
          console.log() 
      2.内置对象-Math
          介绍:Math对象是JavaScript提供的一个“数学”对象
          作用:提供了一系列做数学运算的方法
          Math对象包含的方法有:
            random:生成0-1之间的随机数(包含0不包括1)
            ceil:向上取整
            floor:向下取整
            max:找最大数
            min:找最小数
            pow:幂运算
            abs:绝对值
        1.内置对象-生成任意范围随机数
            Math.random()随机数函数,返回一个0-1之间,并且包括0不包括1的随机小数[0,1)
              1.如何生成0-10的随机数呢?
                Math.floor(Math.random()*(10 + 1))      //floor用来取整
              2.如何生成5-10的随机数?
                Math.floor(Math.random()*(5+1))+ 5
              3.如何生成N-M之间的随机数
                Math.floor(Math.random()*(M-N+1))+ N
            例:1. 0~10 之间的整数
                  console.log(Math.floor(Math.random()* 11))
                2.let arr = ['red', 'green', 'blue']
                  let random = Math.floor(Math.random() * arr.length)
                  console.log(random)             //0 或 1 或 2
                  console.log(arr[random])        //red 或 green 或 blue
5.拓展
    目标:知道一些术语,让自己更专业
        术语                    解释                                                                        举例
        关键字            在JavaScript中有特殊意义的词汇                                    letvarfunctionifelseswitchcasebreak
        保留字            在目前的lavascript中没意义,但未来可能会具有特殊意义的词汇           int、short、long、char
        标识(标识符)      变量名、函数名的另一种叫法                                          无
        表达式            能产生值的代码,一般配合运算符出现                                  10+3、age >=18
        语句              一段可执行的代码                                                  If()for()
      1.拓展-基本数据类型和引用数据类型
          目标:了解基本数据类型和引用数据类型的存储方式
            简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
              1.值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型string,number,boolean, undefined, null
              2.引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型通过 new 关键字创建的对象(系统对象、自定义对象),如 0biect、ArrayDate2.复杂类型的内存分配
        1.引用类型(复杂数据类型):通过 new 关键字创建的对象(系统对象、自定义对象),如 0biect、ArrayDate2.引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中
      3.堆栈空间分配区别:
        1.栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈
        简单数据类型存放到栈里面
        2.堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
        引用数据类型存放到堆里面