JavaScript基本概念

语法

ECMAScript借鉴了C系语言的语法。一切(变量、函数名和操作符)都区分大小写。

标识符

标识符就是指变量、函数、属性的名字,或者函数的参数。标识符的格式规则如下:

  1. 第一个字符必须是一个字母/下划线(_)/美元符号$
  2. 其他字符可以是字母、下划线、美元符号或数字
  3. 不能把关键字、保留字、true、false和null用作标识符

标识符中的字母也包含扩展的ASCII或Unicode字母字符(但是不推荐这么做)。按照惯例,ECMAScript标识符采用驼峰大小写格式,也就是第一个字母小写,剩下的每一个有意义的单词首字母大写。

语句

ECMAScript中的语句以一个分号结尾;如果省略分号,则由解析器确定语句的结尾。


                            var sum = a + b; // 推荐
                            var diff = a - b // 不推荐

                            if (test)
                            alert(test); //有效 容易出错不推荐使用

                            if (test){ //推荐
                            alert(test);
                            }
                        

关于JavaScript 语句后应是否该加分号的争论

注释

ECMAScript使用C风格的注释,包括单行注释和块级注释。


  // 单行注释以两个斜杠开头

  /* 块级注释以一个斜杠和一个星号开头,以一个星号和斜杠结尾
  * 这个星号
  * 和这个星号不是必需。
  */
                        

严格模式

ECMAScript5引入了严格模式(strict mode),定义了一种不同的解析与执行模型。使ECMAScript3中的一些不确定的行为得到处理,而且对某些不安全的操作抛出错误。


  // 在整个脚本中启用严格模式,需要在顶部添加“use strict”编译指示(pragma)
  "use strict"

  // 在函数内部的第一行添加“use strict”编译指示(pragma),指定该函数在严格模式下执行
  function doSomething(){
  "use strict"
  // 函数体
  }
                        

IE10+,Firefox4+,Safari5.1+,Opera12+和Chrome支持严格模式。

关键字和保留字

关键字用于表示控制语句的开始或结束、或者用于执行特定操作等。保留字未来有可能被用作关键字。

ECMAScript中关键字

</table> </section>

ECMAScript第3版保留字

带*号的是第5版中新增的关键字
break case catch continue debugger*
default delete do else finally
for function if in instanceof
new return switch this throw
try typeof var void while
with
</table> </section>

ECMAScript第5版非严格模式中的全部保留字

abstract boolean type char class
const debugger double enum export
extends final float goto implements
import int interface long native
package private protected public short
static super synchronized throws transient
volatile
</table> </section>

ECMAScript第5版严格模式中增加的保留字

class const enum export extends
import super
</table>

为了保证最大的兼容性,建议将第三版定义的保留字外加 letyield 作为编程时的参考。在严格模式中,eval arguments 这两个名字也不能作为标识符。

</section> </section>

变量

  • ECMAScript的变量是松散类型的,可以用来保存任何类型的变量,每个变量只是一个用来保存值的占位符。定义变量时要用var关键字,后跟一个标识符。
  • 虽然省略var操作可以定义全局变量,但是这也不是推荐的做法。因为在局部作用域中定义的全局变量很难维护
  • 省略var可以定义全局变量,但在严格模式下会抛出ReferenceError错误

 var message="hi"; //推荐
 message= 100; //有效,但不推荐
 function test(){
 message= 100; //全局变量
 }
 var message = 'hi' // 一条语句定义多个变量
 ,found = false
 ,age = 29;
                       

数据类型

  • ECMAScript中有 UndefinedNullNumberBooleanString 5种基本数据类型和 Object 一种复杂数据类型。
  • ECMASript不支持任何创建自定义类型的机制,所有值都是上面6种数据类型之一。

typeof操作符

typeof关键字用来检测给定变量的数据类型,typeof操作符可能返回下列字符串:

  1. "undefined"——未定义或未初始化
  2. "boolean"     ——布尔值
  3. "string"           ——字符串
  4. "number"      ——数值
  5. "object"          ——对象或null
  6. "function"     ——函数

