JavaScript语法基础与算法

230 阅读10分钟

认识JavaScript语言

部署JavaScript的运行环境

 1、内部JavaScript代码:

在HTML文档的任意位置书写

<script type=“text/javascript”>

  console.log(“今天开始学习JavaScript脚本语言”);

</script>

 2、外部JavaScript代码:

在项目根目录下新建js文件夹,在该文件夹中新建index.js文件,在HTML文档中加载该文件。

(1)当外部js文件中没有DOM操作时,上述加载脚本的代码可以书写在中。

(2)当外部js文件中有DOM操作时,上述加载脚本的代码必须书写在内部的末尾。

 3、内联JavaScript代码:

    <div onclick=“javascript:window.close();”>关闭窗口</div>

数据的输出

  1. 以警告框的方式输出:window.alert(); 或 alert();

    在警告框中如何换行:window.alert(“请选择您的性别:**\** **n**1-男**\n**2-女”);

    在警告框中使用“转义字符”\n进行换行  
 2. 在页面中输出:document.write();

(1)在页面中将用引号引住的内容原样输出。

     使用双引号:document.write(“我使用双引号输出内容”);

     使用单引号:document.write(‘我使用单引号输出内容’);

     使用单撇号:document.write(`我使用单撇号输出内容`);

(2)在页面中输出HTML标记。

     document.write(“第一行<br />第二行”);

     document.write(“<h1>我是一级标题</h1>”);

(3)在页面中输出运算结果。

     document.write(5*9);

     document.write(`${5*9}`);

(4)在页面中混合输出:

     格式1:利用 + 将不同类型的输出内容首尾相连。

        document.write(“<h2>25*4=” + (25*4) + “</h2>”);

     格式2:利用字符模板技术输出混合内容。

使用``作为输出内容的定界符,内部出现的运算使用${}包裹。

        document.write(`<h2>25*4=${25*4}</h2>`);      // es6规定的新字符拼接模式 

JavaScript数据类型

JavaScript数据类型分为:基本数据类型引用数据类型

1、基本数据类型:数值型、字符型、逻辑型、未定义型、null型、Symbol型 (es6)

2、引用数据类型:数组、对象、函数。

数值型(number)

1、JavaScript将数值型分为“整型数值”、“实型数值”。

 2、整型数值:没有小数点的数值就是“整型数值”。

整型数值按照数值的进制数划分为以下四类:

(1)十进制整型数值:

     例:10、2、-5、1000、-450等。

(2)八进制整型数值:

     以0、0o或0O开头的数值是八进制整型数值。例:047、0o47、0O47等。

     console.log(0o47);         // 39

     console.log(0o10);         // 8

(3)十六进制整型数值:

     以0x或0X开头的数值是十六进制整型数值。

     console.log(0x1a);         // 26

     console.log(0xff);          // 255

(4)二进制整型数值:

         以0b或0B开头的数值是二进制整型数值。

         console.log(0b1010); // 10

     【总结】

    A .0o/0O、0x/oX、0b/0B被称为数值的“前导”,前导既不是数值的一部分,也不参与实际的运

    算。只能说明前导后面的数值是指定的进制数。

        B .在JavaScript编成过程中,前导是可以出现在代码中的,即带有前导的数值是“合法”的。

          以下格式是“非法的”:console.log(0o28);     // 八进制数值不能带有8

 3、实型数值:带有小数点的数值就是“实型数值”。

实型数值分为“定点实数”和“浮点实数”。

(1)定点实数:是实型数据的小数形式。例:1.5、3.14、0.0、5.、.9等。

(2)浮点实数:是实型数据的科学计数法形式。

         A .在数学中:12.4765可以表示为 0.124765×102  1.24765×101  12476.5×10-3 

         B .浮点实数的书写格式:底数e阶码  底数E阶码

           底数:浮点实数中乘号左侧的小数,也被称为“尾数”。

           阶码:浮点实数中乘以10的幂指数。

         C .所以 12.4765可以表示为:

           0.124765e+002 // 阶码可以带有正负号,且可以补足最多三位

           0.124765e+02 // 阶码可以补足两位

           0.124765e+2 // 阶码可以只有一位

           0.124765e2 // 正数次幂阶码可以省略正号

           0.124765E2 // 连接底数和阶码的字母E可以大写

         D .浮点实数书写时必须满足以下规定:

           字母e/E的左侧和右侧必须带有数字。例:4e、e9都是非法的。

           阶码必须为整数。例:4e0.5是非法的。

           字母e/E左右两侧不能带有空格。

           例:表示10-6可以书写为1e-6。

         E .浮点实数在输出时的规范格式:

           浮点实数的底数必须是整数部分只有1位且不是0的浮点实数格式。

           例:console.log(45.39e87)        // 4.539e88

