JavaScript读书笔记02

基本概念

标识符

所谓的标识符就是变量、函数、属性或者函数的名字,需要遵守以下规则:

  1. 第一个字符必须是字母,下划线(_),或者美元符号($)
  2. 其他字符可以是字母,下划线,美元符号或者数字

JavaScript中的一切都对大小写敏感,按照惯例,一般采用驼峰大小写的格式,也就是第一个字母小写,剩下的每个单词的首字母大写:

firstSecond, myCar, doSomeThing

注释

  • 单行注释

    //单行注释

  • 多行注释

    /*
    * 这是一个多行注释
    * 也叫块级注释
    * <-当然,这些星号不是必须的,这里只是为了提高可读性
    */

严格模式

ECMAScript5引入了严格模式(strict mode), 在严格模式下,ECMAScript3中的一些不确定的行为将得到处理,而且对某些对象不安全的操作也会抛出错误。要在整个脚本中启动严格模式只需要在顶部添加如下代码:

"use strict";

这个就是一个字符串,告诉编译器切换到严格模式,当然也可以在单个的函数中定义严格模式:

function doSomeThing(){
"use strict";
//函数体
}

语句

ECMAScript中语句以分号结尾,但是可以省略,由解析器来确定语句的结尾。推荐任何时候都不要省略分号, 一是可以让意图更加明显,避免很多错误;二是可以放心的删除多余的空格来压缩代码;三是可以提高性能,不用编译器花时间去推测断句。

变量

ECMAScript中的变量采用松散类型,就是变量可以用来保存任何类型的数据。定义变量用关键词var,后面接上变量名:

var message;

定义了一个名叫message的变量,它可以用来保存任何类型的值(但这里未经过初始化的变量将会保存着一个特殊的值——undefined)。当然也可以在定义变量的同时设定变量的值:

var message = "hello world";

所谓的变量就是可以改变的量,所以你可以去改变变量保存的值,甚至,你可以修改变量的类型:

message = 123;	//有效,但是不推荐这样做

其实不用关键词var也可以定义变量,直接省略var即可,区别在于用var定义的变量是该变量作用域中的局部变量,而省略掉之后成为了全局变量:

function test1(){
var message1 = "hello world"; //局部变量
}
test1();
alert(message1); //错误

function test2(){
message2 = "hello world"; //全局变量
}
test2(); //调用一次test2之后message2就有了定义,可以一直访问
alert(message2); //“hello world”

数据类型

EXMAScript中有5种简单数据类型:Undeifined, Null, Boolean, Number和String;

还有一种复杂数据类型——Object,Object本质上是由一组无序的键值对组成的。

typeof操作符

由于变量是松散的,所以需要一定的手段来检测给定变量的数据类型,这就是typeof负责的。对一个值使用typeof,返回的结果是可能是下列的某一个字符串:

  • "undefined":这个值未定义;
  • boolean:这个值是布尔值;
  • string:这个值是字符串;
  • number:这个值是数值;
  • object:这个值是对象或者null
  • function:这个值是函数

typeof是一个操作符而不是一个函数,所以可以使用圆括号,也可以不使用:

typeof("hello world");			//"string"
typeof 98;				//"number"

这里比较令人迷惑的是,null虽然是Null类型的一个值,但是typeof null返回的却是“Object”而不是“Null”,因为特殊值null被认为是对空对象的引用。

Undefined类型

Undefined类型只有一个值,就是undefined,在使用var定义变量但未对其进行初始化的时候,这个变量的值就是undeifined。

未定义的变量&&未初始化的变量


var message;
//var age;

alert(message); //"undefined"
alert(age); //产生错误

alert(typeof message); //"undefined"
alert(typeof age); //"undefined"

对于未定义的变量只能执行一项操作,就是使用typeof检测类型,其他的操作会产生错误。然后typeof变量不能区分开这两种变量,因为虽然这两种变量从技术角度上讲有本质的区别,但是无论哪种变量,都是不可能执行真正操作的,都归类为"undefined"

Null类型

Null类型也只有一个值,这个就是null。从逻辑角度上讲,null值表示一个空对象的指针,这也是typeof返回"Object"的原因。

如果定义的变量是准备在将来用来保存对象的,那么最好就可以把变量初始化为null。这样一来只需要去检查null值就知道相应的变量是否已经保存了一个对象的引用。

实际上undeifined值是派生自null的,所以ECMA-262规定对他们的相等性测试要返回true:

alert(undeifined == null);		//true

**==相等操作符会为了比较的目的,会对操作数进行转换,后面会详细介绍

尽管nullundefined有这样的关系,但是他们的用途是完全不一样的。

  • 在任何情况下,都没有必要把变量初始化成undefined
  • 但只要是意在保存变量却还没有真正保存对象时,应该明确的让对象保存null

Boolean类型

Boolean类型是使用的最多的一种类型,该类型有两个字面值:truefalse。虽然字面值只有两个,但是ECMAScript中所有的类型的值都有与这两个值等价的值,要将一个值转换为等价的Boolean值只需要调用转型函数Boolean(),转换规则如下:

数据类型 转换为true的值 转换为false的值
Boolean true false
Srting 非空字符串 “”(空字符串)
Number 任何非零数字 0,NaN
Object 任何对象 null
Undefined n/a undefined

if语句中也会按照这个规则进行自动转换

Number类型

整数