特殊值null被认为是一个空对象的引用。

从技术角度讲,函数在ECMAScript中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,因此通过typeof操作符来区分函数和其他对象是有必要的。

Undefined类型

  • Undefined类型只有一个值,即特殊的undefined。在使用var声明变量但未对其进行初始化时,这个变量的值就是undefined。对未初始化和未声明的变量执行typeof操作符都返回undefined。
  • 引入这个值是为了正式区分空对象指针与未经初始化的变量

Null类型

Null类型只有一个值,即null。从逻辑角度看,null值表示一个空对象指针,这正是typeof操作符检测他返回“object”的原因。

Boolean类型

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

各种数据类型和Boolean类型之间的转换

带*号的是第5版中新增的保留字
implements interface let* package private
protected public static yield*
数据类型 转化为true值 转化为false值
Boolean true false
String 任何非空字符串 空字符串
Number 任何非零数字 0和NaN
Object 任何对象 null
Undefined **不适用** undefined

Number类型

Number类型使用IEEE754格式来表示整数和浮点数值。整数可以使用十进制、八进制(字面量第一位必须是0,严格模式下无效)和十六进制(字面量前两位必须是0x)。浮点数可以使用普通的表示法和科学计数法。

特殊值 说明
Number.MIN_VALUE 最小数值,5e-324
------------------ ------------------
Number.MAX_VALUE 最大数值,1.7976931348623157e+308
------------------ ------------------
-Infinity 或 Number.
NEGATIVE_INFINITY
负无穷。isFinite()函数判断参数值是不是有穷值
------------------ ------------------
Infinity 或Number.
POSITIVE_INFINITY
正无穷。isFinite()函数判断参数值是不是有穷值
------------------ ------------------
NaN 特殊数值,0除以0都会返回NaN

用isNaN() 验证是否是 NaN

Number()函数的数值转换规则

  • Boolean,true和false分别被转换为1和0;
  • Number,原样返回;
  • Null,返回0;
  • Undefined,返回NaN;
  • 字符串见下面规则:
    • 字符串只包含数字(包括前面带加号、减号或0的情况),转换为十进制数;
    • 字符串只包含有效的浮点数,转换为浮点数;
    • 字符串只包含有效的十六进制,转换为相同大小的十进制数;
    • 空字符串,转换为0;
    • 上述格式之外的字符串,转换为NaN;
    • 对象,如果存在valueOf()方法,则调用valueOf()方法,否则调用toString()方法,将返回值按上述规则转换

一元加操作符和Number()函数相同;也可以使用parseInt()和parseFloat()函数对字符串进行转换。

parseInt()

用于解析一个字符串,并返回一个整数。parseInt()函数侧重字符串是否符合数值模式,会忽略字符串前面的空格,直到找到第一个非空格字符。

  1. 第一个字符不是数字字符或者正负号,返回NaN;
  2. 继续解析,直到解析完成所有后续字符或者遇到了一个非数字字符;
  3. 字符串以“0x”或“0X”开头且后跟数字字符,则会将其当做一个16进制数;
  4. 字符串以“0”开头且后跟数字字符,则将其当做一个8进制数。但在ECMAScript5中,不支持8进制数;
  5. 可以为parseInt()提供第二个参数,指定转换时使用的基数。

parseFloat()

用于解析一个字符串,并返回一个浮点数。

  1. 与parseInt()函数类似,也是从第一个字符开始逐个解析字符,直到字符串结尾或遇到一个无效浮点数字为止。
  2. parseFloat()函数只能解析10进制,会始终忽略前导零,因此不提供第二个参数。
  3. 如果字符串是一个可解析为整数的数,则返回整数。

String类型

String类型用于表示由0或多个16位Unicode字符组成的字符序列,即字符串,由双引号或单引号表示(两种方法等价)。字符串的值是不可变的,要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再创建一个新值的字符串填充该变量。

转义序列