字符型(string)

1、字符型数据也被称为“字符串”,是由双引号、单引号、单撇号作为定界符的数据类型。

例:“abc”、‘张三’、xyz1等。

 2、生活中无法进行算数运算的数字全部划分为字符型数据。

    例:“18000319142” 手机号码、“050000” 邮政编码、“130105xxxxxxxxxxxx” 身份证号码

 3、字符型数据分为“字面量字符”和“转移字符”。

    直接利用定界符扩住的普通字符串都是字面量字符,例:“A3”、“4c”等。

 4、什么是转义字符:

在字符定界符范围内,用\开头,后面带有一个或多个字符,且表示特定含义的格式被称为“转义字符”。

例:“\n” 表示换行,相当于按下了键盘上的Enter(回车)键。

    “\t” 表示制表位,相当于按下了键盘上的Tab键。

逻辑型(boolean)

1、逻辑型也被称为“布尔型”,用来表示生活中只有两种状态的情况。

 2、逻辑型数据只有两个:

(1)逻辑真,用true表示。

(2)逻辑假,用false表示。

未定义型(undefined)

空型(null)

数组(Array)

1、数组分为两类:一维数组、多维数组。

 2、创建数组的方法:

var a=["a","b","c","d",123,false];

console.log(a);

console.log(a.length);

 3、数组的复制:

(1)基本数据类型的复制:

     var a=5;

     var b=a; // 将基本数据类型的变量a赋给变量b

     console.log(a,b); // 5 5

     b=10;

     console.log(a,b); // 5 10

(2)数组的复制:

     var a=[10,20,30,40];

     var b=a; // 将数组a赋给数组b被称为数值的“浅拷贝”

     console.log(a,b); // [10,20,30,40]  [10,20,30,40]

     b[0]=“A”;

     console.log(a,b);      // [“A”,20,30,40]  [“A”,20,30,40]

    (3)变量的本质:

     使用var声明变量本质上是在内存中为该变量开辟一个存储空间,用于存放该变量的值。

     var a=5;

     var b=a;

 b    a  
 5    5  

     var a=[10,20,30,40];       // 系统为数组独立分配存储空间

     var b=a;                // b指向了a所指

b 数组 a 
5 001**5 002**5 003**5 004**5 005**5 006**5 007**5 008**5 009**
5 003 10203040 5 003 

      

     A .将数组赋给一个变量,此时内存中该变量的存储空间无法存放数组的数据。

     B .数组在内存中要存放在一片连续的存储空间中。

     C .变量a本质上存储的是数组的地址值。

     D .数组的地址是数组的第一个元素在内存中的地址。

     E .将变量a赋给另一个变量b,则另一个变量b存储的也是这个变量a中存放的数组地址值。

对象(Object)

对象就是一种键值对类型,包括键名和键值。

 1、创建对象:

(1)对象利用{}作为定界符,内部包含对象的成员。

(2)对象的成员由成员名(键名)和成员值(键值)两部分组成,中间利用冒号进行间隔。

(3)成员值必须是符合JS数据类型的数据。

(4)成员之间用逗号间隔。

     例:var a={x:100,y:200,z:300,t:fasle};

         console.log(a)       // {t:false,x:100,y:200,z:300}  输出对象时,对象成员按照成员名升序排列

     例:可以通过对象名来访问内部的成员。

         console.log(a.x);     // 100

         console.log(a.z);     // 300

 2、对象中间也具备“浅拷贝”现象:

var a={x:10,y:20,z:30};

var b=a;                 // 将对象a复制给对象b

b.z=“W”;

console.log(a,b);          // {x:10,y:20,z:“W”}  {x:10,y:20,z:“W”}

