JavaScript基础

JavaScript基础入门

  • JavaScript 是运行在客户端的脚本语言

  • 浏览器如何执行JS语句?

    浏览器本身并不会执行JS代码,而是通过JS引擎来执行JS代码,JS引擎执行代码时逐行解释每一句源码(转换为机器语言),后由计算机执行,所以JS归为脚本语言。

  • 浏览器分为渲染引擎和JS引擎

    1. 渲染负责解析HTML和CSS,俗称内核
    2. JS负责解析JS语句,又称JS解释器
  • JS三部分组成:ECMAScript,DOM(文本对象模型).BOM(浏览器对象模型).

    1. ECMAScript又称JS,实际上JS是ECMAScript语言的实现和扩展

      • 规定了JS的编程语法和基础核心知识,是一套工业标准
    2. DOM——文档对象模型

      对页面各种元素进行操作

    3. BOM——浏览器对象模型

      对浏览器窗口进行操作,比如弹出框,控制浏览器跳转,获取分辨率等

  • JS书写位置:行内,内嵌,外部

    1. 行内:以onclick开头,
    	<input type="button" value="点击" onclick="alert('OK')">
    
    1. 外部样式内不能再添加东西
    	<script src="my.js"></script>
    

  • JS注释快捷键 单行注释:ctrl+/

    ​ 多行注释:shift+alt+A

    ​ 修改多行注释快捷键: ctrl+shift+/

  • JS输入和输出语句

    • alert(msg):浏览器弹出警示框

    • console.log(msg):浏览器控制台打印输出信息

      • console.log()和console.dir()的区别

        • console.log()可以取代alert()或document.write(),在网页脚本中使用console.log()时,会在浏览器控制台打印出信息。
        • console.dir()可以显示一个对象所有的属性和方法。
    • prompt(info):浏览器弹出输入框,用户可以输入

  • JS常见弹出框

    • 警告框:window.alert() 方法可以不带上window对象,直接使用alert()方法。

      alert([content]): 【一个按钮】提示框 ,只有确定按钮

    • *提示框:****confirm([content]): 【两个按钮】提示框,里面既有确定按钮,也有取消按钮,我们可以定义一个变量来接收它的返回值,返回值为TRUE说明点击的是确定;

    • 确认框:****prompt([content]):【两个按钮+输入框】提示框,在confirm基础上可以填写原因,填写的内容可以用变量接收,常见于某些留言本;

  • JS变量

    变量是一个装东西的盒子,是用于存放数据的容器,我们通过变量名获取数据

    变量的本质是程序在内存中申请的一块用来存放数据的空间

    • 变量使用

      1. 声明变量 2. 赋值

      声明一个变量并赋值,称之为变量的初始化

      var  age  = 18;
      
    • 变量语法扩展

      1. 更新变量:一个变量被重新赋值后,原有的值就会被覆盖,变量值将以最后一次赋的值为准

      2. 声明多个变量

        同时声明多个变量,只需写一个var,变量之间使用英文逗号隔开。

        var age =10,name = 'zs',sex = 2;
        
      3. 声明变量特殊情况

        只声明,不赋值 ,结果为?即undefined

        不声明,不赋值,直接使用某个变量会报错

        不声明,直接赋值,可以使用,但不提倡

    • 变量命名规范

      1. 变量名只允许出现下划线(_),$两种特殊符号
      2. 严格区分大小写,如App和app是两个变量
      3. 不能以数字开头
      4. 不能是关键字,保留字,如var,for,while[name不是关键字,但在一些浏览器中有特殊含义,不提倡使用]
      5. 变量名必须有意义
      6. 遵循驼峰命名法,即首字母小写,后面单词首字母大写,myFileName
    • 变量交换

      两个变量互换,需要一个临时变量来帮助实现,就如同我们必须先把右手的青苹果放到左手,此刻左手拿着青,红两种苹果,出现临时变量

      var temp;
      
      var apple1 = "A";
      
      var apple2 = "B";
      
      temp = apple1;//与数学相反,意思是把右边给左边,即给temp赋值为apple1的值A,即把A苹果放到桌上
      
      apple1 = apple2; //苹果1被拿走,变量为空,得到苹果2的值“B”,即拿走B苹果
      
      apple2 = temp;//被赋予temo的值,即apple2拿到桌子上的A苹果
      
    • 变量小结

      • 为什么需要变量?因为我们一些数据需要保存

        变量是什么?变量就是一个容器,用来存放数据,方便我们以后使用

        变量的本质?变量时内存里的一块空间,用来储存数据

        变量如何使用?先声明变量,再赋值变量。 声明变量的本质是去内存申请空间

        变量的初始化? 声明变量并赋值

        变量命名规范有哪些?驼峰命名法,区分哪些变量不合法

        交换变量思路?声明临时变量,交换赋值。

  • 数据类型

    不同数据所需占用的存储空间是不同的,为了便于区分,充分利用储存空间,定义了不同的数据类型,

    数据类型是数据的类别型号

    JS是一种弱类型语言或者说动态语言,所以不用提前声明变量类型,程序运行过程中,根据等号右边的值,类型会自动确定。

    JS具有动态类型,即相同的变量可作不同的类型。

    var x = 6;
    
    var x = "Bill";
    
    • Number:数字型,包括整数和浮点数
    • Boolean:布尔值类型,如true,false
    • String:字符串类型,在js里,字符串都带引号
    • underfined:声明变量未给值
    • null:变量为空
  • Number

    • 在JS中八进制前面加0,十六进制前面加0x

    • 数字类型最大值:console.log(Number.MAX_VALUES);

    • 数字型的三个特殊值:alert(Infinity);

      • Infinity:代表无穷大,大于任何数值
      • -Infinity:代表无穷小,小于任何数值
      • NaN,Not a Number:代表一个非数值
    • isNaN() 这个方法用来判断非数字,并且返回一个值(true,false)

      console.log(isNaN(12));
      
  • String

    JS可以用单引号嵌套双引号,或者用双引号嵌套单引号(外单内双,外双内单)

    var srt = "夫'道德仁义礼',五者一体也。"
    

    系统单(双)引号会自动匹配最近的单(双)引号,形成字符串

    字符串内不能使用HTML的换行标识,需要使用字符串转义符,类似于HTML上的特殊字符,如
    ,

    转义符都是\开头的,换行符:\n,缩进:\t,空格:\b,斜杠:\,单引号:\,双引号:*,都要写到引号里面

    弹出网页警示框 alert(\n指另起一行);

    • String

      检测获取字符串长度 length

      var str = "aaaaaa";
      console.log(str.length);
      
  • 字符串拼接

    1. 多个字符串可以使用+进行拼接,拼接方式为:字符串+任何类型 = 拼接后的新字符串

    2. 拼接前会把与字符串相加的任何类型转换成字符串,再拼接一个新的字符串

    3. 只要有字符串和其它类型相拼接,最终结果是字符串类型

    4. console.log('aa'+18);   输出aa18
      console.log(12+12);   输出24
      console.log('12'+12);   输出1212
      
    5. +号口诀:数值相加,字符相连

      变量和字符串相连口诀:引引加加

      console.log('aa'+age+'岁');
      

      变量不能加引号,加引号的变量会变成字符串

  • 交互编程三要素

    1. 用户输入(我可以追你吗)
    2. 程序处理内部结果(女孩想了想)
    3. 输出结果(最后说:你是个好人)
  • 案例

    var  age = prompt('请输入年龄')var str =  '你今年'+age+'岁了'alert(str);
    
    
  • Boolean

    布尔型有两个值:true,false

    布尔型与数字型相加时:true的值为1,false的值为0

    undefined 和数字相加,最后的结果是 NaN

    console.log(true+1);   //输出结果为2 
    
    var set;   //一个变量声明未赋值,就是undefine
    
    console.log(set + "gg");      //输出结果为undefinedgg
    
    var  de  =  null;
    
    console.log(de+'OK');   //输出结果为nullOK
    
    console.log(de+1);   //输出结果为1
    
    获取数据类型:typeof可以用来检测变量的数据类型
    
    var   num  = 18;
    
    console.log(typeof  num);    //输出结果为 number
    
    

    在浏览器控制台中,数字型为蓝色,字符串类型为黑色,深蓝色是布尔型,浅灰色是特殊字符

    字面量是源代码中一个固定值的表示法,即字面来看如何表达这个值

    数字字面量:1,2,3;字符串字面量:’小人‘;布尔:true;数组:[ ]

  • 数据类型转换

    1. 转换为字符串

      • toString():

        var  num  =  1;
        alert(num.toString());      //toString和String两者位置不同
        
      • String()强制转换:

        var  num  =  1;
        alert(String(num));
        
      • 与字符串加号拼接:

        var  num  =  1;alert(num+'    ');
        
      • toString()和String()使用方式不一样

        日常更多使用第三种方式,也称之为隐式转换。

    2. 转换为数字型

      • parseInt(String)函数(转为整数数值)

      • parseFloat(string)函数(转换为浮点数数值)

      • Number()强制转换函数 Number(“12”);

      • js隐式转换(· * /)用算数运算隐式转化为数值型 ’12‘·0

        	var  str  = 'aaa';console.log(parseInt(str));
        
        console.log(parseInt('3.14'));  //取整
        
        console.log(parseInt('3.94'));
        
        console.log(parseInt(120px));        //120,去掉px单位
        
        console.log(parseInt(rem120px));     //NaN
        
        //parseFloat()  可以把字符型转换成数字型,得到的是小数点
        
        console.log(parseFloat('3.14'));  //取小数,3.14
        
        console.log(parseFloat('120px'));       //120,去掉px
        
        console.log(parseFloat('rem120px'));      //NaN
        
        //Number()  强制转换
        
        var   er   =  "123';
        
        console.log(Number(er));
        
        //隐式转换(- * /)利用还是运算符,在算数运算时,JS自动转换了数据类型
        
        console.log('123'-'120');   //结果为3,且转换成功
        
        console.log(12+0);   //结果为12,且转换成功
        
        
  • 案例:计算年龄

    var  year   =  prompt('出生年份')var  age  =  2019 - year;  //year取出的是字符串类型,但这里存在隐式转换
    
    alert('今年'+age+'岁')
  • 案例:加法器

    var n1  = prompr("输入数");
    
    var n2  = prompr("输入数");
    
    var ty =  parseFloat(n1)+parseFloat(n2);
    
    alert('结果:'+ty);
    
    
    1. 转换为布尔型

      Boolean函数,代表空,否定的值会被转换成false,如0,NaN,null,underfined;其余数都会被转换成true

      console.log(Boolean(0));   //false
      
  • 翻译器

    计算机不能直接理解代码,需要用翻译器将代码翻译成机器语言。

    翻译器有两种翻译方式:编译;解释。两者之间的区别在于翻译的时间点不同

    • 编译器是在代码执行前进行编译,生成中间代码文件。【把所有菜做好,才能上桌吃饭】

    • 解释器是在运行过程中进行及时解释,并立即执行(当编译器以解释方式运行时,也称解释器)【吃火锅,边吃边喝,同时进行】

  • 标识符规范

    • 标识符:指变量,属性,函数,参数的名字;不能是关键字或保留字。

    • 关键字:JS本身已经使用了的字,不能再用他们作变量名,方法名。如break,case,catch,delete等。

    • 保留字:未来的“关键字”,即现在还不是关键字,但未来有可能是关键字,所以不能使用他们作为变量名,方法名。boolean,Byte,char,class

  • Alt + Shift + 方向键:快速复制

  • 运算符又称为操作符,是用于实现赋值,比较何执行算术运算符等功能的符号。

    1. 算术运算符:算术运算使用的符号,用于执行两个变量或值的运算符

      (加+ ,减-,乘*,除/,取余数(取模)%)

      最好在左右都打上空格 如:console.log(1 + 1);

      取余:

      console.log(5%3);  //  2
      
      console.log(4%2);  //  0  
      
      console.log(3%5);  //  3  
      
  • ​ 浮点数在算数运算中会有问题