字面量 说明
\n 换行
\t 制表
\b 空格
\r 回车
\f 换页
\\ 反斜杠
\' 单引号,在用单引号表示的字符串中必须使用
\" 双引号,在用双引号表示的字符串中必须使用
\xnn 以16进制代码nn表示的一个字符。例如,\x41表示“A”
\unnnn 以16进制代码nnnn表示的一个Unicode字符

转义序列用于表示非打印字符或具有其他用途的字符 字符串的length属性表示字符串中16位字符的数目。如果字符串中包含双字节字符,那么可能不会返回精确值。

toString()转换为字符串

  • 数值、布尔值、对象和字符串都有toString方法
  • null和undefined值没有这个方法
  • toString()方法,在多数情况下不必传参
  • 在调用数值的toString()方法时,可以传一个输出数值基数的参数

String()函数转换规则

  1. 如果值有toString()方法,则调用;
  2. 如果值是null,则返回“null”;
  3. 如果值是undefined,则返回“undefined”。
  4. 可以使用('' + 值)将值转换为字符串。

Object类型

对象其实就是一组数据和功能的集合。Object类型是所有它的实例的基础。每个对象都有下列方法和属性:

  • Constructor:保存着用于创建当前对象的函数;
  • hasOwnProperty(propertyName):检查给定的属性在当前对象实例中(而不是实例的原型中)是否存在;
  • isPrototypeOf(object):用于检查传入的对象是否是另一个对象的原型;
  • propertyIsEnumerable(propertyName):用于检查给定的属性能否使用for-in语句枚举;
  • toLocaleString():返回与执行环境的地区对应的字符串表示;
  • toString():返回对象的字符串表示;
  • valueOf():返回对象的字符串、数值或布尔值表示。

操作符

  • 操作符用来操作数据值,包括算术操作符、位操作符、关系操作符和相等操作符。ECMAScript 操作符适用字符串、数字值、布尔值,甚至对象
  • 对于应用对象,相应的操作符通常调用对象的valueOf()或者toString()

一元操作符

只能操作一个值的操作符叫做一元操作符

  • 递增和递减操作符(后置型 i++)
  • 递增和递减操作符(前置型++i)

一元操作符规则

  • 应用于一个包含有效数字字符串,先将其转换为数字值
  • 应用于一个不包含有效数字字符串,将变量的值转换成NaN
  • 应用于布尔值时,false为0 / true为1
  • 应用于对象,先调用valueOf()方法,其结果适用以上方法

范例


 var s1 = “01”,s2 = “1.1”, s3 = “z”,b = false ,f = 1.1;
 var o = {
  valueOf: function() {
  return -1;
  }
 };
 s1 = -s1; //value becomes numeric -1
 s2 = -s2; //value becomes numeric -1.1
 s3 = -s3; //value becomes NaN
 b = -b; //value becomes numeric 0
 f = -f; //change to -1.1
 o = -o; //value becomes numeric 1
    

位操作符

  • 位操作按内存中表示数值的位来操作数值。ECMAScript中的所有数值都是以IEEE-754 64位格式存储,位操作先将64位的值转换为32位的整数,然后执行操作,最后再将结果转回64位。
  • Javascript完全套用了Java的位运算符,这套运算符针对的是整数,所以对Javascript完全无用,因为Javascript内部,所有数字都保存为双精度浮点数。如果使用它们的话,Javascript不得不将运算数先转为整数,然后再进行运算,这样就降低了速度。而且"按位与运算符"&同"逻辑与运算符"&&,很容易混淆。[摘自《Javascript语言精粹》]
  1. 按位非(NOT)~
  2. 按位与(AND)&
  3. 按位或(OR)|
  4. 按位异或(XOR)^
  5. 左移<<
  6. 有符号右移>>
  7. 无符号右移>>>

布尔操作符

布尔操作符用来测试两个值的关系。布尔操作符一共有3个:非(NOT)!、与(AND)&&和或(OR)||。

!逻辑非

  • 可以用于ECMAScript中任何值。! 首先会将其转换成布尔值,然后在求反。(任何值都会返回布尔值)
  • 同时使用两个逻辑非操作符可以将一个值转换为与其对应的布尔值,结果与Boolean()函数相同。

