JS高级程序设计第3章--精简版

前言:纯手打!!!按照自己思路重写!!!这次是二刷了,想暑假做一次完整的笔记,但用本子来写笔记的话太贵了,可能哪天还丢了。。所以还是博客好==


 第三章:基本概念(语法、数据类型、流控制语句、函数)


3.1 语法:

  ECMAScript的语法大量借鉴了C及其他语言。

3.1.1 区分大小写

3.1.2 标识符:

  指的是变量、函数、属性的名字、函数的参数。注意:首字符必须是一个字母、下划线、或者美元$符号。

  ES标识符采用驼峰大小写格式(首字母小写,其他单词的首字母大写,如:setData),不可以把关键字、保留字、true、false、null作为标识符。

3.1.3 注释:

  单行注释: //

  块级注释: /* *内容 */

3.1.4 严格模式:对某些不安全的操作抛出错误

  在脚本中启动严格模式,可以在其顶部写一行代码:"use strict"

3.1.5 语句:

  以分号结尾,其实也可以不写,但最好写。。。

3.2 关键字和保留字:(这些都不可以作为标识符)

  关键字大致为:  break、else、new、var、 case、  finally 、 return、 void 、 catch  、for  、switch 、 while 、 continue、  function  、this 、 with 、default 、 if 、 throw 、 delete 、 in 、  try 、do 、 instranceof、  typeof。。。

  保留字大致位: abstract 、 enum   、int 、 short 、 boolean  、export  、interface、  static、  byte  、extends 、 long 、 super 、 char 、 final  、native  、synchronized 、 class  、float 、 package  、throws 、 const  、goto  、private 、transient 、 debugger 、 implements  、protected 、 volatile 、 double  、import  、public、class、entends、super、const、export、import、let、public。。。、

3.3 变量:

  • var message;   即定义一个变量,该变量成为该变量作用域中的局部变量,此变量未初始化,会保存一个值----undefined、
  • var message = "hi";
  • message = "hi";   全局变量

3.4 数据类型:

  • 五种简单数据类型(即基本数据类型):Undefined、Null、Boolean、Number、String
  • 一种复杂数据类型:Object

3.4.1 typeof操作符:

  检测给定变量的数据类型——typeof

  • “undefined”——如果这个值未定义;
  • “boolean”——如果这个值是布尔值;
  • “string"——如果这个值是字符串;
  • ”number“——如果这个值是数值;
  • ”object”——如果这个值是对象或者null;
  • “function"——如果这个值是函数!!!虽然函数是对象,但可以通过typeof区分是不是函数。

  如:var message = "some string";

    alert(type of message);  //"string"

    alert(type of null);  //”object"

3.4.2 Underfined类型:

      var message; var message1 = undefined; var age

   alert(message == undefined);  //true

   alert(message);  //undefined

      alert(age);  //产生错误

      alert(message1 == underfined);  //true

3.4.3 Null类型:

   null值表示一个空对象指针,所以用typeof检测会返回“object”。

   var car = null;

   alert(typeof car);  //"object"

   !!!注意 undefined值是派生自null值的,所以 alert(null == undefined);  //true

3.4.4 Boolean类型:

  该类型只有两个字面值:true和false。

数据类型

转换为true的值

转换为false的值

Boolean

true

false

String

任何非空字符串

" "(空字符串)

Number

任何非0数字值(包括无穷大)

0和NaN

Object

任何对象

null

Undefined

n/a(不适用)

undefined

  这些转换规则对理解流控制语句(如if语句)自动执行相应的Boolean转换非常重要:

  var mesage = "Hello World";

  if (message) {  // 这个message自动转换了对应的Boolean值——ture

    alert("Value is true");

  }