数据类型的测试:

 1、可以通过typeof()运算符测试常量/变量的数据类型。

 2、var a=10;

console.log(typeof(a)); // number

var b="A";

console.log(typeof(b)); // string

var c=true;

console.log(typeof(c)); // boolean

var d=undefined;

console.log(d); // undefined(颜色暗淡的输出结果)

console.log(typeof(d)); // undefined(颜色明亮的输出结果)

var e=null;

console.log(typeof(e)); // object

var f=[10,20,30,40];

console.log(typeof(f)); // object

var g={a:1,b:2};

console.log(typeof(g)); // object

null,数组,和对象输出数据类型都为object

JavaScript常量与变量

常量

 1、在程序运行过程中不变的量就是常量,是各种不同数据类型的字面量。

列举不同数据类型的常量:

15、0o47、0xff、0b101、3.14、14.75e+002、“abc”、“\n”、true、undefined、null

 2、可以使用const声明一个具备名称的常量。

(1)格式:const 常量名 = 常量;

(2)例:const PI=3.14;

(3)对常量的规定:

     A .常量使用const声明的同时必须赋值。

     B .在程序运行过程中,不能再为常量赋新值。

     C .为了和变量名区分,建议常量名采用全大写模式。

         const PI=3.14;

         console.log(PI);      // 3.14

         PI=5;              // 报错:Assignment to constant variable.(为常量赋值了)

变量

 1、在程序运行过程中可以变化的量就是变量,变量要具备变量名和变量值两部分。

 2、声明变量:

(1)格式1:var 变量名 = 变量值;

(2)格式2:(ES6) let 变量名 = 变量值;

 3、var和let声明的变量的区别:

(1)var可以对变量进行重复声明;let不可以对变量进行重复声明。

     var x=10;

     console.log(x); // 10

     var x=100;

     console.log(x); // 100

     let x=10;

     console.log(x); // 10

     let x=100; // 报错:Identifier 'x' has already been declared(标识符x已经声明)

(2)var声明的变量可以在初始化之前访问;let声明的变两个在初始化之前不能访问。

     x=10; // 对变量x进行了初始化

     console.log(x); // 10

     var x=100;

     console.log(x); // 100

-----------------------

     x=10; // 报错:Cannot access 'x' before initialization(在初始化之前不能访问x)

     console.log(x);

     let x=100;

     例:console.log(x); // undefined

         var x=5;

         console.log(x); // 报错:Cannot access 'x' before initialization

         let x=5;

 4、声明变量的同时赋初值:

(1)允许在声明变量的同时为其赋初值:

     var x=15;

     let y=13;

(2)也允许在声明变量的同时不为其赋初值。

     var x;

     x=15;

     let y;

     y=13;

     例:若声明变量的同时没有赋初值,此时直接输初该变量会返回undefined。

         var x;

         let y;

         console.log(x,y);     // undefined undefined

 5、标识符(Identifier)

(1)标识符是在程序中出现的英文单词。

(2)标识符分为“关键字”和“自定义标识符”两类。

(3)关键字:也被称为“保留字”,是系统保留下来的有固定用途的单词。

     关键字除了系统分配的固定用途之外不能另作他用。

     例:var是一个关键字,所以下列语句是非法的。

         var var=10;      // 报错:Unexpected token 'var'(不能使用关键字作为变量名)

(4)标识符的命名规则:

     A .标识符只能够带有字母大小写、数字、下划线、$、中文。

     B .标识符不得以数字开头。

     C .标识符严格区分大小写。

       例:var a=15;

           console.log(a); // 15

           console.log(A); // 报错:A is not defined(A没有被定义)

     D .[建议] 使用标识符时最好做到“见名知意”。

 6、利用var/let可以一次声明多个变量,变量之间用逗号间隔。

例:let a,b,c;

    let a=5,b,c=15;

JavaScript运算体系

关系运算符比较字符串

(1)比较原则:将两个字符串中对应位置的字符按照字符的ASCII码两两比较,比较过程中若两个字

符相等,则比较下一个位置,以此类推。第一个比较出来的结果就是两个字符串比较的结果。

若在比较过程中,任意一个字符串结束时尚未比较出结果,则串长大的字符串大。