&&逻辑与

逻辑与由(&&)表示,真值表如下:

第一个操作数 第二个操作数 结果
true true true
true false false
false true false
false false false

&&逻辑与

逻辑或由(||)表示,真值表如下:

第一个操作数 第二个操作数 结果
true true true
true false true
false true true
false false false

短路操作

逻辑与与逻辑或操作均属于短路操作,即如果第一个操作数能够决定结果,那么就不会对第二个操作数求值。在有一个操作数不是布尔值的情况下,逻辑与和逻辑或操作不一定返回布尔值。

乘性操作符

ECMAScript定义了3个乘性操作符:乘法*,除法/和求模%。在操作数为非数值的情况下会使用Number()将其转换为数值。

乘法运算处理特殊值规则

  1. 乘积超过ECMAScript数值的表示范围,则返回Infinity或-Infinity;
  2. 如果Infinity与非0相乘,则结果是Infinity或-Infinity;
  3. 如果Infinity与Infinity相乘,则结果是Infinity。
  4. 如果一个操作数是NaN,则结果是NaN;
  5. 如果Infinity与0相乘,则结果是NaN;
  6. 如果不是数值,先调用Number()转换成数值,然后再应用上面的规则

除法运算处理特殊值规则

  1. 商超过ECMAScript数值的表示范围,则返回Infinity或-Infinity;
  2. 如果非0被0除,则结果是Infinity或-Infinity;
  3. 如果Infinity被非0除,则结果是Infinity或-Infinity。
  4. 如果一个操作数是NaN,则结果是NaN;
  5. 如果0被0除,则结果是NaN;
  6. 如果Infinity被Infinity除,则结果是NaN;
  7. 如果不是数值,先调用Number()转换成数值,然后再应用上面的规则

求模运算处理特殊值规则

  1. 如果Infinity被非0除,则结果是NaN;
  2. 如果Infinity被非0除,则结果是NaN;
  3. 如果非0被0除,则结果是NaN;
  4. 如果Infinity被Infinity除,则结果是NaN;
  5. 如果非0被Infinity或-Infinity除,则结果是被除数;
  6. 如果被除数是0,则结果是0;
  7. 如果不是数值,先调用Number()转换成数值,然后再应用上面的规则

加性操作符

加法运算处理特殊值规则

  1. 两个数值:如果一个操作数是NaN,则结果是NaN;
  2. 两个数值:如果Infinity加Infinity,则结果是Infinity;
  3. 两个数值:如果-Infinity加-Infinity,则结果是-Infinity;
  4. 两个数值:如果Infinity加-Infinity,则结果是NaN;
  5. 两个数值:+0加+0为+0、-0加-0为-0、+0加-0为+0
  6. 两个字符串:拼接字符串
  7. 一个字符串一个数值:数值转换成字符串,拼接字符串
  8. 有对象、数值、布尔值:调用toString()方法后,引用字符串相加规则

减法运算处理特殊值规则

  1. 如果一个操作数是NaN,则结果是NaN;
  2. 如果Infinity减Infinity,则结果是NaN;
  3. 如果-Infinity减-Infinity,则结果是NaN;
  4. 如果Infinity减-Infinity,则结果是Infinity;
  5. 如果-Infinity减Infinity,则结果是-Infinity;
  6. +0减+0为+0、-0减-0为+0、+0减-0为-0
  7. 如果一个操作数是字符串、布尔值、null、undefined,则将其使用Number()函数转换后计算。
  8. 如果一个操作数是对象先调用valueOf(),没有的话调用 toString()方法

关系操作符

小于(<)、大于(>)、小于等于(<=)和大于等于(>=)用于对两个值进行比较,并返回一个布尔值。

  • 如果两个操作数都是数值,则进行数值比较;
  • 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值;
  • 如果一个操作数是数值,则将另一个操作数转换为数值,然后进行比较;
  • 如果一个操作数是对象,则调用对象的valueOf()方法,如果对象没有valueOf()方法,则调用toString()方法,将得到的结果根据前面的规则进行比较。
  • 如果一个操作数是布尔值,则将其转换为数值,然后再进行比较;
  • 任何操作数与NaN进行关系比较,结果都是false。

