javascript高级程序设计笔记-第三章(基本概念)
一、数据类型
ECMAScript共有6种数据类型,其中基本数据类型5种:Undefined、Null、Boolean、Number和String,复杂数据类型一种:Object
1、typeof操作符
检测给定变量的数据类型
"undefined"——如果这个值未定义(未声明变量也会出现这个结果)
"boolean"——布尔值
"string"——字符串
"numbel"——数字
"object"——对象或者null
"function"——函数
2、Undefined类型
在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined
var message;
alert(message); //"undefined"
但是如果这个变量,没有声明,就会抛出错误
//var age没有声明
alert(age) //Uncaught ReferenceError:
3、Null类型
如果定义的变量准备在将来用于保存对象,那么最好将其初始化为null
实际上undefined值是派生自null值的
alert(null) //"undefined"
4、Boolean类型
Boolean类型的字面量true和false区分大小写。这两个值与数字值不是一回事,true不一定等于1,false不一定等于0
ECMAScript中所有类型的值都能通过转型函数Boolean()转换为true或false
以下6个值转换为false,其他都转换为ture:
false
""(空字符串)
0和NaN
null
undefined
5、Number类型
isFinite()函数,确定一个数值是不是有穷的;
isNaN()函数,将接收到的参数尝试转换为数值,再做判断。
alert(isNaN(NaN)); //true
alert(isNaN(10)); //false
alert(isNaN("10")); //false(可以转换为10)
alert(isNaN("10blue")); //true(不能转换为数值)
alert(isNaN(true)); //false(转换为1)
NaN的两个特点:
- 任何值涉及NaN的操作都会返回NaN
- NaN与任何值都不相等,包括NaN本身
parseInt()函数:
parseInt("1234blue") //1234
parseInt("") //NaN
parseInt("0xA") //10(十六进制数)
parseFloat()函数:
parseFloat("1234blue") //1234
parseFloat("0xA") //0(只能解析十进制值)
parseFloat("22.34.5") //22.34(第二个小数点无效)
parseFloat("0908.5") //908.5(忽略前导的0)
parseFloat("3.125e7") //31250000
6、String类型
toString()方法(不是函数):数值、布尔值、字符串值都有toString()方法,null和undefined值没有此方法
var age = 11;
alert(age.toString()); //字符串"11"
String()函数(不是方法):
- 如果值有toString()方法,则调用该方法,并返回相应的结果
- 如果值是null,则返回"null"
- 如果值是undefined,则返回"undefined"
7、Object类型
var o = new Object();
创建Object类型的实例,不仅继承Object类型的基本的属性和方法,还可以自定义添加属性和方法
基本的属性和方法:
- constructor
- hasOwnProperty(propertyName)
- isPrototypeOf(object)
- propertyIsEnumerable(propertyName)
- toString()
- valueOf()
新创建的实例对象把之前的初始化了,而不是继承该实例之前添加的属性和方法(Object基本属性和方法除外),就是重写这个对象
二、操作符
1、递增和递减操作符
执行前置递增和递减操作时,变量的值都是在语句被求值以前改变的
var num1 = 2;
var num2 = 20;
var num3 = --num1 + num2; //21(num1变成1了)
var num4 = num1 + num2; //21
执行后置递增和递减操作时,变量的值实在语句被求值之后才改变
var num1 = 2;
var num2 = 20;
var num3 = num1-- + num2; //22(num1还是2)
var num4 = num1 + num2; //21
2、布尔操作符
逻辑非操作符(!):首先将它的操作数转换为一个布尔值,然后求反
两个逻辑非操作符(!!):与转型函数Boolean()函数相同
alert(!NaN); //true
alert(!!NaN); //false
逻辑与操作(&&):属于短路操作。即如果第一个操作数结果为false,就不会再对第二个操作数求值;只有第一个操作数结果为true时,才对第二个操作数求值
var found = true;
var result = (found && what); //what未声明,这里会报错
alert(result); //不会执行
var found = false;
var result = (found && what); //不会发生错误
alert(result); //false
逻辑或操作(||):也属于短路操作。如果第一个操作数的结果是true,就不会再对第二个操作数求值;只有第一个操作数结果为false时,才对第二个操作数求值(与逻辑与相反)
3、加性操作符
加法:
var result1 = 5 + 5; //10
var result2 = 5 + "5"; //55(转换为字符串)
减法
var result3 = 5 - 2; //3
var result4 = 5 - "2"; //3(转换为数值)
4、关系操作符
-如果两个操作数都是数值,则执行数值比较
-如果两个操作数都是字符串,则比较字符串对应的字符编码值
-如果一个操作数是数值,则将另一个操作数转换为数值,然后进行比较
var result = "Brick" < "alphabet"
//true,大写的字符编码全部小于小写的字符编码
var result = "23" < "3"
//true,因为"2"的字符编码小于"3"的字符编码
var result = "23" < 3
//false, "23"被转换为数值23
var result = "a" < 3
//false, "a"被转换成NaN,任何操作数与NaN进行关系比较,结果都是false
5、条件操作符
variable = boolean_expression ? true_value : false_value;
基于对boolean_expression
求值的结果,如果为true,则给变量variable
赋值true_value
,否则赋值false_value
三、语句
1、if语句
if (condition) {
statement1
} else {
statement2
}
if (condition1) {
statement1
} else if (condition2) {
statement2
} else {
statement3
}
2、do-while语句
后测试循环语句,只有在循环中的代码执行之后,才会测试出口条件
对条件表达式求值之前,循环体内的代码至少会被执行一次
do {
statement
} while (expression);
var i = 5;
do {
i++;
alert(i);
} while (i < 10);
//弹出5次(6、7、8、9、10)
3、while语句
前测试循环语句,在循环中的代码执行之前,就会对出口条件求值
var i = 0
while (i < 10) {
i += 2;
alert(i);
}
//输入5次(2、4、6、8、10)
var i = 0
while (i < 10) {
alert(i);
i += 2;
}
//输出5次(0、2、4、6、8)
4、for语句
前测试循环语句,类似while,
for (var i = 0; i < 5; i++) {
alert(i);
}
//输出5次(0、1、2、3、4)
类似于
var i = 0;
while (i < 5) {
alert(i);
i++;
}
//先执行语句,再递增
循环内部定义的变量也可以在外部访问
for (var i = 0; i < 5; i++) {
alert(i);
}
alert(i) //5
无限循环
for (;;) {
doSomething();
}
只给出控制条件实际上就把for循环转换成了while循环
var i = 0;
for (; i < 5;) {
alert(i);
i++;
}
var i = 0;
while (i < 5) {
alert(i);
i++;
}
5、for-in
用来枚举对象的属性
for (property in expression) {
statement;
}
如:
for (var propName in window) {
document.write(propName);
}
//显示BOM中window对象的所有属性。
//为了保证使用局部变量,推荐var
为了保证兼容性,建议使用for-in循环之前,先检测确认该对象的值不是null或undefined。
6、break和continue语句
break语句会立刻推出循环,强制继续执行循环后面的语句
var num = 0;
for (var i = 1; i < 10; i++) {
if (i % 5 === 0) {
break;
}
num++;
}
alert(num); //4
//只循环了4次
continue语句也会立刻推出循环,但退出循环后会从循环的顶部继续
var num = 0;
for (var i = 1; i < 10; i++) {
if (i % 5 === 0) {
continue;
}
num++;
}
alert(num); //8
//循环了8次
7、label语句
一般与for语句等循环语句配合使用,label标签可以在将来由break和continue语句引用。这种联合使用的情况多发生在循环嵌套的情况下
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
break outermost;
导致break语句不仅退出内部的for语句,而且也会退出外部的for语句
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
continue outermost;
导致退出内部循环,执行外部循环
8、switch语句
如果表达式等于case后面的值,则执行后面的statement
switch (i) {
case 25:
alert("25");
break;
case 35:
alert("35");
break;
case 45:
alert("45");
break;
default:
alert("other");
}
//等价于
if (i === 25) {
alert("25");
} else if (i === 35) {
alert("35");
} else if (i === 45) {
alert("45");
} else {
alert("other");
}
如果省略break关键字,就会导致执行完成当前case后,继续执行下一个case
case 25:
/*合并两种情形*/
case 35:
alert("25 or 35");
break;
混合形式,最好添加注释
var num = 25;
switch (true) {
case num < 0:
alert("less than 0");
break;
case num >= 0 && num <= 10:
alert("between 0 and 10");
break;
case num > 10 && num <= 20:
alert("between 10 and 20");
break;
default:
alert("more than 20");
}
//每个case值都返回一个布尔值,所以switch语句的表达式为true
四、函数
函数中的参数在内部用一个数组表示,可以通过arguments对象来访问,arguments.length由传递参数的个数决定,而不是命名参数的个数,arguments的值永远与对应的命名参数的值保持同步,可以互换使用,但是它们的内存空间是独立的。
function doAdd(num1, num2) {
if (arguments.length === 1) {
alert(num1 + 10);
} else if (arguments.length === 2) {
alert(arguments[0] + num2);
}
}
//两个命名参数与arguments对象一起使用
如果传入两个参数,那么arguments[1]设置的值会反映到命名参数中
function doAdd(num1, num2) {
if (arguments.length === 1) {
alert(num1 + 10);
} else if (arguments.length === 2) {
arguments[1] = 10;
alert(arguments[0] + num2);
}
}
doAdd(10); //20
doAdd(10, 20); //20
如果只传入一个参数,那么arguments[1]设置的值不会反映到命名参数中
function doAdd(num1, num2) {
arguments[1] = 10;
alert(arguments[0] + num2);
}
doAdd(10); //NaN(如果只传入一个参数,那么arguments[1]设置的值不会反映到命名参数中)
function doAdd(num1, num2) {
arguments[1] = 10;
console.log(arguments[0] + arguments[1]);
}
doAdd(10); //20(arguments可以添加参数)
function doAdd(num1) {
arguments[1] = 10;
alert(arguments[0] + arguments[1]);
}
doAdd(10); //20(arguments可以添加参数)
function doAdd(num1, num2) {
num2 = 10;
console.log(arguments[0] + arguments[1]);
}
doAdd(10); //NaN(arguments是由传入的参数决定,内部定义无效)
return之后的任何代码都永远不会执行
function sum(num1, num2) {
return num1 + num2;
alert("It won't work"); //永远不会执行
}
- 无须指定返回值,这样的函数返回undefined
- 函数不能重载
严格模式下对函数的限制:
- 不能把函数命名为evel或arguments;
- 不能把参数命名为eval或arguments;
- 不能出现两个命名参数同名的情况。