1、语法
严格模式
严格模式是为 JavaScript 定义了一种不同的解析与执行模型。在严格模式下,ECMAScript 中的一些不确定的行为将得到处理,而且对某些不安全的操作也会抛出错误。要在整个脚本中启用严格模式,可以在顶部添加如下代码:
"use strict";
在函数内部的上方包含这条编译指示,也可以指定函数在严格模式下执行:
function doSomething(){
"use strict";
//函数体
}
2、数据类型
数据类型包括5中基本数据类型(Undefined、Null、Boolean、Number和String)和一种复杂数据类型(Object),可以通过typeof操作符来判断。此外,typeof还可以用来区分函数(返回function)和其他对象。typeof 是一个操作符而不是函数,因此后边的括号尽管可以使用,但不是必需的。
var message = "hello";
alert(typeof message);
alert(typeof (message));
Undefined
对未初始化的变量执行 typeof 操作符会返回 undefined 值,而对未声明的变量执行 typeof 操作符同样也会返回 undefined 值。
var message;
//var age;
alert(typeof message);//undefined
alert(typeof age);//undefined
Null
null 值表示一个空对象指针,而这也正是使用 typeof 操作符检测 null 值时会返回"object"的原因
var car = null;
alert(typeof car);//object
如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为 null 而不是其他值。这样一来,只要直接检查 null 值就可以知道相应的变量是否已经保存了一个对象的引用,如下面的例子所示:
if (car != null){
// 对 car 对象执行某些操作
}
实际上,undefined 值是派生自 null 值的,因此 ECMA-262 规定对它们的相等性测试要返回 true:
alert(null == undefined); //true
alert(null === undefined);//false
Boolen
转型函数 Boolean()用于将一个值转换为其对应的 Boolean 值,对任何数据类型的值调用 Boolean()函数会返回一个 Boolean 值。
| 数据类型 | 转换为true的值 | 转换为false的值 |
|---|---|---|
| Boolen | true | false |
| String | 任何非空字符串 | ""(空字符串) |
| Number | 任何非零数值(包括无穷大) | 0和NAN |
| Object | 任何对象(包括空对象) | null |
| Undefined | 无 | undefined |
Number
0除以0返回NaN(整数除以0为Infinity 或-Infinity,Infinity 除以Infinity 为 NaN,Infinity乘以0为NaN,Infinity乘以非0数值为Infinity 或-Infinity),NaN是一个特殊的数值,它和任何值不相等,包括本身。isNaN()在接收到一个值之后,会尝试将这个值转换为数值。某些不是数值的值会直接转换为数值,例如字符串"10"或 Boolean 值。而任何不能被转换为数值的值都会导致这个函数返回 true。
alert(isNaN(NaN)); //true
alert(isNaN(10)); //false(10是一个数值)
alert(isNaN("10")); //false(可以被转换成数值10)
alert(isNaN(""));//false
alert(isNaN("blue")); //true(不能转换成数值)
alert(isNaN(true)); //false(可以被转换成数值1)
数值转换
-
Number()
-
Boolean 值,true 和 false 将分别被转换为 1 和 0。
-
数字值,只是简单的传入和返回。
-
null 值,返回 0。
-
undefined,返回 NaN。
-
字符串:
- 字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即"1" 会变成 1,"123"会变成 123,而"011"会变成 11(忽略前导零);
- 字符串中包含有效的浮点格式,如"1.1",则将其转换为对应的浮点数值(忽略前导零);
- 字符串中包含有效的十六进制格式,例如"0xf",则将其转换为相同大小的十进制整数值;
- 空字符串,转换为 0;
- 字符串中包含除上述格式之外的字符,则将其转换为 NaN。
-
如果是对象,则调用对象的 valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是 NaN,则调用对象的 toString()方法,然后再次依照前面的规则转换返回的字符串值。
var num1 = Number("Hello world!"); //NaN var num2 = Number(""); //0 var num3 = Number("000011"); //11 var num4 = Number(true); //1 -
-
parseInt()
在使用 parseInt()解析像八进制字面量的字符串时,ECMAScript 3 和 5 存在分歧。例如: //ECMAScript 3 认为是 56(八进制),ECMAScript 5 认为是 70(十进制) var num = parseInt("070"); 在 ECMAScript 3 JavaScript 引擎中,"070"被当成八进制字面量,因此转换后的值是十进制的 56。 而在 ECMAScript 5 JavaScript 引擎中,parseInt()已经不具有解析八进制值的能力,因此前导的零会被认为无效,从而将这个值当成"70",结果就得到十进制的 70。为了消除在使用 parseInt()函数时可能导致的上述困惑,可以为这个函数提供第二个参数:转换时使用的基数(即多少进制)。如果知道要解析的值是十六进制格式的字符串,那么指定基数 16 作为第二个参数,可以保证得到正确的结果,例如:
var num = parseInt("0xAF", 16); //175实际上,如果指定了 16 作为第二个参数,字符串可以不带前面的"0x",如下所示:var num1 = parseInt("AF", 16); //175 var num2 = parseInt("AF"); //NaN //parseInt的一些其他例子 var num1 = parseInt("1234blue"); // 1234 var num2 = parseInt(""); // NaN var num3 = parseInt("0xA"); // 10(十六进制数) var num4 = parseInt(22.5); // 22 var num5 = parseInt("070"); // 56(八进制数) var num6 = parseInt("70"); // 70(十进制数) var num7 = parseInt("0xf"); // 15(十六进制数) -
parseFloat()
parseFloat()与 parseInt()有两个区别:一、第一个小数点有效,二、它始终都会忽略前导的零。
parseFloat()可以识别浮点数值格式,也包括十进制整数格式。但十六进制格式的字符串则始终会被转换成 0。由于 parseFloat()只解析十进制值,因此它没有用第二个参数指定基数的用法。最后还要注意一点:如果字符串包含的是一个可解析为整数的数(没有小数点,或者小数点后都是零),parseFloat()会返回整数。
var num1 = parseFloat("1234blue"); //1234 (整数)
var num2 = parseFloat("0xA"); //0
var num3 = parseFloat("22.5"); //22.5
var num4 = parseFloat("22.34.5"); //22.34
var num5 = parseFloat("0908.5"); //908.5
var num6 = parseFloat("3.125e7"); //31250000
String
转换为字符串
-
toString()方法
除了null和undefined之外,其余数据类型都可以调用该方法,转换为字符串。多数情况下,该方法可以不用传参,但可以通过传递基数,使toString()可以输出以二进制、八进制、十六进制,乃至其他任意有效进制格 式表示的字符串值。
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()方法,则调用该方法(没有参数)并返回相应的结果;
-
如果值是 null,则返回"null";
-
如果值是 undefined,则返回"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
Object 的每个实例都具有下列属性和方法:
-
constructor:构造函数,保存着用于创建当前对象的函数。
-
hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。属性名(propertyName)作为参数,必须为字符串(如:o.hasOwnProperty("name"))。
-
isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型。
-
propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用 for-in 语句来枚举。与 hasOwnProperty()方法一样,作为参数的属性名必须为字符串。
-
toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
-
toString():返回对象的字符串表示。
-
valueOf():返回对象的字符串、数值或布尔值表示。通常与 toString()方法的返回值相同。
3、操作符
一元操作符
- ++、--
不仅适用于整数,还可以用于字符串、布尔值、浮 点数值和对象。在应用于不同的值时,递增和递减操作符遵循下列规则:
-
在应用于一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减 1 的操作。字 符串变量变成数值变量。
-
在应用于一个不包含有效数字字符的字符串时,将变量的值设置为 NaN(第 4 章将详细讨论)。 字符串变量变成数值变量。
-
在应用于布尔值 false 时,先将其转换为 0 再执行加减 1 的操作。布尔值变量变成数值变量。
-
在应用于布尔值 true 时,先将其转换为 1 再执行加减 1 的操作。布尔值变量变成数值变量。
-
在应用于浮点数值时,执行加减 1 的操作。
-
在应用于对象时,先调用对象的 valueOf()方法(第 5 章将详细讨论)以取得一个可供操作的 值。然后对该值应用前述规则。如果结果是 NaN,则在调用 toString()方法后再应用前述规 则。对象变量变成数值变量。
var s1 = "2";
var s2 = "z";
var b = false;
var f = 1.1;
var o = {
valueOf: function() {
return -1;
}
};
s1++; // 值变成数值 3
s2++; // 值变成 NaN
b++; // 值变成数值 1
f--; // 值变成 0.10000000000000009(由于浮点舍入错误所致)
o--; // 值变成数值-2
- +、-
对非数值应用一元加操作符时,该操作符会像 Number()转型函数一样对这个值执行转换。 换句话说,布尔值 false 和 true 将被转换为 0 和 1,字符串值会被按照一组特殊的规则进行解析,而 对象是先调用它们的 valueOf()和(或)toString()方法,再转换得到的值。
var s1 = "01";
var s2 = "1.1";
var s3 = "z";
var b = false;
var f = 1.1;
var o = {
valueOf: function() {
return -1;
}
};
s1 = +s1; // 值变成数值 1
s2 = +s2; // 值变成数值 1.1
s3 = +s3; // 值变成 NaN
b = +b; // 值变成数值 0
f = +f; // 值未变,仍然是 1.1
o = +o; // 值变成数值-1
位操作符
-
按位非(NOT)
按位非操作符由一个波浪线(~)表示,执行按位非的结果就是返回数值的反码。
var num1 = 25; // 二进制 00000000000000000000000000011001
var num2 = ~num1; // 二进制 11111111111111111111111111100110
alert(num2); // -26
var num1 = 25;
var num2 = -num1 - 1;
alert(num2); // "-26"
//虽然以上代码也能返回同样的结果,但由于按位非是在数值表示的最底层执行操作,因此速度更快。
-
按位与(AND)
按位与操作符由一个和号字符(&)表示,它有两个操作符数。从本质上讲,按位与操作就是将两个数值的每一位对齐,只在两个数值的对应位都是 1 时才返回 1,任何一位是 0,结果都是 0。
var result = 25 & 3; alert(result); //1 //25 = 0000 0000 0000 0000 0000 0000 0001 1001 //3 = 0000 0000 0000 0000 0000 0000 0000 0011 --------------------------------------------- //AND = 0000 0000 0000 0000 0000 0000 0000 0001 -
按位或(OR)
按位或操作符由一个竖线符号(|)表示,也有两个操作数。按位或操作在有一个位是 1 的情况下就返回 1,而只有在两个位都是 0 的情况下才返回 0。
var result = 25 | 3; alert(result); //27 //25 = 0000 0000 0000 0000 0000 0000 0001 1001 //3 = 0000 0000 0000 0000 0000 0000 0000 0011 -------------------------------------------- //OR = 0000 0000 0000 0000 0000 0000 0001 1011 -
按位异或(XOR)
按位异或操作符由一个插入符号(^)表示,也有两个操作数。按位异或与按位或的不同之处在于,这个操作在两个数值对应位上只有一个 1 时才返回 1,如果对应的两位都是 1 或都是 0,则返回 0(相同为0,不同为1)。
var result = 25 ^ 3; alert(result); //26 //25 = 0000 0000 0000 0000 0000 0000 0001 1001 //3 = 0000 0000 0000 0000 0000 0000 0000 0011 --------------------------------------------- //XOR = 0000 0000 0000 0000 0000 0000 0001 1010 -
左移
左移操作符由两个小于号(<<)表示,这个操作符会将数值的所有位向左移动指定的位数。
var oldValue = 2; // 等于二进制的 10 var newValue = oldValue << 5; // 等于二进制的 1000000,十进制的 64 //在向左移位后,原数值的右侧多出了 5 个空位。左移操作会以 0 来填充这些空位,以便得到的结果是一个完整的 32 位二进制数左移不会影响操作数的符号位。换句话说,如果将-2 向左移动 5 位,结果将是-64,而非 64。
-
有符号的右移
有符号的右移操作符由两个大于号(>>)表示,这个操作符会将数值向右移动,但保留符号位(即 正负号标记),此时会用符号位的值来填充所有空位。有符号的右移操作与左移操作恰好相反。
var oldValue = 64; // 等于二进制的 1000000 var newValue = oldValue >> 5; // 等于二进制的 10 ,即十进制的 2 -
无符号右移
无符号右移操作符由 3 个大于号(>>>)表示,这个操作符会将数值的所有 32 位都向右移动。对正数来说,无符号右移的结果与有符号右移相同。但是对负数来说,情况就不一样了。首先,无符号右移是以 0 来填充空位,而不是像有符号右移那样以符号位的值来填充空位。所以,对正数的无符号右移与有符号右移结果相同,但对负数的结果就不一样了。其次,无符号右移操作符会把负数的二进制码当成正数的二进制码。而且,由于负数以其绝对值的二进制补码形式表示,因此就会导致无符号右移后的结果非常之大。
var oldValue = 64; // 等于二进制的 1000000 var newValue = oldValue >>> 5; // 等于二进制的 10 ,即十进制的 2 var oldValue = -64; // 等于二进制的 11111111111111111111111111000000 var newValue = oldValue >>> 5; // 等于十进制的 134217726
布尔操作符
-
逻辑与(&&) 逻辑与操作可以应用于任何类型的操作数,而不仅仅是布尔值。在有一个操作数不是布尔值的情况 下,逻辑与操作就不一定返回布尔值;此时,它遵循下列规则:
-
如果第一个操作数是对象,则返回第二个操作数;
-
如果第二个操作数是对象,则只有在第一个操作数的求值结果为 true 的情况下才会返回该对象;
-
如果两个操作数都是对象,则返回第二个操作数;
-
如果有一个操作数是 null,则返回 null;
-
如果有一个操作数是 NaN,则返回 NaN;
-
如果有一个操作数是 undefined,则返回 undefined。
-
-
逻辑或(||)
与逻辑与操作相似,如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值;此时,它遵循下列规则:
-
如果第一个操作数是对象,则返回第一个操作数;
-
如果第一个操作数的求值结果为 false,则返回第二个操作数;
-
如果两个操作数都是对象,则返回第一个操作数;
-
如果两个操作数都是 null,则返回 null;
-
如果两个操作数都是 NaN,则返回 NaN;
-
如果两个操作数都是 undefined,则返回 undefined。
-
乘性操作符
var a1 = NaN * 1;//NaN
var a2 = 1 * NaN;//NaN
var a3 = Infinity * 0;//NaN
var a4 = Infinity * -2;//-Infinity
var a5 = Infinity * Infinity;//Infinity
var b1 = NaN / 1;//NaN
var b2 = 1 / NaN;//NaN
var b3 = 0/0;//NaN
var b4 = 2/0;//Infinity
var b5 = Infinity / Infinity;//NaN
var c1 = Infinity % 5;//NaN
var c2 = 5 % Infinity;//5
var c3 = 6 % 0;//NaN
var c4 = 0 % 0;//NaN
var c5 = 0 % 6;//0
var c6 = Infinity % Infinity;//NaN
加性操作符
var a1 = Infinity + Infinity;//Infinity
var a2 = -Infinity + -Infinity;//-Infinity
var a3 = Infinity + -Infinity;//NaN
var a4 = +0 + +0;//+0
var a5 = -0 + -0;//-0
var a6 = +0 + -0;//+0
var b1 = Infinity - Infinity;//NaN
var b2 = -Infinity - -Infinity;//NaN
var b3 = Infinity - -Infinity;//Infinity
var b4 = -Infinity - Infinity;//-Infinity
var b5 = +0 - +0;//+0
var b6 = +0 - -0;//-0
var b7 = -0 - -0;//+0
关系操作符
如果两个操作数都是字符串,则比较两个字符串对应的字符编码值。
任何操作数与 NaN 进行 关系比较,结果都是 false。
var result = "Brick" < "alphabet"; //true
var result = "Brick".toLowerCase() < "alphabet".toLowerCase(); //false
var result = "23" < "3"; //true
var result = "23" < 3; //false
var result = "a" < 3; // false,因为"a"被转换成了 NaN
var result1 = NaN < 3; //false
var result2 = NaN >= 3; //false
相等操作符
null == undefined;//true
"NaN" == NaN;//false
5 == NaN;//false
NaN == NaN;//false
NaN != NaN;//true
undefined == 0;//false
null == 0;//false
"5" != 5;//false
4、语句
label语句
使用 label 语句可以在代码中添加标签,以便将来使用。加标签的语句一般都要与 for 语句等循环语句配合使用。
label:statement
start: for (var i=0; i < count; i++) {
alert(i);
}
var num = 0;
outermost:
for (var i=0; i < 10; i++) {
for (var j=0; j < 10; j++) {
if (i == 5 && j == 5) {
break outermost;
}
num++;
}
}
alert(num); //55
var num = 0;
outermost:
for (var i=0; i < 10; i++) {
for (var j=0; j < 10; j++) {
if (i == 5 && j == 5) {
continue outermost;
}
num++;
}
}
alert(num); //95
with语句
with 语句的作用是将代码的作用域设置到一个特定的对象中,主要是为了简化多次编写同一个对象的工作。严格模式下不允许使用 with 语句,否则将视为语法错误。
with (expression) statement;
var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;
with(location){
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}
5、函数
参数
参数在内部是用一个数组arguments来表示的,可以使用方括号语法访 问它的每一个元素(即第一个元素是 arguments[0],第二个元素是 argumetns[1],以此类推),使 用 length 属性来确定传递进来多少个参数。arguments 对象可以与命名参数一起使用;arguments的值永远与对应命名参数的值保持同步
function sayHi(name, message) {
alert("Hello " + name + "," + message);
}
function sayHi() {
alert("Hello " + arguments[0] + "," + arguments[1]);
}
function doAdd(num1, num2) {
if(arguments.length == 1) {
alert(num1 + 10);
} else if (arguments.length == 2) {
alert(arguments[0] + num2);
}
}
没有重载
ECMAScript 函数不能像传统意义上那样实现重载。而在其他语言(如 Java)中,可以为一个函数编写两个定义,只要这两个定义的签名(接受的参数的类型和数量)不同即可。