​ 浮点数的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数

console.log(0.1+0.2);  //0.3000000000000000004

console.log(0.07*100);  //7.0000000000001

我们不能拿着浮点数来进行比较,是否相等

console.log(0.1 + 0.2  == 0.3);  //  false

  • 如何判断一个数被整除?余数为0就代表这个数被整除,这就是%运算符的主要作用。
  • 算术运算符优先级:先乘除后加减,有小括号先算小括号
  • 由数字,运算符,变量等组成的式子,称之为表达式。

    把我们右边表达式计算完毕,把返回值给左边:var num = 1 + 1;

​ 2. 递增和递减运算符

​ 递增(++)和递减(–)可以放置在变量前面,称之为前置递增,也可以放置在变量后面称之为后置递增。

  • 递增和递减运算符必须和变量配合使用。

    1. 两者可以简化代码的编写
      2. 单独使用时,两者运算结果相同
      3. 与其他代码联用时,执行结果不同
      4. 后置:先返回原值运算,后自加(先人后己)
      5. 前置:先自加,后运算(先己后人)
      6. 开发时,大多使用后置递增/减,且代码独占一行
  • 前置运算符:++num:num = num + 1;先 +1,后返回值

  • 后置运算符:num++:num = num + 1;口诀:先返回原值参与运算,后自+1

    var  age  =  10;
    
    console.log(age++ +10);  // 10+10 = 20,自增的运算符比加号运算符低
    
    console.log(age);  //11
    
    

    前置递增和后置递增如果单独使用,效果是一样的

  • 案例

    var e = 10;
    
    var f  = e++  +  ++e;   //1. e++ = 10,e = 11; 2. ++e = 12,e = 12 
    
    alert(f);
    
    1. 比较运算符

    ​ 比较运算符是两个数据进行比较所使用的运算符,比较运算后,会返回一个布尔值(true/false)作为比较运算的结果。

    • 程序中的等于符号:== (默认转换数据类型),只要求值相等就可以

    • 全等号:=== (全等要求值和数据类型都一致)

    • 全不等号:!==

    • 不等号:!= ,两个符号间不能留空格

      console.log(18 == '18');  //true,**会默认将字符型转换为数字型,再进行比较**,判定是否相等
      
    • =:赋值,把右边给左边;:判断,判断两边值是否相等(此时有隐式转换);全等:=,判断两边的值和数据类型是否相等

    1. 逻辑运算符

      逻辑运算符是进行布尔值运算的运算符,其返回值也是布尔值。后面开发中常用于多个条件的判断。

      • &&:逻辑与,and

        两侧都为true,结果才是true,只要有一侧为false,结果就为false

        console.log(3 > 5 &&  3 > 2);  // false
        
        console.log(3 < 5  &&  3 > 2);  // true
        
      • ||:逻辑或,or

        两侧都为false,结果才是false,只要有一侧为true,结果就为true

        console.log(3 > 5  || 3 > 2);  // true
        
        console.log(3 < 5  ||  3 > 2);  // false
        
      • !:逻辑非,not

        console.log(!true); //  false
        
      • 短路运算(逻辑中断)

        短路运算原理:当有多个表达式时左边的表达式值可以确定结果时,就不再运算右边表达式的值。

        发现有多个表达式不是布尔值,而是一些值或者表达式

        console.log(123&&456);
        
        • 逻辑与&&短路运算口诀:

          1. 表达式1&&表达式2
          2. 如果表达式1的值为真,则返回表达式2
          3. 如果表达式1的值为假,则返回表达式1
        • 案例:

          console.log(123 && 456);  //  456  ,**数字中除0以外都为真**
          
          console.log(0 && 456);  //  0  ,**数字中0为假**
          
          console.log(0&&456&&12*1212412);  //  0  
          
          

          如果有空的或者否定的,为假的(0,‘ ’,null,undefined,NaN)其余是真的

          如果发现前面这个值是假的,后面都不再运算,直接返回前面这个假值

          如果前面这个值为真,则返回后面这个值

        • 逻辑或短路运算口诀:

          1. 表达式1&&表达式2
          2. 如果表达式1的值为真,则返回表达式1
          3. 如果表达式1的值为假,则返回表达式2
    2. 赋值运算符

      赋值运算符:把数据赋值给变量的运算符

      **num = num + 1;  num++;**
      
      **num =  num +  2;  num +=2;**
      
      **var age = 2; age\* = 5;(age = age\*5 ); console.log(age); //10**
      
      
    3. 运算符优先级

      1. 小括号 ()
      2. 一元运算符 ++ ,-- ,!
      3. 算术运算符 先 * ,/ ,% ;后 +,-
      4. 关系运算符 >,>=,<,<=
      5. 相等运算符 ,!=,=,!==
      6. 逻辑运算符 先&&后 | |
      7. 赋值运算符 =
      8. 逗号运算符 ,

      **一元运算符里逻辑非优先级很高

  • 流程控制

    在一个程序执行过程中,各条代码的执行顺序对结果是有直接影响的

    流程控制:控制我们的代码按照什么结构顺序来执行

    三种结构:顺序结构,分支结构,循环结构,这三种结构代表三种代码执行的顺序

    • 顺序流程控制

      顺序结构是程序中最简单,最基本的流程控制,**没有特定语法结构,**程序会按照代码的先后顺序,依次执行,大多数代码都是这样执行的。

    • 分支流程控制

      在从上到下执行代码的过程中,根据不同的条件,执行不同的路径代码(执行代码多选一的过程),从而得到不同的结果。

      1. if的语法结构:

        if(条件表达式){
        
        // 条件成立执行的代码语句
        
        } 
        
        

        语句可以理解为一个行为,循环语句和分支语句就是典型的语句。一个程序由很多个语句组成,一般情况下,会分割为一个一个的语句。

      • 案例:

        var  age  =   prompt('请输入您的年龄');
        if(age >=18){
        alert('我想你去浪漫的土耳其');
        }
        
      1. ** 语法结构 if 结果 else 否则**

        var  age  =   prompt('请输入您的年龄');
        
        if(age >=18){
        
        alert('我想你去浪漫的土耳其');
        
        }else{
        
        alert('洗洗睡吧');}
        
        //if里面的语句1 和  else里面的语句2,  最终只能有一个语句执行   2选1
        
        //else  后面直接跟大括号
        
        //案例:判断闰年
        
        var year  = prompt();
        
        if(year%4==0&&year%100 !=0 || year%400 ==0{
        
        alert("year  is  闰 .");
        
        }else{
        
        alert("year isn't  闰 .");
        
        }
        
        
      2. ** if else if 语句(多分支语句)**

        • 语法规范:

          if(条件表达式1){
          
          // 语句1;
          
          }else  if(条件表达式2){
          
          //语句2;
          
          }else  if(条件表达式3){
          
          //语句3;
          
          }else{
          
          //最后的语句;
          
          }
          
          
        • 执行思路:

          1. 如果是条件表达式1,满足就执行语句1,执行完毕后,退出整个if分支语句
          2. 如果是条件表达式1,不满足,则判断条件表达式2,满足的话,执行语句2,以此类推
          3. 如果上面都不成立,则执行else里面的语句
        • 注意点:

          • 分支语句还是多选1,最后只能有一个语句执行
          • else if (里面的条件理论上是可以任意多个的)
          • else if 两个单词间有个空格
        • 案例:

          //伪代码    按照从大到小判断的思路
          //弹出prompt输入框,让用户输入分数,把这个值保存到变量中
          使用多分支if  else   if  语句来分别判断输出不同的值
          var  score  =  prompt('输入分数');
          if(score >= 90){
          alert("出色");
          }else  if(score >= 80){
          alert("真棒");
          }else  if(score >= 70){
          alert("还行");
          }else  if(score >= 60){
          alert("勉强");
          }else{
          alert("滚蛋");
          }
          
          
      3. 三元表达式

        由三元运算符组成的式子,称之为三元表达式

        一元:++,–;++num

        二元:3+5

        三元:?,:

        • 语法结构:条件表达式 ? 表达式1 :表达式2

          三元表达式就是简化版的if … else 语句

        • 执行思路:

        ​ 如果条件表达式结果为真,则返回表达式1 的值;如果条件表达式结果为假,则返回表达式2的值。

        • 案例:

          var  num  =  10;
          
          var  result  =  num > 5 ? 'true' : ' false';
          
          console.log(result);  // true
          
          
        • 案例2:

          // 用户输入0~59之间的一个数字
          
          //当数字小于10,则在这个数字前面补0拼接,否则不做操作
          
          //用一个变量接受这个返回值
          
          var t =  prompt("输入0~59");
          
          var  r =  t < 10 ? '0' + time :  time;
          
          alert(r);
          
          
        1. 分支流程控制switch语句

          switch语句也是多分支语句,它用于基于不同的条件来执行不同的代码。当要针对变量设置一系列的特定值的选项时,就可以使用switch.

          switch 语句也是多分支语句,也可以实现多选1

          • 语法结构:switch : 转换,开关 ;case:例子或选项的意思

            switch(表达式){
            
            case  value1:
            
            执行语句1break;
            
            case  value2:
            
            执行语句2break;
            
            ....
            
            default:
            
            执行最后的语句;
            
            }
            
            
    • ​ 执行思路 :利用我们的表达式的值 和 case 后面的选项值相匹配,如果匹配上,就执行该case里面的语句,如果都没有匹配上,那么执行default里面的语句

      switch(2){
      
      case 1:
      
      console.log('1');
      
      break;  //break很重要,是退出语句的意思
      
      case 2:
      
      console.log('2');  // 2
      
      break;
      
      case 3:
      
      console.log('3');
      
      break;
      
      default:
      
      console.log('NO');
      
      } 
      
      

    ​ switch语句更适合于处理变量特定值的语句,而变量带有范围,用else if 语句更好做。

    • switch注意事项

      var  num  =  3;
      
      switch(num){
      
      case 1:
      
      console.log('1');  
      
      break;
      
      case 3:
      
      console.log('3');  
      
      break;
      
      }
      
      
      1. 开发里面,表达式经常写成变量,如上
      2. num的值 和 case里面的值相匹配的时候是全等(值和数据类型一致才可以 num===1)
      3. break:如果当前的case里面没有break,则不会退出switch,而是继续执行下一个case
    • 案例:

      var  fruit = prompt("输入水果");
      
      switch(fruit){
      
      case '苹果'alert('apple');
      
      break;
      
      case '橘子'alert('orange');
      
      break;
      
      default:
      
      alert('NO');
      
      }
      
      
    • 分支语句:switch语句和if else if 语句

      两者区别:

      1. 一般情况下,它们两个语句可以相互替换
      2. switch…case语句通常处理case比较确定值得情况,而 if…else 语句更加灵活,常用于范围判断(大于,等于某个范围)
      3. switch语句进行条件判断后直接执行到程序的条件语句,效率更高。而 if…else语句有几种条件,就要判断多少次
      4. 当分支比较少的时候,if…else语句得执行效率比switch语句高
      5. 当分支比较多得时候,switch语句得执行效率比较高,而且结构更清晰
  • 循环语句

在程序中,一组被重复执行的语句被称之为循环体,能否继续执行,取决于循环的终止条件。由循环体及循环的终止条件组成的语句,称之为循环语句。

循环的目的:在实际问题中,有许多具有规律性的重复操作,因此在程序中要完成这类操作就需要可以重复执行某些代码。

  1. for循环(王者-常用)
  2. while 循环(青铜)
  3. do…while循环(青铜)
  • for循环

    for循环只要用于把某些代码循环若干次,通常跟计数有关。

    • 语法结构:

      for(初始化变量;条件表达式;操作表达式){
      // 循环体
      }
      
      

      初始化变量:用var声明的一个普通变量,通常用于作为计数器使用

      条件表达式:用来决定每一次循环是否继续进行,就是终止的条件

      操作表达式:每次循环最后执行的代码,经常用于计数器变量更新(递增或递减)

      // for循环可以执行相同的代码
      
      for(var  i  = 1;i <= 100 ; i++){
      
      console.log('Hello  World');   // 我错了
      
      }
      
      
    • 运行过程:

      1. 先执行计数器变量 var i = 1,但这句话在for里面只执行一次 index
      2. 到 i <= 100 来判断是否满足条件,如果满足,执行循环体,不满足退出循环
      3. 最后执行i++,i++是单独写的代码 ,递增,第一轮结束
      4. 接着执行i <=100,如果满足,执行循环体,不满足退出循环
      5. 第二轮:执行i++,i++是单独写的代码 ,递增
      6. 执行i <=100,如果满足,执行循环体,不满足退出循环
    • 案例:

      // 可以让用户控制输出的次数
      var  num  =  prompt('输入次数');
      for(var i = 0; i <= num ;i++){
      console.log('Hello Word');  
      }
      
      
    • for循环重复不相同的代码

      因为我们有计数器变量 i 的存在,i 每次循环值都会变化

      案例:

      for(var i = 1; i <= 100;i++){
      if(i == 1){
      console.log('他出生了');
      }else  if ( i ==  100){
      console.log('这个人今年百岁大寿‘);
      }else{
      console.log('这个人今年' +  i  + '岁了');
      }
      }
      
      
    • for循环重复某些相同的代码

      for循环因为有了计数器的存在,我们还可以重复的执行某些操作,比如做一些算数运算。

      // 案例:求1~100之间的整数累加和
      var  sum  =  0;
      for(var  i  =  1;i <=100;i++){
      sum + = i  ;  //sum = sum +i ;
      }
      alert(sum);
      //求1~100之间所有数的平均值
      var  ave =  0;
      ave  =  sum / 100 ;
      alert(ave);
      // 求1~100之间所有偶数和奇数的和
      var  even  =  0var  odd  =  0;
      for(var  i  = 1;i <= 100;i++){
      if(i%2 == 0){
      even = even + i;
      }else{
      odd = odd + i;
      }
      }
      alert('偶数和' + even);
      alert('奇数和' + odd);
      //求1~100之间所有能被3整除的数字的和
      var  result = 0;
      for(var i  =  1;i <=100;i++){
      if(i%3 == 0){
      result = result + i;
      }
      }
      alert('被3整除的数字的和是:' + result);
      //学生成绩
      var  num = prompt('请输入班级总人数:');   //弹出框为班级总人数
      var sum  = 0; //求和的变
      var  average = 0; //求平均值的变量
      for(var i = 1;i <=num;i++){
      var score = prompt('请输入第'+ i + '个学生成绩');//依次输入学生的成绩(保存score),用到for循环
      //因为从prompt取过来的数据是 字符串型的需要转换为数字型
      sum = sum +parseFloat(sore);//0+学生成绩
      }
      aveage = sum/num;
      alert('班级总成绩'+ sum);
      alert('班级平均分' + aveage);
      案例:打印星星
      for(var i = 0;i<=100;i++){
      console.log("★");
      }
      //采取追加字符串的方式,可以一行打印到控制台上
      var str = ''";
      	for(var i = 1; i<=5;i++){
      			str = str + '★';
      		}
      		console.log(str);
      
      
    • 双重for循环

循环嵌套是指在一个循环语句中在定义一个循环语句的语法结构,如在for循环语句中,再嵌套一个for循环。

​ 语法结构:

for(外层的初始化变量;外侧的条件表达式,外层的操作表达式){
for(内层的初始化变量;内侧的条件表达式,内层的操作表达式){
//执行语句;
    }
}	

//    1. 将里面的循环看做外层循环的语句

// 2. 外层执行一次,里层执行全部
  • 代码验证

    for(var i = 1;i<=3;i++){
    		console.log('外' + i + '次')for (var j = 1; j<= 3; j++){
    				console.log('里'+ j +'次')}
    }
    //案例:打印5行星星
    var  str1 = '';
    for(var i = 1;i<=5;i++){
    			for (var j = 1; j<= 5; j++){
    				str1 = str1 + '★';
    			}
    			str1 = str1 + '\n';//要换行,不然会出现在一行
    		}
    		console.log(str1);
    //案例:打印倒三角
    		var  str1 = '';
    		for(var i = 1;i<=10;i++){
    			for (var j = i; j<= 10; j++){
    				str1 = str1 + '★';
    			}
    			str1 = str1 + '\n';//要换行,不然会出现在一行
    		}
    		console.log(str1);
    //案例:九九乘法表
    //一共有9行,每行个数不一样,需要双重for循环
    //外层for 循环控制行数i,打印9行
    //内层for循环控制每行公式 j
    //核心算法:每一行公式的个数正好和行数一致,j<=i
    //每行打印完毕都需要重新换一行
    		var  str1 = '';
    		for(var i = 1;i<=9;i++){//外层控制行数 i
    			for (var j = 1; j<= i; j++){  //内层行数内容,列数
    				//1 X 2 = 2
    				str1 = str1 + i + 'x' + j + '=' + i * j; 
    			}
    			str1 = str1 + '\n';// str += '\n';
    			//要换行,不然会出现在一行
    		}
    		console.log(str1);
    
    
  • for循环总结

    1. 可以重复执行某些代码
    2. 可以重复执行些许不同代码,有计数器(for(var i = 1; i <= 100;i++){})
    3. 可以重复执行某些操作,如算数运算符加法操作
    4. 双重for循环,外层循环一次,内层for循环全部执行
    5. for循环是循环条件和数字之节相关的循环
    6. 分析思路比打代码更重要
    7. 一些核心算法想不到,但要学会,分析它执行过程
    8. 举一反三,经常总结,多做案例
  • 断点调试

断点调试可以****帮我们观察程序的运行过程

​ 浏览器-----F12-----Sources-----打断点(程序运行到这里会停止)------刷新(程序运行)----F11(查看程序运行步骤)-----再次点击断点,取消 -----刷新(直接运行)

JS_2019.10.30

  • while循环

    while语句可以在条件表达式为真的前提下,循环执行指定的一段代码,直到表达式不为真时结束循环。

    • while语句语法结构: while 当…的时候

      while(条件表达式){
      
      //循环体代码
      
      }
      
      
    • 执行思路:

      1. 先执行条件表达式,如果结果为true,则执行循环体代码;为false,则退出循环,执行后面代码
      2. 执行循环体代码
      3. 循环体代码执行完毕后,程序会继续执行条件表达式,如条件仍为true,则继续执行循环体,直到循环体条件为false,整个循环过程才会结束。
    • 代码验证

      var num = 1;
      
      		while(num <= 100){
      
      		console.log('OK')//操作表达式
      
      		num++//计数器
      
      		}
      
      

      里面也需要计数器 ,初始化变量

      里面也应有操作表达式 ,完成计数器的更新,防止死循环

    • 案例:计算1~100 之间所有整数的和

      var sum = 0;
      	var  i = 1;
      		while(i <= 100){
      		sum += i;
      		i++}
      		console.log(sum);
      
      
    • 案例:提示框

      var message = prompt('你聪明吗?');
      
      	while (message !=='不聪明') {
      			message = prompt('聪明');
                  }
      alert('还算有自知自明');
      
      
  • do…while循环

    do…while语句是while语句的一个变体。该循环会先执行一次代码块,然后对条件表达式进行判断,如果为真,就会重复执行,否则退出循环。

    • 语法结构:

      do{
      
      //循环体代码   条件为true时重复执行循环体代码
      
      }while(条件表达式)
    • 执行思路:do…while与while不同的是do…while先执行一次循环体,再判断条件。

      先执行循环体,再判断,do…while 循环体至少执行一次循环体代码

    • 代码验证:

      var j = 1;
      
      do{
      console.log('how are you?');
      			j++;
      		}while(j<=100)
    • **案例:**计算1~100 之间所有整数的和

      var sum = 0;
      var  i = 1;
      do{
      sum += i;
      i++}while(i <= 100);
      console.log(sum);
      
      
  • do…while循环总结

    1. JS循环有for,while,do…while
    2. 三个循环很多情况下能够相互替代使用
    3. 如果用来计数,跟数字相关,三者使用基本相同,但我们更喜欢用for
    4. while 和 do…while 可以做更复杂的判断条件,比for循环更灵活一点
    5. while 和 do…while 执行次数不一样 ,do…while至少会执行一次循环体,而while可能一次也不执行
    6. while 和 do…while 执行顺序不一样 ,do…while先执行一次,再判断执行,而while先判断后执行
    7. 实际工作中,我们更常用for循环语句,它写法更简洁直观,是重点学习对象
  • continue和break

    continue关键字用于立即跳出本次循环,继续下一次循环(本次循环体中continue之后的代码就会少执行一次)

    • continue 关键字 退出本次(当前次的循环),继续执行剩余次数循环

      吃五个包子,吃到第三个发现有虫子,扔掉,继续吃第4个,第5个。

      for(var i = 1;i <= 5; i++){
      		if (i == 3) {                             // 第三个包子有虫子扔掉
      continue;                      //  只要遇见  continue就退出本次循环  直接跳到 i++
      	}
          console.log('我正在吃第'+ i + '包子')}
      
      
      • 案例:求1~100之间,除了能被7整除之外的整数和

        var sum = 0;
        for (var i = 0;i <=100; i++){
        if(i%7 == 0){
        	 	continue;
        	 }
        	 sum += i;
        	 }
         console.log(sum);
        
        
    • break关键字用于立即跳出整个循环(循环结果)。

    ​ 吃五个包子,吃到第三个发现有虫子,扔掉,其余的不吃了。

    for(var i = 1;i <= 5; i++){
    		if (i == 3) {                             // 第三个包子有虫子扔掉
    	break;                      //  只要遇见  break就退出本次循环  for循环也不再执行
    		}
    		console.log('我正在吃第'+ i + '包子')}
    
    
  • 标识符命名规范

    1. 变量,函数命名必须要有意义
    2. 变量名称一般用名词
    3. 函数名称一般用动词
  • 操作符规范

    1. 操作符左右两侧个保留一个空格 for(var i = 1 ; i <= 5 ; i++)
  • 单行注释规范

    单行注释前面注意有个空格

    循环语句左右两侧各有一个空格 for (var i = 1 ; i <= 5 ; i++) {}

  • 数组

    数组是指一组数据的集合,其中每个数据被称为元素,在数组中可储存任意类型的元素,数组是一种将一组数据存储在单个变量名下的优雅方式。(作用)

    之前学习的变量只能储存一个值,而数组(Array)可以把一组相关的数据一起存放,并方便访问(获取)方式。

    // 普通变量一次只能储存一个值
    var  num  = 10;
    //  数组一次可以储存多个值
    var   arr   =   [1,2,3,4] ;
    
    
    • 创建数组

    ​ JS中创建数组方式:

    ​ 1. 利用new创建数组

     var  arr(数组名) =  new Array();  //   创建一个新的空数组  ,注意A要大写
    
     arr[0]  = "ps";
    
    

    ​ 2. 利用数组字面量创建数组(常用)

     var  arr = ['a','b','c','d'];       //   使用数组字面量方式创建带初始值的数组
    //  数字内数据一定用逗号分隔,数组里面数据称之为数组元素
    //  数组的字面量是方括号[ ]
    //   声明数组并赋值称之为数组的初始化
    
    • 获取数组中的元素

      数组索引,索引(下标):用来访问数组元素的序号(数组下标从0开始)。

       var  arr = ['a','b','c','d'];  
      //索引号:     0   1   2   3
      

      数组可以通过索引来访问,设置,修改对应的数组元素,我们可以通过"数组名[索引]"的形式来获取数组中的元素。

      取出数组的某一项:数组名[索引]

      从数组中取出每一个元素时,代码是重复的,不一样的是索引值在递增

      console.log (arr[1]);  //  b
      console.log (arr[2]);  //  c
      console.log (arr[4]);  //  因为没有这个数组元素  ,所以输出的是  undefined
      
    • 遍历数组

      遍历:把数组中的每个元素从头到尾都访问一次(类似早点名)。

      输出数组所有元素通过循环

      var  arr = ['a','b','c','d'];  
      for (var i = 0; i < 4 ; i++) {   //  因为我们的数组**索引号从0开始**,所以 i 必须从 0 开始  i  <  4
      console.log(arr[i]);        //   输出的时候  arr[i]    i 是索引号当计数器来用
      }
      
    • 数组的长度

      使用"数组名.length"可以访问数组元素的数量(数组长度)。

      for (var i = 0; i < arr.length ; i++) {    //  arr.length  动态监测数组元素的个数,添加元素后也可准确遍历
      
      console.log(arr[i] );      
      
      }
      
      console.log(arr.length);   //   数组长度是元素个数  ,不要跟索引号混淆
      
      数组索引和数组长度关系:数组索引号从0开始, 数组长度是元素个数
      
    • 案例:数组求和及平均值

      //执行思路:
      // 声明一个求和变量 sum
      // 遍历这个数组,把里面每个数组元素加到sum里面
      // 用求和变量sum除以数组的长度就可以得到数组的平均值
      var  arr = [2,6,1,7,4];
      var sum = 0;
      var  average = 0;
      for(var i = 0;i < arr.length;i++){
      sum += arr[i];  //+ 的是数组元素arr[i],不是计数器i
      }
      average = sum / arr.length;
      console.log(sum,average);   //先要输出多个变量,用逗号分隔即可
      
      
    • 案例:取数组最大值

      //执行思路:
      // 声明一个保存最大元素的变量  max
      // 默认最大值可以去数组中第一个元素
      // 遍历这个数组,把里面每个元素和 max 相比较
      // 如果这个数组元素大于max 就把这个元素存到max里面,否则进行下一轮比较
      // 输出max
      var  arr = [2,6,1,7,4];
      var max = arr[0];
      for(var i = 1;i < arr.length;i++){
      if(arr[i]>max){max = arr[i];}  
      }
      console.log('最大值是' + max);
      
      
    • 案例:把数组转换为字符串

      //执行思路:
      // 需要一个新变量用于存放转换完的字符串 str
      // 遍历原来的数组,分别把里面的数据取出来,加到字符串里面
      // 同时在后面加一个分隔符
      var  arr2 = ["red","green","blue","pink"];
      var  str = '';
      var  sep = ']';
      for(var i = 0;i<arr.length;i++){
      str += arr[i] + sep;
      }
      console.log(str);
      
      
    • *** 数组中新增元素**

      可以通过修改length长度以及索引号增加数组元素

      但只能为空

      var  arr2 = ["red","green","blue","pink"];
      arr.length = 5;
      console.log(arr2);
      console.log(arr[4]);  //undefine
      console.log(arr[5])   //undefine
      // 其中索引号是4,5的空间没有给值,就是声明变量未赋值,默认值为undefined
      

      可以通过修改数组索引的方式追加数组元素(最常用)

      // 不能直接给数组名赋值,否则会覆盖掉以前的元素
      
      arr2[4] = "oppo";
      
      arr2[5] = "vivo";
      
      console.log(arr2);
      
      arr2[0] = "huawei";  //这里会替换原来的数组元素
      
      console.log(arr[0]);  
      
      console.log(arr[4]);  //undefine
      
      console.log(arr[5])
      
      arr2 = "you";
      
      console.log(arr2);  //不要直接给数组名赋值,否则里面的数组元素都没有了
      
      
      • 案例:在数组中依次加入1~10整数

        // 新建一个数组,里面存放10个整数
        // 核心原理:使用循环来追加数组
        // 声明一个空数组
        // 循环中的计数器 i 可以做为数组元素存入
        // 由于数组的索引号是从0开始的,因此计数器从0开始更为合适,存入的数组元素要+1
        var arr3 = [];
        for(var i = 0; i< 10;i++){
        // arr = i;  不要直接给数组名赋值,否则以前的元素都没了
        arr[i] = i + 1;
        }
        console.log(arr3);
        
        
      • 案例:筛选数组,将数组中大于等于10的元素选出来,放入新数组

        // 声明一个新的数组用于存放新数据newArr
        // 遍历原来的旧数组,找出大于等于10的元素
        // 依次追加给新数组newArr
        var  arr4 = [2,3,4,5,6,45,23,12,78,11,10];
        var  newArr = [];
        var  j  =  0;
        for(var i = 0;i < arr4.length;i++){
        if(arr4[i] > 10){
        //新数组应该从0开始,依次递增
        newArr[j] = arr4[i];
        j++;
        }
        }
        console.log(newArr);
        //  方法2
        var  arr4 = [2,3,4,5,6,45,23,12,78,11,10];
        var  newArr = [];
        for(var i = 0;i < arr4.length;i++){
        if(arr4[i] > 10){
        //新数组应该从0开始,依次递增
        newArr[newArr.length] = arr4[i];
        }
        }
        console.log(newArr);
        
        
      • 案例:删除指定数组元素

        将数组中的0去掉后,形成一个不包含0的新数组

        // 需要一个新数组用于存放筛选之后的数据
        // 遍历原来的数组,把不是0的数据添加到新数组里面(此时要注意采用数组名 + 索引的格式接收数据)
        // 数组里面的个数,用length不断累加
        var  arr5 = [2,3,4,5,6,0,45,23,12,78,11,10,0];
        var newArr1 = [];
        for(var i = 0;i < arr5.length;i++){
        if (arr5[i]!=0) {
        newArr1[newArr1.length] = arr5[i];
        }
        }
        console.log(newArr1);
        
        
      • 案例:翻转数组

        // 声明一个新数组 newArr2
        
        // 把旧数组索引号第4个取过来(arr6.length - 1),给新数组索引号第0个元素 (newArr2.length)
        
        // 采取递减的方法 i--
        
        var  arr6 = ["red","green","blue","pink"];
        
        var  newArr2 = [];
        
        for(var i = arr6.length - 1;i >= 0 ;i--){
        
        newArr2[newArr2.length] = arr6[i];
        
        }
        
        console.log(newArr2);
        
        
      • 案例:数组排序(冒泡排序)

        //  交换两个变量 
        
        var  num1 = 'A';
        
        var  num2  = 'B';
        
        var  temo;
        
        temp = num1;  //num1的值赋给temp
        
        num1 = num2;
        
        num2 = temp;
        
        console.log(num1,num2);
        
        
        
        

        **冒泡排序是一种简单的排序算法,把一系列的数据按照一定的顺序进行排列显示,重复地走访要排序的数列,**一次比较两个元素,如果他们的顺序错误即将他们交换过来。

        走访数列的工作是重复地进行直到没有再需要交换,也就是数列已经排序完成。

        这个名称是因为越小的元素会经由交换慢慢"浮"到数列顶端。

      • 案例分析: 5 4 3 2 1

        1. 一共需要的趟数,用外层for循环
          1. ​ 4 3 2 1 5
          2. ​ 3 2 1 4 5
          3. ​ 2 1 3 4 5
          4. ​ 1 2 3 4 5

      ​ 长度 是 数组长度 减去 次数

    ​ 2. 每一次交换次数,用里层for循环

    ​ 第1趟 交换4次

    ​ 第2趟 交换3次

    ​ 第3趟 交换2次

    ​ 第4趟 交换1次

    ​ 长度 是 数组长度 减去 次数

    ​ 但因为次数从0开始 所以最终 arr.length - i - 1

    ​ 3. 每次交换2个变量

    var arr7 = [5,4,3,2,1];
    for(var i = 0;i < arr7.length -1 ;i++){
    for(var j = 0; j <= arr7.length - i - 1;j++ ){   //里面的循环体。每一趟的交换次数
     if(arr7[j] > arr7[j + 1]{   //内部交换2个变量的值  前一个和后一个数组元素相比较
     var temp = arr7[j];
     arr7[j] = arr7[j + 1];
     arr7[j + 1] = temp;
                     }
            }
    }         //   [1,2,3,4,5]
    
    var arr7 = [5,4,3,2,1];
    for(var i = 0;i < arr7.length -1 ;i++){
    for(var j = 0; j <= arr7.length - i - 1;j++ ){   //里面的循环体。每一趟的交换次数
     if(arr7[j] < arr7[j + 1]{   //内部交换2个变量的值  前一个和后一个数组元素相比较
     var temp = arr7[j];
     arr7[j] = arr7[j + 1];
     arr7[j + 1] = temp;
                     }
            }
    }               //   [5,4,3,2,1]
    
    
  • 函数

    • 函数的概念

      for循环语句也能实现一些简单的重复操作,但是比较有局限性,此时可以使用JS中的函数。

      函数:封装了一段可被重复调用执行的代码块,通过此代码块可以实现大量代码俄重复使用。

      • 案例:求10~50的累加和

        var  sum = 0;
        
        for(var i =10);i <= 50);i++{
        
        sum  += i;
        
        }
        
        console.log(sum);
        
        

        方法二:

        //函数就是封装了一段可以被重复执行的代码块
        
        //目的:让大量代码重复使用
        
        function getSum(num1,num2){
        
        var sum = 0;
        
        for(var i = num1;i<num2;i++){
        
        sum += i;
        
        }
        
        console.log(sum);
        
        }
        
        getSum(1,100);
        
        get(10,50);
        
        
    • 函数使用

      函数使用分为两步

      1. 声明函数

        function     函数名(){
        
        //   函数体
        
        }
        
        

        代码验证:

        function say(){
        
        	console.log('hello')}
        
        

        A. function 声明函数的关键字 全部必须小写

        B. 函数是做某件事情,一般是为了实现某个功能才定义的,所以通常我们将函数名命名为动词,函数名一般是动词 say

        C. 声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码

      2. 调用函数

        函数名();//  通过调用函数名来执行函数体代码
        
        getSum(1050)

        A. 调用的时候千万不要忘记加小括号

        B. 口诀:函数不调用,自己不执行

    • 案例:利用函数计算1~100之间的累加和

      function getSum(num1,num2){
      
      var  sum = 0;
      
      for( var i =  num1 ;  i <= num2 ; i++ ){
      
       sum = sum + i;
      
      }
      
      console.log(sum);
      
      }
      
      getSum(1,100);
      
      
  • 函数封装

    函数封装是把一个或多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口。

    白话文:封装类似于将电脑配件整合组装到机箱中(类似于快递打包)

  • 函数参数

    函数可以重复相同代码 say(); //helllo

    可以利用函数的参数实现函数重复不同的代码

    1. 形参

    形式上的参数,函数定义的时候,传递的参数 ,当前并不知道是什么

    function(形参1,形参2…){ // 在声明函数的小括号里面是 形参(形式上的参数)}

    1. 实参

    实际上的参数,函数调用的时候传递的参数,实参是传递给形参的

    function(实参1,实参2…){ // 在函数调用的小括号里面是 实参(实际的参数)}

    1. 形参和实参的执行过程
    function cook(aru){    //**形参是接收实参的**  aru = '番茄炒蛋'  形参类似于一个变量
    console.log(aru);
    }
    cook('番茄炒蛋');  
    
    
    1. 函数的参数可以有,也可以没有。个数不限
    • 案例

      1. 利用函数求任意两个数的和

        function getSum(num1,num2){
        console.log(num1+num2);
        }
        getSum(1,3);
        
        
      2. 利用函数求任意两个数之间的和

        function getSum(start,end){
        
        var sum = 0;
        
        for(var i = start;i<=end;i++){
        
        sum += i;
        
        }
        
        console.log(sum);
        
        }
        
        getSum(1,100);
        
        
        • 注意:
          • 多个参数之间用逗号隔开
          • 形参可以看作是不用声明的变量
        //函数形参和实参不匹配
        
        function getSum(num1,num2){
        
        console.log(num1+num2);
        
        }
        
        // 实参与形参的个数一致,则正常输出结果
        
        getSum(1,3);
        
        // 如果实参的个数多于形参的个数  会取到形参的个数
        
        getSum(1,2,3);  //  则3不再参与运算
        
        // 如果实参的个数少于形参的个数  多出的形参会定义为undefined   结果为NaN
        
        getSum(1);         //  形参可以看作是不用声明的变量   num2是一个变量但没有接收值    var num2 = ' ' = undefined     即  1+undefined = NaN
        
        
  • 总结

    1. 函数可以带参数,也可以不带参数
    2. 声明函数的时候,函数名括号里面的是形参 ,形参的默认值是undefined
    3. 调用函数的时候,函数名括号里面的是实参
    4. 多个参数之间用逗号分隔
    5. 形参的个数可以和实参个数不匹配,但是结果不可预计,我们应当尽量匹配
  • 函数的返回值

    函数内部不应该有输出语句(函数值返回到外部–厨师应当把菜端出)

    将函数值返回给调用者

    • return语句

      function 函数名(){
      return  需要返回的结果;
      }
      函数名();
      
      
      1. 函数只是实现某种功能,最终的结果需要返回给调用者函数名() ,通过return来实现
      2. 函数遇到return 就把后面的结果返回给函数的调用者 函数名()= return后面的结果
      • 代码验证:

        function getResult(){
        
        return 666;
        
        }
        
        getResult();
        
        console.log(getResult());   //666
        
        function cook(aru){    //形参是接收实参的  aru = '番茄炒蛋'  形参类似于一个变量
        
        return cook;
        
        }
        
          	console.log(cook('番茄炒蛋'));
        
        
      • 案例:

        //   利用函数 求两个数的最大值
        
        function getMax(num1,num2){/*if(num1 > num2){
        
        return num1;
        
        ​	}else{
        
        ​		return num2;
        
        ​	}*/return  num1 > num2 ? num1:num2;
        
        }
        
        console.log(getMax(1,3));
        
        //利用函数  求数组[5,2,99,101,67,77]中的最大数值
        
        functon getArrMax(arr){var max = arr[0];for(var i = 1; i <= arr.length;i++){if(arr[i] > max){
        
        ​			max = arr[i];}}return max;
        
        }
        
        // getArrMax([5,2,99,101,67,77]);  实参是一个数组送过去
        
        // 实际开发中,我们经常用一个变量来接受函数的返回结果,使用更简单
        
        var re = getArrMax([5,2,99,101,67,77]);
        
        console.log(re);
        
        **return  终止函数**
        
         //   return语句后代码不再被执行
        
        function cook(aru){   
        
        return cook;  
        
        alert('不再被执行!');
        
        }
        
          	console.log(cook('番茄炒蛋'));
        
        //  return只能返回一个值,如果逗号隔开多个值,以最后一个为准
        
        function fn(num1,num2){
        
        return num1,num2;   //返回的结果是最后一个值
        
        }
        
        console.log(fn(1,2));  // 2
        
        // 当需要输出多个数值,可以使用数组
        
        function getResult(num1,num2){return [num1 + num2 ,num1 - num2 ,num1 * num2 ,num1 /num2 ];
        
        }
        
        var re = getResult(1,2);
        
        console.log(re);
        
        // 函数如果有return 则返回的是return后面的值;如果函数没有return 则返回undefined
        
        function fun1(){return 666;
        
        }
        
        console.log(fun1());  //  666
        
        function fun2(){
        
        }
        
        console.log(fun2());  //  undefined
        
        
  • break,continue,return的区别

    • break:结束当前循环体
    • continue:跳出本次循环,继续执行下次循环(for,while 扔掉第三个包子)
    • return:不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前的函数体内的代码 (return 666;)
  • 通过榨汁机看透函数

    榨汁机 函数

    输入原料 function fn (参数1,参数2){ // 输入参数

    内部处理 函数体; // 内部处理

    输出果汁 return 返回值; // 返回结果

  • arguments的使用

    当不确定有多少个参数传递时,可以用arguments来获取。在JS中,arguments实际上是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。

    function  fn(){
    
    ​	console.log(arguments);     //   里面存储了传递过来的所有实参
    
    ​	console.log(arguments.length);  
    
    ​	console.log(arguments[2]);  // 1,2,3// 我们可以按照数组的方式进行遍历for(var i = 0 ; i <argument.length;i++){
    
    console.log(argument[i]);  //1,2,3,4,5}
    
    }
    
    fn(1,2,3);
    
    fn(1,2,3,4,5);
    
    

    arguments展示形式是一个伪数组,因此可以进行遍历

    • 伪数组具有如下特点:

      1. 具有length 属性
      2. 按索引方式储存数据
      3. 不具有数组的push,pop等方法
    • 案例:

      //利用函数  求任意个数的最大值
      
      functon getMax(){var max = arguments[0];for(var i = 1; i < argument.length;i++){if(argument[i] > max){
      
      ​			max = argument[i];}}return max;
      
      }
      
      console.log(getMax(1,2,3));
      
      console.log(getMax(1,2,3,4));
      
      //翻转任意数组  reverse 翻转
      
      function reverse(arr){var newArr = [];for(var i = arr.length - 1;i >= 0;i--){
      
      ​		newArr[newArr.length] = arr[i];}return newArr;
      
      }
      
      var arr1 = reverse([5,2,99,101,67,77]);
      
      console.log(arr1);  //[77,67,101,99,2,5]
      
      var arr2 = reverse(['red','pink','blue']);
      
      console.log(arr2);
      
      //利用函数冒泡排序 sort排序
      
      function sort(arr){
      
      for(var i = 0; i <arr.length - 1;i++){for(var j = 0; j < arr.length - i - 1;j++){
      
      if(arr[j] > arr[j + 1]){var temp = arr[j];
      
      ​	arr[j] = arr[j + 1];
      
      ​	arr[j + 1] = temp;
      
      }}
      
      }
      
      return arr;
      
      }
      
      var arr1 = sort([5,2,99,101,67,77]);
      
      // 利用函数判断闰年
      
      function isYear(year){
      
      var flag = false;
      
      if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
      
      flag = true;
      
      }
      
      return flag;
      
      }
      
      console.log(isYear(2000));
      
      
  • 函数可以调用另外一个函数

    因为每个函数都是独立的代码块,用于完成特殊任务,因此经常会用到函数相互调用的情况。

    • 案例:

      //函数可以互相调用
      
      function  fn1(){
      
      ​	console.log(11);fn2();  // 在fn1函数里面调用了 fn2函数
      
      }
      
      fn1();
      
      function fn2(){
      
      ​	console.log(22);
      
      }
      
      //打印结果  11  22
      
      //  用户输入年份,输出当前年份2月份的天数
      
      function backDay(){var year = prompt('请您输入年份:');if(isYear(year)){  //调用函数加小括号()alert('闰年2月份29天');}else {alert('平年2月份28天');}
      
      }
      
      backDay();
      
      // 利用函数判断闰年
      
      function isYear(year){
      
      var flag = false;
      
      if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
      
      flag = true;
      
      }
      
      return flag;
      
      }
      
      console.log(isYear(2000));
      
      
  • 函数的两种声明方式

    1. 利用函数关键字自定义函数(命名函数)

      这种是函数声明 ,可以先使用后定义 ,它会对函数的声明进行一个提升

      function fn(){
      }
       fn();
      
      
    2. 函数表达式(匿名函数)

      这种叫做函数表达式 ,必须先定义后使用

      //var 变量名 = function() {};
      
      var fun = functon(aru){
      
      ​	console.log('我是函数表达式');
      
      console.log(aru);
      
      }
      fun('换笔记');// 打印结果  我是函数表达式  换笔记
      
      

      A. fun是变量名,不是函数名

      B. 函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值,而函数表达式里面存的是函数

      C. 函数表达式也可以进行传递参数

       fun();
         var fun=function(){
         console.log("本事啦,我的弟");//Uncaught TypeError: fun is not a function
         }
      
      

      直接使用fun则会报一个”Uncaught ReferenceError: fun is not defined”的错误(和不声明fun报错是不一样的),其实fun也是一个变量,只不过他是function(){console.log(“本事啦,我的弟”);}的一个引用,fun的声明被提升了,但是初始化没有被提升。

JS作用域

  • 作用域概述

    一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

    作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突

    // js作用域:是代码名字(变量)在某个范围内起作用和效果,目的是提高程序的可靠性,更重要的是减少命名冲突
    // js作用域(es6)之前: 全局作用域   局部作用域
    // 全局作用域:整个script标签 或者是一个单独的js文件
    var  num = 10;
    console.log(num);
    //局部作用域(函数作用域):在函数内部就是局部作用域,这个代码的名字只在函数内部起效果和作用
    function fn(){
    	//局部作用域
    	var num = 20;
    	console.log(num);
    }
    fn();
    //打印结果 10  20 虽然命名相同,但在不同作用域下,所以两者不影响
    
    
  • 变量作用域分类

    根据作用域的不同,变量可以分为

    1. 全局变量

      // 全局变量:在全局作用域下的变量,在全局下都可以使用(在函数外定义的变量)
      // 如果在函数内部 ,没有声明直接赋值的变量也属于全局变量
      var num  = 10;   // num就是一个全局变量
      console.log(num);
      function fn(){
      	console.log(num);
      }
      fn();
      
      
    2. 局部变量

      // 局部变量:在局部作用域下的变量 , 后者在函数内部的变量就是局部变量(函数内部定义的变量)
      // 在函数内部var声明的变量是局部变量  
      // 函数的形参实际上就是是局部变量  aru
      function fun(aru){
      	var num1 = 10;  //num1就是局部变量  只能在函数内部使用
      	num2 = 20;
      }
      fun();
      console.log(num1);  //报错,局部变量无法在外部被调用
      console.log(num2);  //20
      
      
  • 从执行效率来看全局变量和局部变量

    1. 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
    2. 局部变量 当程序执行完毕就会销毁,比较节约内存资源
  • JS没有块级作用域

    // 现阶段我们js没有块级作用域
    // JS也是在es6的时候新增的块级作用域
    // 块级作用域就是用{}进行包含的    if{}   for{}
    // 在java中  
    // if(xx){int num = 10;}  外面是不能调用的
    if(3>5){
    	var num = 10;
    }
    console.log(num);  //10
    //由于现阶段js没有块状作用域 ,所以变量放在内外都可以使用
    
    

    JS也是在es6的时候新增的块级作用域

  • 块级变量和局部变量的区别

    局部变量是函数内部的变量,函数运行完毕后局部变量会被销毁;块级变量是在代码块中的变量,不是函数内,也不是全局的。

  • 作用域链

    1. 只要是代码,就至少有一个作用域
    2. 写在函数内部的局部作用域
    3. 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
    4. 根据在内部函数可以访问外部函数变量的这种机制,用链式查找(一层一层向上查找)决定哪些数据能被内部函数访问,就称为作用域链
    //作用域链 :  内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,这种结构我们称之为作用域链   就近原则
    var  num = 10;    //写了一行代码就有作用域,是全局作用域
    function fun(){      //外部函数
    	var num = 20;
    	function fn(){   //内部函数
           console.log(num);   // 20 ,就近原则
    	}
    	fn();
    }
    fun();
    
    
    //案例1:结果是几?
    function f1(){
    	var num = 123;
    	function f2(){
    		var num = 0;
    		console.log(num); //0,站在目标出发,一层一层地往外查找
    	}
    	f2();
    }
    var num = 456;
    f1();
    
    

JS预解析

  1. js引擎运行分为两步:预解析 代码执行

    • 预解析:js引擎会把js里面所有的 var ,还有 function 提升到当前作用域的最前面
    • 代码执行:按照书写的顺序从上往下执行
  2. 预解析分为变量预解析(变量提升)和 函数预解析(函数提升)

    • 变量提升就是把所有变量声明提升到当前的作用域最前面
      • 只提升变量声明,不提升赋值操作
    • 函数提升就是把所有的函数声明提升到当前作用域的最前面
      • 不调用函数
    //未赋值
    console.log(num);    //undefined
    //
    console.log(num);    //undefined
    var num = 10;
    //相当于执行了以下代码
    /*var num;   //变量提升,未赋值
    console.log(num);
    num = 10;*/
    
    //
    fn();
    function fn(){  // 变量声明
    	console.log(11);   //11
    }
    //预解析会将所有变量声明提升到当前作用域的最前面
    //
    fun();     // 报错
    var fun = function(){  //该表达式是函数声明的形式
    	console.log(22);    
    }
    //相当于执行了以下代码
    var fun;   //声明变量,未赋值
    fun();
    fun = functon(){
    	console.log(22);
    }   //  fun();上面的代码没有这个函数的方法,所以报错
    //函数表达式调用必须写在函数表达式下
    
    
  3. 预解析案例:

    var num = 10;
    f1();
    function  f1(){
    	console.log(num);
    	var num = 20;
    }
    //相当于以下代码(变量提升后的结果)
    var num;
    function  f1(){  //f1也是一个作用域,需要变量提升
    var num;  //未赋值,就近原则
    	console.log(num);   //undefined
    num = 20;
    }
    num = 10;
    f1();
    
    
    var num = 10;
    function  f1(){
    	console.log(num);
    	var num = 20;
    	console.log(num);
    }
    f1();
    //相当于以下代码(变量提升后的结果)
    var num;
    function  f1(){  //f1也是一个作用域,需要变量提升
    var num;  //未赋值,就近原则
    	console.log(num);   //undefined
    num = 20;
    console.log(num);    //20
    }
    num = 10;
    f1();
    
    
    var a = 18;
    f1();
    function  f1(){
    	var b = 9;
    	console.log(a);
    	console.log(b);
    	var a = 123;
    }
    //相当于以下代码
    var a;
    function  f1(){
    	var b;   // 未赋值
    	var a;
    	b = 9;
    	console.log(a);   //undefined
    	console.log(b);  //9
    	a = '123';
    }
    a=18;
    f1();
    
    
    f1();
    console.log(a);
    console.log(b);
    console.log(c);
    function f1(){
    	var a = b = c = 9;
    	//相当于var a = 9;b = 9;c= 9;
    	//b和c直接赋值,没有var声明,当全局变量看
    	//集体声明:var a = 9,b = 9,c = 9;
    	console.log(a);
    	console.log(b);
    	console.log(c);
    }
    //以下代码
    function f1(){
    	var a ;  //a加了var,属于局部变量
    	a = b = c = 9;
    	//相当于var a = 9;b = 9;c= 9;
    	//b和c直接赋值,没有var声明,当全局变量看(全局变量任何地方都能使用)
    	//集体声明:var a = 9,b = 9,c = 9;
    	console.log(a);   //9
    	console.log(b);   //9
    	console.log(c);   //9
    }
    f1();
    console.log(a);   //报错
    console.log(b);   //9
    console.log(c);   //9
    
    

JS对象

  1. 什么是对象

    现实生活中,对象是一个具体的事物,看得见摸得着的实物,如一本书,一辆车

    在JS中,对象是一组无序相关属性和方法的集合,所有事物都是对象,如字符串,数值,数组,函数等。

    • 对象由属性和方法组成

      • 属性:事物的特征,在对象中用属性来表示(常用名称)

      • 方法:事物的行为,在对象中用方法来表示

        (常用动词)

      • 举例:手机的大小,颜色,重量(属性);打电话,发短信(方法)

      1. 为什么需要对象?

    保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组。

    举例:保存一个人的个人信息在数组中方式为

    var  arr = ['张三''男'12,154];
    
    

    JS中的对象表达结构更清晰,更强大

    person.name = '张三';
    person.sex = '男';
    person.age = 12;
    person.height = 154;
    
    
    1. 创建对象三种方式
    • 利用字面量创建对象

      • 对象字面量:{ }里面包含了表达这个具体事物(对象)的属性和方法

      • 键:相当于属性名

      • 值:相当于属性值,可以是任意类型的值(数字类型,字符串类型,布尔类型,函数类型等)

        //1. var obj = {};//创建一个空的对象
        var obj = {
        	uname:'张三',
        	age :18,
        	sex:'男',
        	sayHi:functon(){
        		console.log('hello');
        	}
        }
        //里面的属性或方法我们采用键值对的形式   键 属性名 :值  属性名
        //多个属性或者方法中间用逗号隔开
        //方法冒号后面跟的是一个匿名函数
        //2.使用对象
        //调用对象的属性,我们采用 对象名.属性名,这个小点.我们理解为 "的"
        console.log(obj.uname);  //张三
        //调用属性还有一种方法:对象名['属性名'],注意方括号里面必须加引号
        console.log(obj['age']);  //18
        //调用对象的方法sayHi()     对象里面的方法调用:对象名.方法名()
        //千万别忘记添加小括号
        obj.sayHi();  //hello
        
        
      • 变量,属性,函数,方法的区别

        • 变量:单独声明赋值,单独存在
        • 属性:对象里面的变量称为属性,不需要声明,用来描述该对象的特征
        • 函数:单独存在,通过"函数名()"的方式就可以调用
        • 方法:对象里面的函数称为方法,方法不需要声明,使用"对象.方法名( )"的方式就可以调用,方法用来描述该对象的行为和功能
        //1.变量和属性相同时,他们都是用来存储数据的
        //变量 单独声明并赋值,使用的时候必须是 对象.属性
        //变量和函数可以直接写,而属性和方法一定要加一个对象 
        var num  = 10var obj = {   //对象
        	age:18;     //属性
        	fn:function(){  //方法
        
        	}
        }
        function fn(){   //函数
        
        }
        console.log(obj.age);  //18
        console.log(age);  //报错
        //2.函数和方法的相同点 都是实现某种功能 做某件事
        //函数是单独声明并调用的,函数名()单独存在的方法在对象里面,调用的时候 对象.方法()
        
        
    • 利用new Object 创建对象

      // 利用 new Object 创建对象
      var obj = new Object();
      obj.uname = '张三';
      obj.age = 18;
      obj.sex = '男';
      obj.sayHi = function(){
      	console.log('hello');
      }
      //利用等号 = 赋值的方法,添加对象的属性和方法
      //每个属性和方法之间用分号结束
      console.log(obj.uname);  //张三
      console.log(onj['sex']);  //男
      obj.sayHi();  //hello
      
      
    • 利用构造函数创建对象

      为什么需要使用构造函数?

      因为前面两种创建对象的方式一次只能创建一个对象

      //因为我们一次创建一个函数,里面很多的属性和方法是大量相同的,只能复制
      //因此我们可以利用函数的方法,重复这些相同的代码,我们称之为构造函数
      //又因为这个函数不同,里面封装的不是普通代码,而是对象
      //构造函数,就是把对象里面一些相同的属性和方法抽象出来封装到函数里面
      
      //案例运用:创建四大天王的对象   相同属性:名字  年龄  性别   相同方法:唱歌
          var ldh = {
      	uname:"刘德华",
      	age:55,
      	sing:function(){
      		console.log('冰雨');
      	}
      }
      
      	var zxy = {
      	uname:"张学友",
      	age:58,
      	sing:function(){
      		console.log('李香兰');
      	}
      
      }
      
      
      • 构造函数:一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用。

        我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

      • 语法格式:

        function   构造函数名( ){
        
        this.属性  =  值;
        this.方法 =  function( )
        
        } 
        new.构造函数值();
        
        

      案例优化后:

      //1.构造函数名字首字母要大写
      function Star(uname,age,sex){
      	//5.属性和方法前面必须添加 this
      	this.name = uname;
      	this.age = age;
      	this.sex = sex;
      	this.sing = function (song) {
      		console.log(song);
      	}
      }
      //2.构造函数不需要return,就可以返回结果
      var ldh = new Star('刘德华',18,'男');  //调用函数返回的是一个对象
      //3.调用构造函数,必须使用new
      //4.如下,只要new Star() 调用函数就创建一个对象 ldh{}  
      var zxy = new Star('张学友',19,'男');
      //console.log(typeod ldh);  判断lah变量的类型
      console.log(ldh.name);  //刘德华
      console.log(ldh.age);   //18
      console.log(ldh['sex']);  //男
      ldh.sing('冰雨');  //向上传回一个实参  打印:冰雨
      
      
      • 构造函数和对象的区别

        • 构造函数,如Star( ),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class)

          —— 汽车设计图纸

        • 创建对象,如new Star( ),特指某一个,通过new关键字创建对象的过程也称为对象的实例化

          —— 宝马车

        // 构造函数和对象
        //1.构造函数 泛指的某一大类,类似于java语言里的类(class);如明星,也是指一大批人
        function Star(uname,age,sex){
        	//属性和方法前面必须添加 this
        	this.name = uname;
        	this.age = age;
        	this.sex = sex;
        	this.sing = function (song) {
        		console.log(song);
        	}
        }
        //2.对象 是特指一个具体的事物,如刘德华
        var ldh = new Star('刘德华',18,'男'); //调用函数返回的是一个对象 
        
        console.log(ldh);  // ldh == {name:"刘德华",age:18,sex:"男",sing:f}
        //3.利用构造函数创建对象的过程也称为对象的实例化
        
        
      • new关键字执行过程

        //new关键字执行过程
        //1. new 构造函数可以在内存中创建了一个空的对象
        //2. this 就会指向刚才创建的空对象
        //3. 执行构造函数里面的代码,给这个空对象添加属性和方法
        //4. 返回这个对象(所以构造函数里面不需要return)
        function Star(uname,age,sex){
        	this.name = uname;
        	this.age = age;
        	this.sex = sex;
        	this.sing = function (song) {
        		console.log(song);
        	}
        }
        var ldh = new Star('刘德华',18,'男'); //调用函数返回的是一个对象 
        console.log(ldh);  // ldh == {name:"刘德华",age:18,sex:"男",sing:f}
        
        
    • 遍历对象

      //遍历对象
      var obj = {
      	uname:'张三',
      	age :18,
      	sex:'男',
      	sayHi:functon(){
      		console.log('hello');
      	}
      }
      // for in  遍历我们的对象
      // for(变量 in 对象){
      //}
      for(var k in obj){
      console.log(k);  // 打印:uname age sex     如果输出的是变量,得到的是属性名
      console.log(obj[k]);//得到的是属性值 打印:{name:"张三",age:18,sex:"男",sayHi:hello}
      
      }
      //k是变量,不加引号
      //for  in  里面的变量,常用k或key命名
      
      
    • 总结

      1. 对象可以让代码结构更清晰
      2. 对象复杂类型Object
      3. 本质:对象就是一组无序的相关属性和方法的集合
      4. 构造函数泛指一大类,比如水果,不管香蕉还是苹果统称为水果
      5. 对象实例特质一个事务,比如刘德华,这个苹果
      6. for . … in 语句用于对对象的属性进行循环操作

JS内置对象

  • 内置对象

    • JS对象分为三种:自定义对象,内置对象,浏览器对象

    • 前两者是JS基础内容,属于ECMAScript;浏览器对象是JS独有的,在JS API中出现

    • 内置对象是JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用或是最基本而必要的功能(属性和方法)

      —— 直接封装好的一些代码,像是安装好的手机,不需要直到手机内部构造,直接可以使用

      • 内置对象最大的优点是帮助我们快速开发
    • JS提供了多个内置对象:Math,Array,String等

  • 查阅文档

    内置对象很多,方法更多,很难一下子都记住。可以了解未知的内置对象使用方法。

    • MDN

      学习一个内置对象的使用,只需要学会常用的方法使用即可,可以通过文档学习,通过MDN/W3C来查询。

      Mozilla开发者网络(MDN)提供了有关开放网络技术(Open Web)的信息,包括HTML,CSS和万维网及HTML5应用的API。

      MDN:https://developer.mozilla.org/zh-CN/

      MDN(JS):https://developer.mozilla.org/en-US/docs/Web/JavaScript

    • 学习对象中的方法

      1. 查阅该方法的功能
      2. 查看里面参数的意义和类型
      3. 查看返回值的意义和类型
      4. 通过demo进行测试
  • Math对象

    Math对象是一个内置对象,它具有数学常数和函数的属性方法,跟数学有关的运算(求绝对值,取整,最大值等)都可以使用Math中的成员,它不是一个函数对象。

    与其他全局对象不同的是,Math不是一个构造函数(构造器),Math的所有属性和方法都是静态的。

    /Math数学对象 不是一个构造函数,所以我们不需要用new来调用,而是直接使用里面的属性和方法即可
    console.log(Math.PI);   //属性:圆周率
    console.log(Math.max(1,2,3));  //3
    console.log(Math.max(2,44,'张三')); //NaN ,其中含有字符串,则返回NaN;如果没有参数,则返回-INfinity,负的无穷大
    
    

    案例:

    //利用对象封装自己的数学对象,里面有PI圆周率 最大值和最小值
    var myMath = {
    PI :3.141592653;
    max:function(){
    	var max = argument[0];
    	for(var i = 1;i < arguments.length;i++){
    		if(arguments[i] > max){
    			max =  arguments[i];
    		}
    	}
    	return  max;
    },
    min:function(){
    	var min = argument[0];
    	for(var i = 1;i < arguments.length;i++){
    		if(arguments[i] < min){
    			min =  arguments[i];
    		}
    	}
    	return  min;
      }
    }
    console.log(myMath.PI);  //3.141592653
    console.log(myMath.max(1,2,3));//3
    console.log(myMath.min(4,5,6));//4
    
    

    Math方法

    Math.PI( ) 圆周率
    Math.floor() 向下取整
    Math.ceil() 向上取整
    Math.round() 四舍五入,就近取整(如果是-3.5,结果为 -3)
    Math.abs() 绝对值
    Math.max()/Math.min() 求最大和最小值
    //绝对值
    console.log(Math.abs(1));// 1
    console.log(Math.abs(-1));// 1
    console.log(Math.abs('-1'));// 隐式转换,把字符串型-1转化为数字型
    console.log(Math.abs('张三'));// NaN
    //取整方法
    //Math.floor()   地板  向下取整  往小了取
    console.log(Math.floor(1.1));// 1
    console.log(Math.floor(1.9));// 1
    //Math.ceil()   天花板  向上取整  往大了取
    console.log(Math.ceil(1.1));// 2
    console.log(Math.ceil(1.9));// 2
    //Math.round()   四舍五入  其他数字都是四舍五入 但.5特殊,往大取值
    console.log(Math.ceil(1.1));// 1
    console.log(Math.ceil(1.9));// 2
    console.log(Math.ceil(-1.1));// -1
    console.log(Math.ceil(-1.5));// -1
    
    
    • 随机数方法 random( )

      //1.Math对象随机数方法  random()返回一个随机数的小数  0 <= x  < 1
      //2.这个方法里面不跟参数
      //3.代码验证
      console.log(Math.random());
      //4.得到两个数之间的随机整数 并且 包含这2个整数
      //Math.floor(Math.random()*(max - min + 1)) + min;   //核心语句要背下来
      function getRandom(min,max){
      return Math.floor(Math.random()*(max - min + 1)) + min;
      }
      console.log(getRandom(1,10)); 
      //5.随机点名
      var arr = ['张三','李四','王二麻子'];
      console.log(arr[getRandom(0,arr.length-1]);
      </script>
      
      

      案例:

      //猜数字
      //1.随机生成一个1~10之间的整数,用到Math.random()方法
      //2.直到正确才停止,要一直循环
      //3.while循环更简单
      //4.核心算法:使用 if  else  if 多分枝语句来判断大于,小于,等于。
      function getRandom(min,max){
      	return Math.floor(Math.random()*(max-min+1))+ min;
      }
      var random = getRandom(1,10);
      while (true) { //死循环
      	// statement
      	var num = prompt('猜数字');
      	if (num > random()) {
      alert("猜大了");
      	}else if{
      alert("猜小了");
      	}else{
      		alert("猜对了");
      		break;//退出整个循环结束程序
      	}
      }
      
      
  • Date日期对象

    • Date概述

      Date实例是用来处理日期和时间

      Date对象和Math对象不一样,它是一个构造函数,需要实例化后才能使用,只能通过Date构造函数来实例化日期对象。

      //Date()日期对象是一个构造函数,不许要使用new来调用
      var arr = new  Array(); //创建一个数组对象
      var  obj  = new Object();//创建了一个对象实例
      
      
    • Date( )方法的使用

      • 获取当前时间必须实例化

        //1.使用Date
        var date = new Date(); //如果没有输入任何参数,则Date的构造器会依照系统设置的当前时间来创建一个Date对象
        console.log(date);
        
        
      • Date( )构造函数的参数

        如果括号里有时间,就返回参数里面的时间。

        例如日期更是字符串为’2019-5-1’,可以写成newDate(‘2019-5-1’)或new Date(‘2019/5/1’)

        //2.参数常用的写法:数字型2019,10,01或者是字符串型'2019-10-01 8:8:8'
        var date1 = new Date(2019,10,1);
        console.log(date1);   // Fri Nov 01 2019 00:00:00 GMT+0800 (中国标准时间)返回的是11月,不是10月
        var date2 = new Date('2019-10-1 8:8:8');
        console.log(date2); //Tue Oct 01 2019 08:08:08 GMT+0800 (中国标准时间)
        
        
      • 日期格式化

        需要2019-10-1 8:8:8格式的日期,怎么做到?

        要获取日期指定的部分,需要手动得到这种格式。

        方法名 说明 代码
        getFullYear() 获取当年 dObj.getFullYear()
        getMonth() 获取当月(0-11) dObj.getMonth()
        getDate() 获取当天日期 dObj.getDate()
        getDay() 获取星期几(周日0-周六6) dObj.getDay()
        getHours() 获取当前小时 dObj.getHours()
        getMinutes() 获取当前分钟 dObj.getMinutes()
        getSeconds() 获取当前秒钟 dObj.getSeconds()
        //格式化日期  年月日
        var date3 = new Date();
        console.log(date3.getFullYear());  //返回当前日期的年  2019
        console.log(date3.getMonth() + 1); //月份  返回的月份小1个月  记得月份+1 
        console.log(date3.getDate()); //  返回的是几号
        console.log(date3.getDay());  //3  周一返回的是1
        // 返回 2019 年 5 月 1 日  周三
        var year = date3.getFullYear();
        var month = date3.getMonth() + 1;
        var dates = date3.getDate();
        var arr = ['周日','周一','周二','周三','周四','周五','周六'];
        var day = date3.getDay();
        console.log('今天:'+year+'年'+month+'月'+dates+'日'+arr[day]);
        console.log(date3.getDate());
        console.log(date3.getDay());
        
        //格式化日期  时分秒
        console.log(date3.getHours()); //时
        console.log(date3.getMinutes()); //分
        console.log(date3.getSeconds()); //秒
        //要求封装一个函数返回当前的时分秒  格式08:08:08
        function getTime(){
        	 var time = new Date();
        	 var h = time.getHours();
        	 h = h < 10 ? '0' + h : h;
        	 var m = time.getMinutes();
        	 m = m < 10 ? '0' + m : m;
        	 var s = time.getSeconds();
        	 s = s < 10 ? '0' + s : s;
        	 return h + ':' + m + ':' + s;
        }
        console.log(getTime());//15:15:48
        
        
      • 获得Date总的毫秒数

        //获得Date总的毫秒数(时间戳),不是当前时间的毫秒数,而是距离1970年1月1日过来多少毫秒数
        //1.通过valueOf()  getTime()
        var date = new Date();
        console.log(date.valueOf()); //当前时间距离1970.1.1的总毫秒数
        console.log(date.getTime());  //同上
        //2.简单的写法(最常用的写法)
        var date1 = +new Date(); //+new Date() 返回的是总毫秒数
        console.log(date1);
        //H5新增方法  获取总的毫秒数
        console.log(Date.now());
        
        
      • 案例:倒计时

        • 核心算法:输入时间减去现在的时间就是剩余的时间,即倒计时,但是不能拿着时分秒相减,比如05分减去25分,结果会是负数的。

        • 用时间戳来做,用户输入时间总的毫秒数减去现在时间总的毫秒数,得到的就是剩余时间的毫秒数。

        • 把剩余时间总的毫秒数转换为天,时,分,秒。

        转化公式如下:
        d = parseInt(总秒数/60/60/24); //计算天数
        h = parseInt(总秒数/60/60%24); //计算小时
        m = parseInt(总秒数/60%60); //计算分数
        s = parseInt(总秒数%60); //计算当前秒数
        
        
        function conutDown(time){
        	var nowTime = +new Date(); //返回的是当前时间总的毫秒数
        	var inputTime = +new Date(time); //返回的是用户输入时间总的毫秒数
        	var times = (inputTime - nowTime)/1000;
        	//time是剩余时间的总秒数
        	var d = parseInt(times/60/60/24); //计算天数
        	d = d < 10 ?'0'+d:d; 
        var h = parseInt(times/60/60%24); //计算小时
        h = h < 10 ?'0'+h:h; 
        var m = parseInt(times/60%60); //计算分数
        m = m < 10 ?'0'+m:m; 
        var s = parseInt(times%60); //计算当前秒数
        s = s < 10 ?'0'+s:s; 
        }
        console.log(conutDown('2019-5-1 18:00:00'));
        
        
  • 数组对象

    • 检测是否为数组

      //检测是否为数组
      //instanceof 运算符,可以检测是否为数组
      var arr = [];
      var obj = {};
      console.log(arr instanceof new Array());//true
      console.log(obj instanceof new Array());//false
      // Array.isArray(参数);H5新增的方法 ie9以上支持
      console.log(Array.isArray(arr));
      console.log(Array.isArray(obj));
      
      
    • 添加删除数组方法

      方法名 说明 返回值
      push(参数1…) 末尾添加一个或多个元素,注意修改原数组 数组及新的长度
      pop() 删除数组的最后一个元素,把数组长度减1无参数,修改原数组 返回它删除的元素的值
      unshift(参数1…) 向数组的开头添加一个或更多元素,注意修改原数组 数组及新的长度
      shift() 删除数组的第一个元素,数组长度减1无参数,修改原数组 数组及第一个元素的值
      //添加删除数组元素
      //1.push() 在数组的末尾 添加一个或多个元素
      var arr = [1,2,3];
      //arr.push(4,'张三');
      console.log(arr.push(4,'张三')); //5
      console.log(arr);//[1,2,3,张三]
      //push是可以给数组追加新的元素
      //push()参数直接写 数组元素就可以了
      //push完毕后,返回的结果新数组的长度
      //原数组也会发生变化
      //2.unshift 在数组的开头,添加一个或多个数组元素
      console.log(arr.unshift('red','orange'));//6
      console.log(arr);//['red','orange',1,2,3,'张三']
      //unshift是可以给数组前面追加新的元素
      //unshift()参数直接写数组元素就可以了
      //unshift完毕后,返回的结果是新数组的长度
      //原数组也会发生变化
      //3.pop()可以删除数组的最后一个元素
      console.log(arr.pop()); //张三
      console.log(arr);  //['red','orange',1,2,3]
      //pop是可以删除数组的最后一个元素,记住一次只能删除一个元素
      //pop()没有参数
      //pop完毕之后,返回的结果是删除的那个元素
      //原数组也会发生变化
      //4.shift() 它可以删除数组的第一个元素
      console.log(arr.shift()); //red
      console.log(arr);//[orange',1,2,3]
      //shift是可以删除数组的第一个元素,记住一次只能删除一个元素
      //shift()没有参数
      //shift完毕之后,返回的结果是删除的那个元素
      //原数组也会发生变化
      
      
    • 筛选数组

      //有一个包含工资的数组[1500,2000,2100,1800],要求把数组中工资超过2000的删除,剩余的放到新数组里面
      var arr = [1500,2000,2100,1800];
      var newArr = [];
      for(var i = 0;i < arr.length;i++){
      	if (arr[i] < 2000) {
      	//newArr[newArr.lenght] = arr[i];
      	newArr.push(arr[i]);
          }
      }
      console.log(newArr);//[1500,1800]
      
      
    • 数组排序

      方法名 说明 是否修改原数组
      reverse() 颠倒数组中元素的顺序,无参数 该方法会改变原来的数组,返回新的数组
      sort() 对数组的元素进行排列 该方法会改变原来的数组 ,返回新数组
      //数组排序
      //1.翻转数组
      var arr = ['orange','yellow','red'];
      arr.reverse();
      console.log(arr);
      //2.数组排序(冒泡排序)
      var arr1 = [1,2,3,4];
      arr1.sort(function(a,b){   //要记住
      // return a - b;  //按照增序的顺序排列
      return b - a;  //按照降序的顺序排列
      });
      console.log(arr1);//[4,3,2,1]
      
      
      
    • 数组索引方法

      方法名 说明 返回值
      indexOf( ) 数组中查找给定元素的第一个索引 如果存在返回索引号,如果不存在,则返回-1
      lastIndexOf() 在数组中最后一个的索引 如果存在返回索引号,如果不存在,则返回-1
      //返回数组元素索引号方法  indexOf(数组元素)  作用是返回该数组元素的索引号 从前面开始查找
      //它只返回第一个满足条件的索引号
      //它如果在该数组里面找不到元素,则返回的是-1
      var arr = ['orange','yellow','red'];
      console.log(arr.indexOf('red'));//2
      //返回数组元素索引号方法  lastIndexOf(数组元素) 作用就是返回该数组元素的索引号 从后面开始查找
      console.log(arr.lastIndexOf('orange')); //0
      
      
    • 案例:数组去重

      //数组去重['c','a','b','f','e','c','g','h','g']  去除数组中重复的元素
      //目标:把旧数组中不重复的元素选取出来放到新数组里,重复的元素只保留一个,放到新数组去重
      //核心算法:遍历旧数组,然后拿着旧数组元素去查询新数组,如果该元素只在新数组里面没有出现过,就添加,否则不添加
      //怎么知道该元素没有存在?利用新数组.indexOf(数组元素),如果返回时-1就说明新数组里面没有改元素
      //封装一个去重的函数 独一无二的
      function unique(arr){
      	var newArr = [];
      	for(var i = 0;i < arr.length;i--){
      		newArr.push(arr[i]);
      	}
      }
      return newArr;
      var demo = unique(['c','a','b','f','e','c','g','h','g']);
      console.log(demo);  //'c','a','b','f','e','g','h'
      
      
    • 数组转化为字符串

      方法名 说明 返回值
      toString( ) 把数字转换成字符串,逗号分割一项 返回一个字符串
      join( ‘分隔符’) 方法用于把数组中所有元素转化成一个字符串 返回一个字符串
      //数组转换成字符串
      //1.toString()将数组转换为字符串
      var arr = [1,2,3];
      console.log(arr.toString());//1,2,3
      //2.join(分隔符)
      var arr1 = ['red','orange','blue'];
      console.log(arr1.join()); //red,orange,blue
      console.log(arr1.join('-'));//red-orange-blue
      console.log(arr1.join('&'));//red-orange-blue
      
      
    • 方法名 说明 返回值
      concat() 连接两个或多个数组,不影响原数组 返回一个新的数组
      slice() 数组截取slice(begin,end) 返回被劫持项目的新数组
      splice() 数组删除splice(第几个开始,要删除个数) 反会被删除项目的新数组,注意这个会影响原数组
  • 字符串对象

    • 基本包装类型

      为了方便操作基本数据类型,JS还提供了三个特殊的引用类型:String,Number,Boolean。

      基本包装类型是指把简单数据类型包装成复杂数据类型,这样基本数据类型就有了属性和方法。

      //基本包装类型
      var str = "Tom";
      console.log(str.length);//3
      //对象才有属性和方法    复杂数据类型才有属性和方法
      //简单数据类型为什么会有length属性?
      //因为js会把基本数据类型包装成复杂数据类型
      //基本包装类型:将简单数据类型包装成为复杂数据类型
      //1.把简单数据类型包装为复杂数据类型
      var temp = new String('Tom');
      //2.把临时变量的值给str
      str = temp;
      //3.销毁临时变量
      temp = null;
      
      
    • 字符串的不可变

      不可变是指里面的值不可变,虽然看上去内容改变了,但其实是str指向发生变化,内存中新开辟了一个内存空间。

      var str = 'orange';
      console.log(str); //orange
      //当重新给str赋值时,变量'orange'不会被修改,依然在内存中
      //重新给字符串赋值,会重新在内存中开辟空间,这个特点是字符串的不可变
      var str = 'red';
      console.log(str) //red
      //因为字符串的不可变所以不要大量的拼接字符,会有效率问题
      var str = '';
      for(var i = 1;i <= 100;i++){
      str += i;
      
      }
      console.log(str);
      
      
    • 根据字符返回位置

      字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串。

      方法名 说明
      indexOf() 返回指定内容在元字符串中的位置,如果找不到就返回-1,开始的位置是index索引号
      lastIndexOf() 从后往前找,只找第一个匹配的
      //字符串对象
      //根据字符返回位置 str.indexOf('要查找的字符',[起始的位置]);
      var str = '长莫长于博谋';
      console.log(str.indexOf('长')); //0
      console.log(str.indexOf('长'1)); //索引是1的位置开始往后查找    2
      
      
    • 案例:

      //查找字符串"abcoefoxyozzopp"中所有o出现的位置以及次数
      //核心算法:先查找第一个o出现的位置
      //只要indexOf返回的结果不是-1,就能继续往后查找
      //因为indexOf只能查找到第一个,所有后面的查找,一定是当前索引加1,从而继续查找
      var str = "abcoefoxyozzopp";
      var index = str.indexOf('o');
      var num = 0;//次数
      while (index !== -1) {
      	// statement
      	console.log(index);
      	num++;
      	index = str.indexOf('o',index + 1);
      }
      console.log('次数'+num);//4
      
      
    • 根据位置返回字符(重点)

      方法名 说明 使用
      charAt(index) 返回指定位置的字符(index字符串的索引号) str.charAt(0)
      charCodeAt(index) 获取指定位置处字符的ASCI码(index索引号) str.charCodeAt(0)
      str[index] 获取指定位置处字符 H5,IE8支持,和charAt()等效果
      //根据位置返回字符
      //1.charAt(index) 根据位置返回字符
      var str ='andy';
      console.log(str.charAt(3));
      //遍历所有字符
      for(var i = 0;i <str.length;i++){
      console.log(str.charAt(i));
      }
      //2.charCodeAt(index) 返回相应索引号ASCII值
      //目的:判断用户按下了那个键
      console.log(str.charCodeAt(0));//97
      //3.str[index] H5新增的
      console.log(str[0]); //a
      
      
    • 案例:

      //判断一个字符串"abcoefoxyozzopp"中出现次数最多的字符,并统计其次数
      //o.a = 1
      //o.b = 1
      //o.c = 1
      //o.o = 4
      //核心算法:利用charAt() 遍历这个字符串
      //把每个字符都储存给对象,如果对象没有该属性,就为 1 ,如果存在就+1
      //遍历对象:得到最大值和该字符
      var str = "abcoefoxyozzopp";
      var o = {};
      for(var i = 0;i < str.length;i++){
      var chars = str.charAt(i); //chars 是字符串的每一个字符
      if(o[chars]){ //o[chars]得到的是属性值
      	o[chars]++;
      }else{
      	o[chars] = 1;
         }
      }
      //2.遍历对象
      var max = 0;
      var ch = '';
      for(var k in o){
      	//k得到的是属性名
      	//o[k]得到的是属性值
      	if(o[k]>max){
      		max = o[k];
      		ch = k;
      	}
      }
      console.log(max);
      console.log('最多字符'+ ch);
      
      
    • 字符串操作方法(重点)

      方法名 说明
      concat(str1,str2) concat()方法用于连接两个或多个字符串,拼接字符串,等效于+,+更常用
      substr(start.length) 从start位置开始(索引号),length取的个数
      slice(start,end) 从start位置开始,截取到end位置,end取不到(两者都是索引号)
      substring(start,end) 从start位置开始,截取到end位置,end取不到,基本和slice相同,但是不接受负值
      toUpperCase() 转换大写
      toLowerCase() 转换小写
      //字符串操作方法
      //1.concat(str1,str2)
      var str = 'andy';
      console.log(str.concat('red'));
      //2.substr('截取起始位置','截取几个字符');
      var str1 = '改革春风吹满地';
      console.log(str1.substr(2,2));  //第一个2,索引号的2,从第几个开始;第二个2,取几个字符
      //3.替换字符串replace('被替换字符','替换为字符') 他只会替换第一个字符
      var str = 'andyandy';
      console.log(str.replace('a','b'));
      //把字符串"abcoefoxyozzopp"里面所有的'o'替换为*
      var str1 = "abcoefoxyozzopp";
      while(str1.indexOf('o')!== -1){
      	str1 = str1.replace('o','*');
      }
      console.log(str1);
      //4.字符转换为数组 split('')  数组转换为字符串join()
      var str2 = 'red,pule,black';
      console.log(str2.split(','));
      var str3 = 'red&pule&black';
      console.log(str3.split('&'));
      
      
  • 简单数据类型和复杂数据类型

    简单类型又称基本数据类型或者值类型,复杂类型又叫做引用类型。

    • 值类型:简单数据类型/基本数据类型,在储存时变量存储的是值本身,因此称为值类型。

      String,number,boolean,undefine,null

      //简单数据类型 null 返回的是一个空对象  object
      var time = null;
      console.log(typeof time);
      //如果有变量打算以后存储为对象,没想好放什么,这时候就给null
      
      
      • 值类型变量的数据直接存放在变量(栈空间)中
    • 引用类型:复杂数据类型,在存储时变量存储的仅仅是地址(引用),称之为引用类型,通过new关键字创建的对象(系统对象,自定义对象),如Object,Array,Date等

    • 堆栈空间

      • 堆栈空间分配区别:

        • 栈(操作系统):由操作系统自动分配释放存放函数的参数值,局部变量的值等,操作方法类似于数据结构中的栈。

          简单数据类型存放到栈里面,里面直接开辟一个空间存放的是值。

        • 堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。

          复杂数据类型存放到堆里面,首先存放地址,然后这个地址指向堆里面的数据。真正的对象实例存放在堆空间中。

      注意:JS中并没有堆栈的概念,但两者在内存中互不干扰。

    • 简单类型传参

      function fn(a){
      	a++;
      	console.log(a);
      }
      var x = 10;
      fn(x); //11
      console.log(x); //10
      
      
    • 复杂类型传参

      function Person(name){
      	this.name = name;
      }
      function f1(x){ //x = p
      	console.log(x.name); //刘德华
      	x.name = "张学友";
      	console.log(x.name);//张学友
      
      }
      var p = new Person("刘德华");
      console.log(p.name); //刘德华
      f1(p);
      console.log(p.name);//张学友
      
      

你可能感兴趣的:(黑马程序员)