相等操作符

ECMAScript提供两组相等操作符:相等==和不相等!=——先转换再比较;全等===和不全等!==(仅比较而不转换)。

  1. 如果一个操作数是布尔值,则将其转换为数值,在进行比较;
  2. 如果一个操作数是数值,另一个操作数是字符串,则将字符串转换为数值在进行比较;
  3. 如果一个操作数是对象,另一个不是,则调用对象的valueOf()方法,用得到的基本类型值按前面的规则进行比较;
  4. null和undefined是相等的;
  5. NaN不等于任何操作数,包括NaN;
  6. 如果两个操作数都是对象,则比较他们是不是同一个对象。
  7. 全等=== 不在比较之前转换操作数

条件操作符

三元操作符(三目运算):boolean_expression ? true_value : false_value;

赋值操作符

把右侧的值赋值给左侧的变量,包括等于号=,和复合赋值操作符:*=、/=、%=、+=、-=、<<=、>>=、>>>=

逗号操作符

逗号操作符可以在一条语句中执行多个操作,逗号表达式的值是最后一项的值。

语句

if


if(condition){
 statement1;
}
 else{
 statement2;
}
                        

condition可以是任意表达式,ECMAScript会自动调用Boolean()将结果转换为一个布尔值。

do-while


do{
  statement;
}while(condition);
                        

do-while是一种后测试循环语句,只有在循环体内的代码执行后,才会测试出口条件。

while



while(condition){
statement;
}
                        

while是一种前测试循环语句,在循环体内的代码执行前,测试出口条件求值。

for


 for(initialization; condition; post-loop-expression){
 statement;
 }
                        

for-in


 for(property in expression){
 statement;
 }
                        

ECMAScript对象的属性没有顺序。如果迭代的对象为undefined或null,则for-in语句会报错,ECMAScript5更正了这种行为,对这种情况不再抛出错误,而只是不执行循环体。

Safari 3 以前的版本 for-in语句中存在一个bug,该bug回到只某些属性被返回两次

label


label: statement
                        

使用label语句可以在代码中添加标签,一般配合for等循环语句中break和continue使用。

break和continue

break和continue语句用于在循环中精确的控制代码的执行。其中,break语句会立即退出循环,强制继续执行循环后面的语句;而continue语句虽然也是立即退出循环,但退出循环后会从循环的顶部继续执行。break和continue配合label使用,会退出label标识处的循环。

with

with语句的作用是将代码的作用域设定到一个特定的对象中。严格模式下不允许使用with语句,否则将视为语法错误。

switch


switch(expression){
   case value1:statement;
       break;
   case value2:statement;
       break;
   case value3:statement;
       break;
   default:statement;
 }
                        

switch语句在比较值时使用的是全等操作符,不会发生类型转换。

函数

通过函数可以封装多条语句,而且可以在任何地方、任何时候调用指定。ECMAScript使用function关键字来声明函数,后跟一组参数以及函数体。


 function name(arg0, arg1, ..., argN){
      statement;
       return value;
 }
                        

严格模式对函数有一些限制:

  1. 不能把函数命名为eval或arguments;
  2. 不能把参数命名为eval或arguments;
  3. 不能出现两个命名参数同名的情况。

理解参数

ECMASript函数不介意传递进来多少个参数,也不在乎参数类型。在函数体内可以通过arguments对象来访问这个参数数组,aguments的值永远与对应的命名参数保持同步,但这种影响是单向的,即修改arguments中的值,相应的命名参数值会发生改变,反之却不成立。但严格模式下,不存在这种关系,改变arguments的值会导致语法错误。

没有重载

ECMAScript函数没有签名,其参数是由包含0个或多个值的数组来表示,所以也不能实现传统意义上那样的重载。

Thanks

返回目录