美文网首页
《JavaScript高级程序设计》读书笔记-第三章(基本概念)

《JavaScript高级程序设计》读书笔记-第三章(基本概念)

作者: 极奏 | 来源:发表于2019-06-15 23:23 被阅读0次

    变量

    • ECMAScript的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。
    • 每个变量仅仅是用于保存值的占位符。
    • 不建议变量所保存值的类型,但这种操作在ECMAScript中完全有效
    • var操作符定义的变量将成为定义该变量的作用域中的局部变量,也就是说,如果在函数中使用var定义一个变量,那么这个变量在函数退出后就会被销毁
    function test(){
      var message = 'hi'
    }
    test()
    alert(message)
    //message is not defined
    
    • 可以使用一条语句定义多个变量,只要像下面这样把每个变量(初始化或不初始化均可)用逗号分开
     var message = 'hi',
         found   = false,
         age     = 29 
    

    在严格模式下,不能定义名为evalarguments的变量,否则会导致语法错误

    typeof操作符

    • typeof操作符可能返回的字符串
      1、'undefined'
      2、'boolean'
      3、'string'
      4、'number'
      5、'object'
      6、'function'

    • 有时候typeof会返回一些令人迷惑但技术上却正确的值。
      比如,调用type of null会返回object,因为null被认为是一个空的对象引用

    Undefined

    • Undefined的类型只有一个值,即特殊的undefined。在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined
    var message
    alert( message == undefined ) //true
    

    等于

    var message = undefined
    alert( message == undefined ) //true
    

    但是我们没必要这么做

    • 但是包含undefined值的变量与尚未定义的变量还是不一样的
    var message
    alert(message) //'undefined'
    alert(age)     //错误
    
    • 对未初始的变量执行typeof操作符会返回undefined值,而对未声明的变量执行typeof操作同样会返回undefined值
    var message
    alert(typeof message ) //'undefined'
    alert(typeof age )     //错误
    

    Null类型

    • Null类型是第二个只有一个值的数据类型,这个特殊的值是null。从逻辑角度来看,null值表示一个空对象指针,而这也正是使用typeof操作符检测null值会返回'object'的原因。
    • 如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他值
    • 实际上,undefined值是派生自null值的,因此ECMA-262规定对 它们的相等性测试要返回true
    alert(null == undefined) //true
    

    null和undefined的用途完全不同,如果保存对象的变量还没有真正保存对象,就应该明确地让该变量保存null值,这样做不仅可以体现null作为空对象指针的惯例,而且也有助于进一步区分null和undefined

    alert(null === undefined) //false
    

    Boolean类型

    • Boolean类型是ECMAScript中使用得最多的一种类型
    • 该类型只有两个值,一个true,一个false
    • true不一定等于1,而false也不一定等于0
    • true 和 false是区分大小写的
    • 要将一个值转换为其对应的Boolean值,可以调用转型函数Boolean()
    var message = 'Hello world!'
    var messageAsBoolean = Boolean(message)
    
    • 下表给出了各种数据类型及其对应的转换规则
    数据类型 转换为true的值 转换为false的值
    Boolean true false
    String 任何非空字符串 ' '(空字符串)
    Number 任何非零数字值 0和NaN
    Object 任何对象 null
    Undefined 不适用 undefined

    Number类型

    • 使用IEEE754格式来表示整数和浮点数值
    • 最基本的数值字面量格式是十进制整数,十进制整数可以像下面这样直接在代码中输入
    var intNum = 55 //整数
    
    • 也可以八进制或者十六进制
    • 八进制字面值的第一位必须是(0),然后是八进制数字序列(0~7),如果超出了范围,那么前导零将被忽略,后面的数值将被当做十进制数值解析
    var octalNum1 = 070 //八进制的56
    var octalNum2 = 079 //无效的八进制数值——解析为79
    var octalNum3 = 08 //无效的八进制数值,解析为8
    

    八进制字面量在严格模式下是无效的,会导致支持的JavaScript引擎抛出错误

    • 十六进制的字面值的前两位必须为0x,后跟任何十六进制数字(0 ~ 9 及 A ~ F),字母A ~ F可以大写,也可以小写。
    var hexNum1 = 0xA //十六进制的10
    var hexNum2 = 0x1f //十六进制的31
    

    浮点数值

    • 所谓浮点数值,就是数值中必须包含一个小数点,并且小数点后面必须至少有一位数字。
    var floatNum1 = 1.1
    var floatNum2 = 0.1
    var floatNum3 = .1
    

    由于保存浮点数值需要的内存空间是保存整数值的两倍,因此ECMAScript会不失时机地将浮点数值转换成整数值

    • 对于那些极大或极小的数值,可以用e表示法(即科学计数法)表示 的浮点数值表示。用e表示法表示的数值等于e前面的数值乘以10的指数次幂
    var floatNum = 3.125e7 //等于31250000
    
    • 浮点数值的最高精度是17位小数,但在进行算术计算是其精确度远远不如整数。

    例如:0.1+0.2的结果不是0.3

    这是使用基于IEEE754数值的浮点计算的通病

    数值范围

    • ECMAScript能够表示的最小数值保存在Number.MIN_VALUE中——在大多数浏览器中,这个值是5e-324
    • 最大值保存在Number.MAX_VALUE中——在大多数浏览器中,这个值是1.7976931348623157e+308
    • 如果某次计算的结果得到一个超出JavaScript数值范围的值,那么这个数值会被自动转换成特殊的Infinity值,分别为正Infinity和负Infinity
    • 想要确定一个数是不是有穷的,可以使用isFinite()函数。这个函数位于最小与最大数值之间时会返回true
    var result = Number.MAX_VALUE+Number.MAX_VALUE
    console.log(isFinite(result)) //false
    

    NaN

    • NaN,即非数值(Not a Number)是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况。
    • 任何涉及NaN的操作都会返回NaN
    • NaN与任何值都不相等,包括NaN本身
    console.log(NaN === NaN) //false
    
    • 针对NaN的这两个特点,ECMAScript定义了isNaN()函数。isNaN在接收到一个值之后,会尝试将这个值转换为数值,而任何不能被转换为数值的值都会导致这个函数返回true

    数值转换

    • 有三个函数可以把非整数转换为数值
      1、Number()
      2、parseInt()
      3、parseFloat()

    • Number()函数的转换规则如下
      1、如果是Boolean值,true和false将分别转换为1和0
      2、如果是数字值,只是简单的传入和返回
      3、如果是null值,返回0
      4、如果是undefined,返回NaN
      5、如果是字符串,则:

      • 如果字符串只包含数字,则将其转换为十进制数值,前导零忽略
      • 如果字符串包含有效的十六进制格式,则将其转换为对应的十进制整数值
      • 如果字符串是空的,则将其转换为0
      • 如果字符串中包含除上述格式之外的字符,则将其转换为NaN

    Sting类型

    • ECMAScript中的字符串是不可变的,也就是说,字符串一旦创建,它们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量
    var lang ='Java'
    lang = lang + 'Script'
    

    实现这个操作的过程如下:
    1、创建一个能容纳10个字符的新字符串
    2、在这个字符串中填充'Java'和'Script'
    3、销毁原来的字符串'Java'和字符串'Script'

    销毁也是某些旧版本的浏览器中拼接字符串时速度很慢的原因所在

    • 转换为字符串
      1、使用toString()
      nullundefined 值没有这个方法
      2、转型函数String(),在不知道要转换的值是不是null或undefined的情况下,可以用这个函数,可以将任何类型的值转换为字符串。
    var value1 = 10
    var value2 = true
    var value3 = null
    var value4
    alert(String(value1))  //'10'
    alert(String(value2))  //'true'
    alert(String(value3))  //'null'
    alert(String(value4))  //'undefined'
    

    Object类型

    • ECMAScript中的对象其实就是一组数据和功能的集合。对象可以通过new操作符后跟要创建的对象类型的名称来创建。
      而创建Objcet类型的实例为其添加属性、方法,就可以创建自定义对象
    var o = new Object()
    

    如果不传参的话,可以省略圆括号,但是不推荐

    var o = new Object  //有效,但是不推荐
    

    Object类型是所有它的实例的基础。换句话说,Object类型所具有的任何数学和方法也同样存在于更具体的对象中

    • Object的每个实例都具有下列属性和方法
      1、Constructor:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor)就是Object()
      2、hasOwnProperty( propertyName ):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在
      3、isPrototypeOf( object ):用于检查传入的对象是否是另一个对象的原型
      4、propertyIsEnumerable( propertyName ):用于检查给定的属性是否能够使用for-in语句来枚举
      5、toLocaleString():返回对象的字符串表示
      6、valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同

    操作符

    一元操作符
    • 递增,递减操作符
    • 前置型和后置型
      前置型
    var age = 29
    ++age
    

    与以下操作的效果相同

    var age = 29
    age = age + 1
    

    递减操作符形式相同

    执行前置递增和递减操作时,变量的值都是在语句被求值以前改变的。(在计算机科学领域,这种情况通常被称作副效应)

    前置递增和递减操作与执行语句的优先级相等,因此整个语句会从左至右被求值

    var num1 = 2
    var num2 = 20
    var num3 = --num1 + num2   //等于21
    var num4 = num1 + num2     //等于21
    

    后置递增和递减操作符,递增和递减操作是在包含他们的语句被求值之后才执行的

    • 他们不仅适用于整数,还可以用于字符串、布尔值、浮点数值和对象。在应用不同的值时,递减和递增操作符遵循下列规则
      1、在应用于一个包含有效数字字符的字符串时,将其转换为数字值,再执行加减1的操作。字符串变量变成数值变量
      2、在应用于一个不包含有效数字字符的字符串时,将变量的值设置为NaN,字符串变量变成数值变量
      3、在应用于布尔值是,先将其转换为0或1在执行加减1的操作。布尔变量变成数值变量
      4、在应用于对象时,先调用对象的valueOf()方法以取得一个可供操作的值。如果结果是NaN,则在调用toString()方法后再应用前述规则。对象变量变成数值变量
    位操作符
    • 位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。ECMAScript中的所有数值都以IEEE-75464位格式存储,但位操作符并不直接操作64位的值。而是先将64位转换为32位的整数,然后执行操作,最后再将结果转换回64位。对于开发人员来说,由于64位存储格式是透明的,因此整个过程就像是只存在32位的整数一样。在转换过程中也导致了一个严重的副效应,即在对特殊的NaN和Infinity值应用位操作时,这两个值都会被当成0来处理

    • 负数同样以二进制码存储,但使用的格式是二进制补码。计算一个数值的二进制补码,需要经过下列3个步骤:
      1、求这个数值绝对值的二进制码
      2、求二进制反码,即将0替换为1,将1替换为0
      3、得到的二进制反码加1

    ECMAScript会尽力向我们隐藏所有这些信息,如下面代码所示

    var num = -18              //1111 1111 1111 1111 1111 1111 1110 1110
    alert(num.toString(2))     //'-10010'
    
    按位非(NOT)
    • 按位非操作由一个波浪线(~)表示,执行按位非的结果就是返回数值的反码。按位非是ECMAScript操作符中少数几个与二进制有关的操作符之一
    var num1 = 25
    var num2 = ~num1
    alert(num2)       //-26
    
    按位与(AND)
    • 按位与操作符由一个和号字符(&)表示,同样也有两个操作数。
    • 简而言之,按位与操作只在两个数值的对应位都是1时才返回1,任何一位是0,结果都是0
    var result = 25 & 3
    alert(result)  //1
    
    按位或(OR)
    • 按位或操作符由一个竖线符号(|)表示,同样也有两个操作数。
    • 按位或操作在有一个位是1的情况下就返回1,而只在两个位都是0的情况下才返回0
    var result = 25 | 3
    alert(result)    //27
    
    按位异或(XOR)
    • 按位异或操作符由一个插入符号(^)表示,也有两个操作数
    • 这个操作在两个数值对应位上只有一个1时才返回1,如果对应的两位都是1或都是0,则返回0
    var result = 25 ^ 3
    alert(result)  //26
    
    左移
    • 左移操作符由两个小于号(<<)表示,这个操作符会将数值的所有位向左移动指定的位数。
    var oldValue = 2                  //等于二进制的10
    var newValue = oldValue << 5     //等于二进制的1000000,十进制的64
    

    在向左移动后,原数值的右侧多出了5个空位。左移操作会以0来填充这些空位,以便得到的结果是一个完整的32位二进制数

    无符号的右移
    var oldValue = 64
    var newValue = oldValue >>> 5
    
    • 无符号的右移跟左侧同理,但是对负数来说,情况就很不一样了。首先,无符号右移是以0来填充空位,而不是像有符号右移那样以符号位的值来填充空位。
    • 无符号右移操作会把这个二进制码当成正数的二进制码。
    有符号的右移

    保留符号位

    var oldValue = 64
    var newValue = oldValue >> 5
    
    布尔操作符

    布尔操作符一共有3个:非(NOT)、与(AND)和或(OR)

    • 逻辑非(!)
      同时使用两个逻辑非操作符,实际上就会模拟Boolean()转型函数的行为
    • 逻辑与(&&)
    var result = true && false
    

    他遵循下列规则:

    第一个操作数 第二个操作数 结果
    对象 - 第二个操作数
    true 对象 第二个操作数
    false 对象 -
    对象 对象 第二个操作数

    如果一个操作数是null、NaN、undefined则返回null、NaN、undefined

    不能在逻辑与操作中使用未定义的值。

    var found = true
    var result = (found && someUndefinedVariable)   //发生错误
    alert(result)                                  //不会执行
    
    逻辑或( || )

    遵循的规则与逻辑与相似
    如果两个操作数都是null、NaN、undefined则返回null、NaN、undefined

    var found = false                               //false
    var result = (found || someUndeFinedVariable)  //会发生错误
    alert(result)                                 //不会执行
    
    乘性操作符
    乘法

    如果参加乘法计算的某个操作数不是数值,后台会先使用Number()转型函数将其转换为数值

    var result = 34 * 56
    

    在处理特殊值的情况下:
    1、如果有一个操作数是NaN,则结果是NaN
    2、如果是Infinity与0相乘,则结果是NaN
    3、如果Infinity与非0数值相乘,则结果是Infinity或-Infinity
    4、如果不是数值,则在后台调用Number()将其转换为数值

    除法
    var result = 66 / 11
    

    在处理特殊值的情况下:
    1、如果有一个操作数是NaN,则结果是NaN
    2、如果有一个操作数是NaN,则结果是NaN
    3、如果是Infinity被Infinity除,则结果是NaN
    4、如果零被零除,则结果是NaN
    5、如果是非零的有限数被零除,则结果是Infinity或-infinity
    6、如果不是数值,则在后台调用Number()将其转换为数值

    相等操作符

    ECMAScript的解决方案就是提供两组操作符:
    相等和不相等

    • 强制转型
    • null 和 undefined 是相等的
    • NaN跟任何值都不相等,包括NaN

    全等和不全等

    for-in循环

    • ECMAScript对象的属性没有顺序。因此,通过for-in循环输出的属性名是不可预测的。具体来讲,所有属性都会被返回一次。
    • 但是,如果表示要迭代的对象的变量值为 nullundefined,for-in语句会抛出错误
      ES5更正了这一行为:对这种情况不再抛出错误,而只是不执行循环体

    函数

    • ECMAScript中的参数在内部是用一个数组表示的
    • 在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数
    function sayHi(name, message){
      alert('Hello' + name + ',' + message)
    }
    

    与下面的函数相等

    function sayHi(){
      alert('Hello' + arguments[0] + ',' + arguments[1])
    }
    
    • 命名的参数只提供便利,但不是必需的
    • arguments对象的长度是由传入的参数个数决定的,不是由定义函数时的命名参数的个数决定的
    没有重载
    • 不能像传统意义上那样实现重载。而在其他语言中,可以为一个函数编写两个定义,只要这两个定义的签名不同即可
    • ECMAScript函数没有签名,因为其参数是包含零或者多个值的数组来表示的
    • 如果定义了两个名字相同的函数,则该名字只属于后定义的函数

    相关文章

      网友评论

          本文标题:《JavaScript高级程序设计》读书笔记-第三章(基本概念)

          本文链接:https://www.haomeiwen.com/subject/jghmfctx.html