(2)例:“abc”和“abd”比较,“abd”大。

         “abaabaaba”和“abz”比较,“abz”大。

         “abc” 和“abcd”比较,“abcd”大。

4、关系运算符的优先级:

   (1)>  >=  <  <=

   (2)==  !=  ===  !==
1、都有哪些关系运算符:

    >  >=  <  <=  ==  !=  ===  !==

 2、关系运算符的功能:

(1)关系运算符组成的关系表达式在现实生活中成立,则运算结果为true;在现实生活中不成立,则

运算结果为false。【即关系表达式的运算结果是一个逻辑值】

         console.log(5<10);       // true

         console.log(5>10);       // false

(2)==(等于号):若两边的数据转换为同一个数据类型后值相等,则成立;若两边的数据转换为同

一个数据类型后值不相等,则不成立。

     console.log(5==5); // true

     console.log(“5”==5); // true

     console.log(“”==false); // true

(3)!=(不等于号):若两边的数据转换为同一个数据类型后值相等,则不成立;否则成立。

     console.log(5!=5); // false

     console.log(“5”!=5); // false

    (4)===(精确等于):两边的数据完全相同,则精确等于成立;否则不成立。

         console.log(5===5); // true

         console.log(“5”===5); // false

(5)!==(精确不等于):两边的数据完全不相同,则精确不等于成立;否则不成立。

     console.log(5!==5); // false

     console.log(“5”!==5); // true

 3、利用关系运算符比较字符串:

(1)比较原则:将两个字符串中对应位置的字符按照字符的ASCII码两两比较,比较过程中若两个字

符相等,则比较下一个位置,以此类推。第一个比较出来的结果就是两个字符串比较的结果。

若在比较过程中,任意一个字符串结束时尚未比较出结果,则串长大的字符串大。

(2)例:“abc”和“abd”比较,“abd”大。

         “abaabaaba”和“abz”比较,“abz”大。

         “abc” 和“abcd”比较,“abcd”大。

4、关系运算符的优先级:

   (1)>  >=  <  <=

   (2)==  !=  ===  !==

5、关系运算符的结合性:常规结合。

逻辑运算符

 1、都有哪些逻辑运算符:

    &&(逻辑与运算符)  ||(逻辑或运算符)  !(逻辑非运算符)

 2、参与逻辑运算的数据必须是逻辑值整数

 3、逻辑与运算符的功能:

(1)&&逻辑与运算符的功能:有假则假,全真则真。

     true && true // 结果:true

     true && false // 结果:false

     false && true // 结果:false

     false && false // 结果:false

(2)&&逻辑与运算符整数参与运算的法则:

     JavaScript规定:0表示逻辑假,非0表示逻辑真

         0 && 9 // 0,逻辑与运算符左侧为0,在整个表达式结果为0。

         2 && 7 // 7,逻辑与运算符左侧不为0,则整个表达式结果为右侧的整数。

(3)逻辑与运算符的数学意义:

          数学表示:-3<x<10

          程序表示:x>-3 && x<10,x大于-3 且 x小于10。

4、逻辑或运算符的功能:

(1)||逻辑或运算符的功能:有真则真,全假则假。

     true || true // 结果:true

     true || false // 结果:true

     false || true // 结果:true

     false || false // 结果:false

(2)||逻辑或运算符整数参与运算的法则:

         0 || 9 // 9,逻辑或运算符左侧为0,则整个表达式结果为右侧的整数。

         2 || 7 // 2,逻辑或运算符左侧为非0,则整个表达式结果为左侧的整数。

(3)逻辑或运算符的数学意义:           数学表示:x<-3,或x>10

          程序表示:x<-3 || x>10,x小于-3 或 x大于10。

5、逻辑非运算符的功能:

   逻辑非运算符是一个单目运算符:非真则假,非假则真。

        ! true // false

        ! fasle // true

         ! 0 // true

         ! 5 // false

 6、逻辑运算符的优先级:

(1)!,在JavaScript中,所有的单目运算符是一家子,具有正数第二的优先级和从右向左的结合性。

(2)&&

(3)||

逻辑运算符的短路问题

A .只有逻辑与运算符 && 和 逻辑或运算符 || 会发生短路问题。