3.4.5 Number类型:

  数值字面量格式:(在进行算术计算时,所有八进制和十六进制表示的数值最终都将被转换成十进制数值)

  • 十进制整数:var intNum = 55;
  • 八进制:(严格模式下无效)第一位是0,然后是八进制数字序列(0~7),若超过7,则第一位的0被忽略,

   后面的数值被当作十进制来看,var octalNum1 = 070;  //八进制的56          var octalNum2 = 079;  //无效的八进制,解析为79

  • 十六进制:前2位必须是0x,后跟任何十六进制数字(0~9及A~F 字母可大小写)
  浮点数值: 简单的不说,说说 var floatNum = 3.125e7;  //等于31250000,即3.125乘以10的七次方。
  0.1 + 0.2 结果不是0.3,而是0.30000000000000004,所以在进行算术计算时其精确度远远不如整数,所以最好不要做以下测试:
  if (a + b == 0.3) {
    alert ("You got 0.3" );
  }
  
  数值范围:有规定最大最小值,若超出,则转换成负无穷(-Infinity),正无穷(Infinity)。
  
  NaN:即非数值,它是一个特殊的数值。表示一个本来要返回数值的操作数未返回数值的情况(这样子就不会抛出错误)
     任何涉及NaN的操作都会返回NaN,NaN与任何值都不相等,包括NaN本身。 alert (NaN == NaN);  //false
     !!!所以ES定义了 isNaN() 函数,这个函数接受一个任何类型的参数,函数可以帮我们确定这个参数是否“不是数值”,某些不是数值的值会被自动直接地转换为数值。
     alert (isNaN(NaN));  //true,表示这个不是数值
     alert (isNaN(10));  //false,表示10是数值
        alert (isNaN(“10”));  //false,表示可以被转换成数值10
     alert (isNaN(“blue"));  //true,表示这个不能转换成数值
     alert (isNaN(true));  //false,表示可以转换成数值1
 
  数值转换:有三个函数可以把非数值转换成数值
 

  Number() 可以用于任何数据类型,转型函数将其转换为数值。

    • var num1 = Number(”Hello Wordl“);  //NaN,即字符串中若包含除了数字的字符,则将其转换为NaN
    • var num2 = Number(” “);        //0
    • var num3 = Number(”000011“);        //11,前面的0被忽略
    • var num4 = Number(true);   //1
    • var num5 = Number(null);  //0
    • var num6 = Number(undefined);  //NaN
    • 如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。若转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串。

  parseInt():处理整数的时候常用:

    • var num1 = parseInt(”1234blue“);  //1234,忽略blue
    • var num2 = parseInt(” “);        //NaN,和Number()不同,因为parseInt()会拼命找第一个非空格字符。
    • var num3 = parseInt(”0xA“, 16);        //10(十六进制数转十进制)
    • var num4 = parseInt(22.5);   //22
    • var num5 = parseInt(”070“ ,8);  //56(八进制数转十进制)
    • var num6 = parseInt(”70“ ,10);  //70

  parseFloat() :与parseInt()的相似与区别是  都是从第一个字符开始解析,只认识一个小数点,会忽略一开始的0,只识别十进制,而十六进制的字符串会被转换为0

    • var num1 = parseFloat(”1234blue“);  //1234
    • var num2 = parseFloat(”0xA“);  //0,不认识十六进制~
    • var num3 = parseFloat(”22.4.33“);  //22.4
    • var num4 = parseFloat(”0202.4“);  //202.4
    • var num5 = parseFloat(”3.125e7“);  //31250000

 

3.4.6 string类型:即字符串

  可以由双引号和单引号表示。

  • String数据类型包含一些特殊的字符字面量(转义序列),用于表示非打印字符。常用的有:

  \n 表示换行,\t 表示制表,\b表示退格,\r表示回车,\\表示斜杠,\'表示单引号,\"表示双引号,\xnn表示以十六机制代码nn表示的一个字符(n为0~F),\unnnn表示以十六进制代码nnnn表示的一个Unicode字符(n为0~F)。

  !!!注意,n个字符长的转移序列只表示一个字符(在length里表示1)

  • 将一个值转换为字符串:有两种方法
    • toString()方法:返回相应值的字符串表现,相应值可以是数值、布尔值、对象和字符串值(返回字符串的一个副本)!但null和undefined值没有这个方法。

        可传参也可以不传参,参数表示以n进制格式(基数)返回数值,默认不填为十进制。

      var num = 10;

      alert (num.toString());  // "10"

      alert (num.toString(2));  // "1010"

      alert (num.toString(8));  // "12"

      alert (num.toString(10));  // "10"

      alert (num.toString(16));  // "a"

    • String()转型函数:在不知道要转换的值是不是null或undefined时可以使用。这个函数可以将任何类型的值转换为字符串!
      • 如果值有toString() 方法,则调用该方法并返回相应的结果。
      • var value1 = true;  alert(String(value1));  // “true" ,一个副本
      • var value2 = null;   alert(String(value2));  // "null" ,因为null没有toString()方法所以String()函数就返回了这个值的字面量"null"。
      • var value3;  alert(String(value3));  // ”undefined“ ,因为undefined没有toString()方法所以String()函数就返回了这个值的字面量”undefined“。

3.4.7 Object类型:就是对象!即一组数据和功能的集合。

  对象可以通过执行new操作符后跟要创建的对象类型的名称来创建,即 var o = new Object (); 如果不用给构造函数传参,也可以这么写:var o = new Object;但不推荐。

  关于Object的每个实例的具体属性和方法,第五、六章再讨论。

3.5 操作符:

  是用于操作数据值的操作符,包括算术操作符、位操作符、关系操作符、相等操作符。

3.5.1 一元操作符:

  • 前置操作符: var age = 29; ++age;  age变量的值都是在语句被求值以前改变的。
  • 后置操作符: var price = 29; price++;  price变量的值都是在包含它们的语句被求值之后才执行的。
  • 以上的意思可以从这段代码看出:

   var num1 = 2;  var num2 = 20;  var num3 = num1-- + num2;  //等于22,因为是后置,所以在var num3语句里它不改变先,等到这条语句被求值之后才改变  var num4 = num1 + num2 ;  //等于21,num1=1。

  • 加减前后置操作符不仅可以应用在整数上,还可以应用在字符串、布尔值、浮动数值和对象上哦!!!
    • var s1 = "2";  s1++;  // 3,包含有效数字字符的字符串先转换为数字值,再执行加减的操作,然后字符串变量变成数值变量。
    • var s2 = "x",  s2++;  // NaN,因为不包含数字,不过字符串变量还是会变成数值变量NaN;应用一元操作符都会变成NaN!!!
    • var b = false;  b++;  // 1,布尔值变成0或1,再执行加减1的操作,然后布尔值变量变成数值变量。
    • var f = 1.1;        f--;  //0.10000000000000009
    • var o = {         ;  o--;    //-2

        valueOf : function () {

            return -1;

        }

      }

  • 一元减操作符(-):主要用于表示负数

3.5.2 位操作符:本小节暂不讲解。。。。。。。

3.5.3 布尔操作符:

  • 逻辑非(!):短路操作符。应用于任何值,返回一个布尔值。生动的说就是:alert(!”我是好人“)   //false,返回一个坏人,因为有!存在。
    • alert(!false);  // true
    • alert(!"blue");  // false
    • alert(!0);    // true
    • alert(!NaN);  // true
    • alert(!" ");   // true
    • alert(!12345); //false

   若使用两个!那就是反过来咯。

  • 逻辑与(&&):全true则true。应用于任何类型的操作数,不仅仅是布尔值,但不可以在&&操作中使用未定义的值,不然会导致错误,不返回值。遵循以下规则:

   若第一个操作数能决定结果了,那第二个就无视。即第一个是false,那就不看第二个了。若第一个是true,那还是会去看第二个(第二个不可以使用未定义的值)。

   若两个操作数都是对象,则返回第二个操作数;若第一个操作数是null,则返回null;若第一个操作数是NaN,则返回NaN;若第一个操作数是undefined,则返回undefined;

第一个操作数

第二个操作数

结果

true

true

true

true

false

false

false

true

false

false

false

false

 

  • 逻辑或(||):有true则true,和逻辑与一样,不可以使用未定义的值

   若第一个操作数能决定结果了,那第二个就无视。即第一个是true,那就不看第二个了。若第一个是false,那还是会去看第二个(第二个不可以使用未定义的值)。

   若两个操作数都是对象,则返回第一个操作数;若两个操作数都是null,则返回null;若两个操作数都是NaN,则返回NaN;若两个操作数都是undefined,则返回undefined;

第一个操作数

第二个操作数

结果

true

true

true

true

false

true

false

true

true

false

false

false

3.5.4 乘性操作符:乘法、除法和求模,会自动把非数值的操作符转换位数值(即自动用Number()转换)

  • 乘法要注意的是: 结果超出ES数值表示范围,则返回Infinity或-Infinity;若有某一个操作数是NaN,那结果就是NaN;操作数是Infinity,那结果也是Infinity;Infinity乘以0等于NaN。
  • 除法要注意的是: 结果超出ES数值表示范围,则返回Infinity或-Infinity;若有某一个操作数是NaN,那结果就是NaN;操作数是Infinity,那结果也是Infinity;Infinity除以Infinity等于NaN;0除以0等于NaN。
  • 求模(%)主要需要注意的是:Infinity除以Infinity等于NaN;被除数是0,结果就是0。

3.5.5 加性操作符:加法、减法

  • 加法要注意的是:若有一个操作数是NaN,结果就是NaN;+0加+0等于+0;-0加-0等于-0;+0加-0等于+0;

   !!!最重要的来了,如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来;如果只有一个操作数是字符串,则将另外一个操作数转换为字符串,再将第二个操作数与第一个操作数拼接起来。

   如果有一个操作符是对象、数组或布尔值,则调用它们的toString() 方法取得相应的字符串值;对于undefined和null,则分别调用String()函数并取得”undefined“和”null“。

   例题:var num1 = 5;  var num2 = 10;  var message = "The sum of 5 and 10 is" + num1 + num2;  alert(message);  //"The sum of 5 and 10 is 510" ;

      var num1 = 5;  var num2 = 10;  var message = "The sum of 5 and 10 is" + (num1 + num2);  alert(message);  //"The sum of 5 and 10 is 15" ;

      var result1 = 2 + true;  // 3,因为true被Number()函数转换成1

  •  减法要注意的是:若有一个操作数是NaN,结果就是NaN;+0减+0等于+0;-0减-0等于+0;+0加-0等于-0;

   !!!最重要的来了,它和加法不一样,不拿来拼接什么鬼字符串。

   !!! (主要是使用了Number()函数)

   例题:var result1 = 5 - true;  //4

      var result2 = NaN - 1;  //NaN

      var result3 = 5 - 3;  //2

      var result4 = 5 - " ";  //5

      var result5 = 5 - ”2“;  //3

      var result6 = 5 - null;  //5

3.5.6 关系操作符:大于、小于、小于等于、大于等于:

  相应规则:

  • 若两个操作数都是数组,则执行数值比较。
  • 若两个操作数都是字符串,则比较两个字符串对应的字符编码值。
  • 若有一个操作数是数值,则将另外一个操作数转换为一个数值,然后执行数值比较。
  • 若有一个操作数是对象,则调用这个对象的valueOf()方法再比较,若没有此方法,则调用toString()方法,再比较。
  • 若一个操作数是布尔值,则先将其转换为数值然后再比较。
  • 任何数和NaN比较,结果都是false。

  例题:var result = "a" < 3;  //false,字符串a不能被转换成合理的数值,所以”a"被转换成NaN

     var result1 = "23" < "3";  //true,比较的是字符编码

     var result2 = "23" < 3;  //false,因为”23“变成了23

3.5.7 相等操作符:==、!= ,===、!== :

  • 相等与不相等:==、!=
    • 相等:相等和不相等是先强制转型再比较它们的相等性
      • 若两个操作数相等则返回true,不相等则返回false;
    • 不相等:
      • 若两个操作数相等则返回false,不相等则返回true;
    • 基本规则:
      • 若有布尔值,则先转换为数值,false=0,true=1;
      • 若有一个是字符串,另一个是数值,则先把字符串转换为数值;
      • 若有一个是对象,另一个不是,则调用对象的valueOf()方法,用得到的基本类型值再进行比较;
      • null == undefined(相等)
      • 若有一个是NaN,则相等操作符返回false,不相等操作符返回true;即使有两个都是NaN都一样,因为NaN不等于NaN;
      • 若两个都是对象,则比较它们是不是都指向同一对象,是则 相等操作符返回true,否则返回false;
      • null == 0 ,undefined == 0 //false,因为null和undefined在做相等判断时不进行转型,所以null、undefined和0是不同类型数据,所以返回false;

表达式

null == undefined、false == 0、NaN != NaN、”5“ == 5、true == 1

true

”NaN“ == NaN、5 == NaN、NaN == NaN、null == 0、undefined == 0

false

  • 全等和不全等:===、!==
    • 比较前不转换,所以比较的时候看数据类型相不相等
    • 其他规则和相等不相等一样~~

 3.5.8 条件操作符:?:  variable = boolean_expression ? true_value : false_value;

               基于对boolean_expression求值的结果,决定给变量赋什么值。如果求职结果为true,则将true_value的值赋给变量variable,反之。

             例题:var max = (num1 > num2) ? num1 : num2;  若num1=3,num2=2,则将num1的值赋给max。

3.5.9 赋值操作符: =  即把右侧的值赋给左侧的变量。  例题:var num = 10;

  • 复合赋值操作符: 仅仅只是为了简化操作,不会提示性能什么的。。。
    • 乘/赋值 (*=);  num  = num + 10 和 num += 10一样
    • 除/赋值 (/=);
    • 模/赋值 (%=);
    • 加/赋值 (+=);
    • 减/赋值 (-=);
    • 左移/赋值 (<<=);
    • 有符号右移/赋值 (>>=);
    • 无符号右移/赋值 (>>>=);

3.5.10 逗号操作符: ,  

  • 使用逗号操作符可以在一条语句中执行多个操作,多用于声明多个变量。 例题:varn num1 = 1, num2 = 2,num3 = 3;
  • 逗号操作符还可以用于赋值,总会返回表达式中的最后一项。例题:var num = (5, 1, 4, 8, 0);  //num值为0

3.6 语句:流控制语句

3.6.1 if语句:

  语法:if (condition) { statement1 } else { statement2 }  condition是任意表达式,表达式求值的结果不一定是布尔值,ES会自动调用Boolean()转换函数将这个表达式的结果转换为一个布尔值。

     如果对condition求值的结果是true,则执行语句1:statement1;反之。

     还可以:if (condition1) { statement1 } else if (condition2) { statement2 } esle {statement3}

3.6.2 do-while语句:

   语法:do { 

        statement

       } while (expression);

     do-while是一种后测试循环语句,在对条件表达式expression求值之前,循环体内的代码statement至少会被执行一次。

3.6.3 while语句:

  语法: while (expression) statement

      while是一种前测试循环语句,在循环体内的代码statement被执行之前,会先对条件表达式expression求值。

3.6.4 for语句:

  语法: for (initialization; expression; post-loop-expression) statement

      for是一种前测试循环语句,但它具有在执行循环之前初始化变量和定义循环后要执行的代码的能力。

     只有当条件表达式expression返回true的情况下才会进入for循环;如果执行了循环体中的代码statement,则一定会对循环后的表达式post-loop-expression求值(这段话有时在笔试题里会考题目)

     !!!由于ES中不存在块级作用域(let可以),所以在循环内部定义的变量也可以在外部访问到。

     例题:var count = 10;

        for (var i = 0; i < count; i++) {

          alert ( i );

        }  //9

        alert ( i );  //10,因为在循环内部定义的变量也可以在外部访问到。

3.6.5 for-in语句:

  是一种精准的迭代语句,可以用来枚举对象的属性。

  语法:for (property in expression) statement  ,在使用for-in前先检测确定该对象的值不是null或undefined,否则循环不执行。

  例题:for (var propName in window) {  console.log(propName)  }  //循环输出很多BOM中window对象的所有属性。

3.6.6 lable语句:

  语法:label : statement 

  例题:state : for (var i = 0; i < count; i++) {

      alert ( i );

     }

  这个state标签可以在将来由break或continue语句引用,加标签的语句一般都要与for语句等循环语句配合使用。

3.6.7 break和continue语句:

  这两个语句用于在循环中精确地控制代码的执行。

  • break语句会立即退出循环,强制继续执行循环以后的语句。
  • continue语句也是会立即退出循环,但退出循环后会从循环的顶部继续执行。

  例题:var num = 0;

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

      if (i % 5 == 0) {

        break;

      }

      num++;

     }

     alert( num );  //4,当i为5时,break了,不再执行循环里的代码(即num++),直接去执行alert( num )

  ————————————————————————

     var num = 0;

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

      if (i % 5 == 0) {

        continue;

      }

      num++;

     }

     alert( num );  //8,当i为5时,continue了,不再执行循环里的代码(即num++),而是直接去执行下一次循环(即i = 6)

  ————————————————————————

 

     var num = 0;

     outermost :  //一个标签,表示外部的for语句。

     for (var i = 0; i < 10; i++) {

       for (var j = 0; j< 10; j++) {

        if (i == 5 && j == 5) {

          break outermost ;  //要返回到outermost标签,这时候num等于55

        }

         num++;

        }

     }

     alert( num );  //55,当i、j为5时,break了,不仅会退出内部循环的for语句,而且会退出外部循环的for语句,所以num的值正好等于55.

  ————————————————————————

     var num = 0;

     outermost :  //一个标签,表示外部的for语句。

     for (var i = 0; i < 10; i++) {

       for (var j = 0; j< 10; j++) {

        if (i == 5 && j == 5) {

          continue outermost ;  //continue语句会强制继续执行循环——退出内部循环,执行外部循环。所以这里少了内循环五次。

        }

         num++;

        }

     }

     alert( num );  //95,内部循环少执行了5次。