var intNum = 44;		//整数
var octalNum = 070; //八进制以0开头
var hexNum = 0x1f; //十六进制以0x开头

浮点数值

var floatNum1 = 1.9;
var floatNum2 = 30.0; //会被解析成整数
var floatNum3 = 2.903e7 //29030000

由于保存浮点的空间是整数的两倍,所以ECMAScript会不失时机的把能转换成整数的浮点数转成整数

浮点数值的精确度是17位小数,进行算术计算的适合精度远远不如整数,所以不要去测试某个特定的浮点数


if(a + b == 0.9){ //不要去做这样的测试
alert("this sum is 0.9");
}

数值范围

由于内存的限制,ECMAScript并不能保存所有的数值,是有一定的范围的,超出这个范围将会被转换成Infinity(正无穷)或者-Infinity(负无穷),因为正负无穷都是不能参与计算的,要确定一个值是否是有穷的,可以通过isFinite()函数来判断:

var min = Number.MIN_VALUE;	//能保存的最小值
var max - Number.MAX_VALUE; //能保存的最大值

var num = max + max;
alert(num) //Infinity
alert(isFinite(num)) //false

NaN

NaN(Not a Number),是一个特殊的数值,表示本来要返回数值的的操作数却返回了不是数值的情况,这样就不会抛出错误。比如其他语言在遇到除以0的时候都会导致错误而停止代码执行,但是ECMAScript中不会停止代码执行,会返回相应的值:

alert(100/0);			//Infinity
alert(-100/0); //-Infinity
alert(0/0); //NaN

NaN有两个特点:

  • 凡是NaN参与的运算都返回NaN
  • NaN和任何值都不相等,包括NaN本身(你不能保证两个都不值数值的值是相等的)

针对这两个特点,ECMAScript定义了isNaN()函数,接受一个参数,判断参数是不是NaN。在接收到一个值时,会尝试将参数转换为数值。有些值虽然本身不是数值,但是是可以转换成数值的,就像"100", true就可以转换成数值1001。对于不能被转换成数值的值就会导致isNaN()返回true,其他则返回false

数值转换

有三个函数可以把非数值转换成数值:

  • Number(): 把任意类型转换成数值
  • parseInt(): 把字符串转换成整数
  • parseFloat(): 把字符串转成换浮点数

Number()的转换规则:

  • 如果是Booleantruefalse分别转成10
  • 如果是Number,只是简单的传入和传出;
  • 如果是null,返回0
  • 如果是undefined,返回NaN
  • 如果是字符串,遵守下面的规则:
    • 如果只包含数字(包括前面的正负号),转换成对应的十进制数值
    • 如果包含有效的浮点格式,转换成对应的浮点格式数值
    • 如果包含有效的十六进制的格式,转换为相同大小的十进制数值
    • 如果为空,转换为0
    • 如果包含上述格式之外的字符,转换为NaN
  • 如果是对象,调用对象的valueOf()方法,然后按照前面的规则转换返回值,如果转换的结果为NaN,则继续调用对象的toString()方法,在按照字符串规则转换返回值。

因为Number()转换规则很复杂,并且转换字符串的适合有不合理的地方,所以一般更多的采用parseInt()来处理字符串转成数值。parseInt()的规则是:忽略掉前面的空格,直到找到第一个非空字符,如果第一个非空字符串不是数字或者正负号,则直接返回NaN,也就是空字符串也会返回NaN,但Number()会返回0。如果第一个非空字符是数字或者正负号,则继续解析第二个字符,直接解析完或者遇到非数字字符,例如"1234abcd"会被转换成1234,"12.2"会转换成"12",因为小数点也不是有效的数字字符。

parseInt()可以指定第二个参数来作为进制数

parseInt()函数类似,parseFloat()也是从第一个字符开始一直解析到字符串尾,或者遇到一个无效的浮点数字字符为止。也就是说第一个小数点是有效的,而之后的小数点就是无效的。

String类型

String类型表示由零或多个16位Unicode字符组成的字符序列,即字符串。字符串可以用单引号或者双引号来表示。

字符串的不可变性

字符串一但创建就是不可变的,如果要改变某个变量保存的字符串,首先销毁掉原来的字符串,然后再用一个包含新值的字符串来赋值给该变量。

转换为字符串

把一个值转换成字符串有两种方法:

  • 几乎每个值都有toString()方法,除了null和undefined
  • 转型函数String()
    • null 返回"null"
    • `undefined 返回 "undefined"
    • 其他返回toString()的返回值

Object类型

ECMAScript中的对象其实就是一组数据和功能的集合。对象通过new操作符后跟要穿件的对象类型的名称来创建。而创建Object类型的实例并为其添加属性或方法,就可以创建自定义的对象。
在ECMAScript中,Object类型是所有它的实例的基础,也就是Object类型所具有的任何属性和方法也同样存在于更具体的对象中。每个Object实例都具有以下属性和方法:

  • constructor:构造函数,也就是创建当前对象的函数
  • hasOwnProperty(propertyName):检测给定属性在当前实例中(不是实例的原型中)是否存在
  • isPrototypeOf(Object):检测当前对象是否是传入对象的原型
  • propertyIsEnumerable(propertyName):检测给定属性是否能使用for-in语句来枚举
  • toLocalString():对象的字符串表示,与执行环境的地区对应
  • toString():对象的字符串表示
  • valueOf():对象的字符串、数值或布尔值的表示,通常和toString()返回的相同