B .逻辑与运算符的短路问题:

       根据逻辑与运算符“有假则假”的法则,可以判定&&任意一侧为fasle,结果一定为false。

       短路问题认为:当&&左侧为false时,因为结果已经确定为fasle,所以右侧不再计算

       var x=0,y=5;

       x++ && y++ x结果为1,y结果为5,整个表达式的结果为0。【发生短路了】

       ++x && y++ x结果为1,y结果为6,整个表达式的结果为5。【没有发生短路】

       x++ && ++y x结果为1,y结果为5,整个表达式的结果为0。【发生短路了】

       ++x && ++y x结果为1,y结果为6,整个表达式的结果为6。【没有发生短路】

C .逻辑或运算符的短路问题:

       根据逻辑或运算符“有真则真”的法则,可以判定||任意一侧为true,结果一定为true。

       短路问题认为:当||左侧为true时,因为结果已经确定为true,所以右侧不再计算

       var x=0,y=5;

       x++ || y++ x结果为1,y结果为6,整个表达式的结果为5。【没有发生短路】

       ++x || y++ x结果为1,y结果为5,整个表达式的结果为1。【发生短路了】

       x++ || ++y x结果为1,y结果为6,整个表达式的结果为6。【没有发生短路】

       ++x || ++y x结果为1,y结果为5,整个表达式的结果为1。【发生短路了】

条件运算符

 1、条件运算符是三目运算符。

    格式:表达式1?表达式2:表达式3

 2、功能:判断表达式1的结果是否成立?若成立,则表达式2的结果是整个表达式的结果;若不成立,

则表达式3的结果是整个表达式的结果。

 3、例:计算x的绝对值。

        var x=-10,y;

    y=x>=0?x:-x;                // 计算绝对值也可以使用:y=Math.abs(x);

    console.log(`|${x}|=${y}`);

例:计算x的符号。正数返回1;负数返回-1;0返回0。

    var x=-8,y;

y=x>=0?x==0?0:1:-1;      // 计算符号也可以使用:y=Math.sign(x);

console.log(y);           // -1

 4、优先级:倒数第三。

 5、结合性:从右向左。

逗号运算符

 1、逗号运算符是多目运算符。

格式:表达式1,表达式2,表达式3,….,表达式n

 2、功能:从左向右依次运算每一个表达式,最后一个表达式的结果是整个表达式的结果。

 3、优先级:倒数第一。

 4、结合性:常规结合。

 例:var x=5,y=3,t

     t=x++,y++,x+y;   // (t=x++),y++,x+y

     console.log(x,y,t);         // 6 4 5

     var x=5,y=3;

     var t=(x++,y++,x+y);

     console.log(x,y,t); // 6 4 10

结构化程序设计

多分支选择switch case default

1、语法格式:

switch(表达式){

case 值1:语句1;

case 值2:语句2;

case 值3:语句3;

……

default: 语句n ;

}

 2、执行流程:

(1)计算表达式的值。

(2)从众多case子句中自上而下的比较case后面的值是否和第(1)步表达式的结果相同。

     找出第一个和表达式结果相同的case子句。

(3)执行后面的语句以及其后的所有语句(在case子句的末尾添加break可以停止其后语句的执行)。

(4)若众多case子句中每个值都与表达式的结果不一致,则执行default子句后面的语句。

 3、语法要求:

(1)switch后面{}中的部分被称为“switch体”。

(2)表达式的结果必须是整型或字符型,不能是实型数据。

(3)case和“值”之间必须有一个空格。

(4)case子句后面的语句可以根据业务逻辑省略,但是分号不能少。

(5)default子句可以书写在switch体的任意位置,但是功能不变。

 4、案例 14:利用switch结构实现考生成绩的等级评定。

    function getBank2(){

    let grade=document.querySelector("input[type=text]").value;

    let bank;

    switch(parseInt(grade/10)){

         case 10:

         case 9:bank="A";break;

         case 8:bank="B";break;

         case 7:bank="C";break;

         case 6:bank="D";break;

         default:bank="E";

}

       window.alert(`考生等级为:${bank}`);

}

 5、案例15:单击按钮返回今天是星期几。

    (1)让系统自动返回今天是星期几,需要用到JavaScript内置类:Date。

         // 第一步:创建Date类的实例。

         let today=new Date();

         // 第二步:通过实例调用Date类的方法getDay()

         let week=today.getDay();

         注意:Date类中getDay()方法返回的星期值取值范围为0(星期日)-6(星期六)