3.6.8 with语句:

  作用时将代码的作用域设置到一个特定的对象中,简化多次编写同一对象的工作。

  语法:with (expression) statement;

  例题:var qs = location.search.substring(1);

     var url = location.href;

     以上代码可以简写为:使用with语句关联了location对象,在with语句的代码块内部,每个变量首先被认为是一个局部变量,而如果在局部环境中找不到该变量的定义,就会查询location对象中是否有同名的属性。

     with(location) {

      var qs = substring(1);

      var url = href;

     }

3.6.9 switch语句:

  语法:switch (expression) {  // expression = value

      case value : statement

        break;

      case value : statement

        break;

      case value : statement

        break;

      default : statement

     }

  比较:在比较值的时候使用的是全等操作符,所以不会发生类型转换。

  case的含义是:如果表达式等于value,则执行后面的语句statement。而break关键字会导致代码执行流跳出switch语句;若省略break,则会导致执行完当前case后继续执行下一个case。最好的default关键字用于在表达式不匹配任何情形时,执行机动代码。

  混合:若需要混合多种情形,则不写某个case的statement和break,这个case就会和下一个case混合。

3.7 函数:

  语法:function functionName (arg0, arg1, ....., argN) {

      statements

     }

  调用:通过其函数名来调用,后面还要加上园括号和参数 。

  返回值:可以在函数体里通过return语句后跟要返回的值来实现返回值。且位于return语句后的下一句代码不会执行。(比如alert那些,但如果时else那些还是正常判断来执行)。

      return语句也可以不带有任何返回值,函数在停止执行后将返回undefined值,这种用法一般用于需要提前停止函数执行而又不需要返回值的情况下。

3.7.1 理解参数:

  ES函数不介意传递进来几个参数,也不在乎是什么数据类型。因为ES中的参数在内部可以用一个数组来表示,所以在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。

  例题:function sayHi (name, message) {

      alert("Hello " + name + "," + message);

     }

     以上代码可以写成:

     function sayHi() {

      alert("Hello " + arguments[0] + "," + arguments[1] );

  参数数量:通过访问arguments对象的length属性可以获知有多少个参数传递给函数。

      console.log(arguments.length);  //2

  undefined:没有传递值的命名参数将自动赋予undefined值。

3.7.2 没有重载:

  若2个函数名字的名字都一样,那该名字只属于后定义的函数。

 

posted @ 2019-07-12 03:20  X1aoYE  阅读(360)  评论(0编辑  收藏  举报