(2)程序代码:

    function getWeek(){

    let today=new Date();

    let week=today.getDay();

    let result;

    switch(week){

      case 0:result="星期日";break;

      case 1:result="星期一";break;

      case 2:result="星期二";break;

      case 3:result="星期三";break;

      case 4:result="星期四";break;

      case 5:result="星期五";break;

      case 6:result="星期六";

}

    window.alert(`今天${result}`);

}
    

循环结构

for循环寻话题的执行次数=(终值-初值)/步长+1

 (1)正向递增循环:

         for(let i=1;i<=100;i++)      特点:终值>初值,步长>0(即步长为1)。

(2)反向递减循环:

     for(let i=100;i>=1;i--)      特点:终值<初值,步长<0(即步长为-1)。

案例6:质数问题。判断任意数x是否为质数。

1)算法:

        A .让x分别除以234、…、x/2,若都不能将x整除,则x就是质数。

        B .让x分别除以234、…、![](),若都不能将x整除,则x就是质数。

   (2)如何实现算数平方跟的运算:Math.sqrt(x),返回x的算术平方根。

   (3)程序代码1:

        function isPrime(){

            let x=document.querySelector("input[type=text]").value;

            let i;

            for(i=2;i<=Math.sqrt(x);i++){       // for循环的正常化出口

             if(x%i==0) break;              // for循环的非正常化出口

        }

        // 如果从“非正常化出口”退出,说明x不是质数

        // 如果从“正常化出口”退出,说明x是质数

        if(i<=Math.sqrt(x)){

        console.log(`${x}不是质数`);

        }else{

        console.log(`${x}是质数`);

        }

       }

(4)上述代码是否能够判断出2357是否为质数?

        答案:能。当被判断的数x取值为2时,for循环的循环变量i取值为2时立刻不成立,即直接从

正常化出口退出循环,所以可以判断出x是质数。  
    (5)程序代码2:

        function isPrime(){

            let x=document.querySelector("input[type=text]").value;

            let i=2;

            for(;i<=Math.sqrt(x);i++){

            if(x%i!=0){

            continue; // 停止此次循环,继续执行下一次循环

              }else{

            break; // 停止循环,继续执行循环后面的语句,只能用于循环和switch中

          }

    }

        if(i<Math.sqrt(x)){

          console.log(`${x}不是质数`);

        }else{

          console.log(`${x}是质数`);

        }

    }

do-while 循环:

 1、语法格式:

do{

  // 循环体;

}while(条件);

 2、执行流程:当条件成立时,执行循环体。

 3、while循环和do-while循环的区别:

(1)while循环被称为“前测试当型循环”,循环体可能一次都不执行。

(2)do-while循环被称为“后测试当型循环”,循环体至少执行一次。

 4、当型循环和计数循环的区别:

(1)当型循环(while)适合实现不知道循环次数的循环。

     不知道循环次数的循环最好不要使用计数循环(for)来实现。

(2)计数循环(for)适合实现已知循环次数的循环。

     已知循环次数的循环也可以使用当型循环(while)来实现。

循环嵌套

案例:计算1-10的阶乘和(1!+2!+3!+4!+5!+6!+7!+8!+9!+10!=?)。

分析:计算求和需要使用循环(1-10),其中每次计算阶乘也得是循环(1-x)。

结论:外层循环控制求和;内层循环控制求阶乘。

方法一:使用循环嵌套实现。

let sum=0; // 用于统计最终的求和结果

for(let i=1;i<=10;i++){

let fact=1;// ② 用于计算i的阶乘

for(let j=1;j<=i;j++){

fact=fact*j;

}

sum=sum+fact;

}

console.log(`1-10的阶乘和=${sum}`);

思考:将②放在以i为循环变量的for循环以外是否可行?不可以。

方法二:使用单个for循环实现。

        1!=1

        2!=1×2 = 12

        3!=1×2×3 = 23

        4!=1×2×3×4 = 34

        ……

        n! = n(n-1)!

        let sum=0,fact=1;

for(let i=1;i<=10;i++){

fact=fact*i;

sum=sum+fact;

}