js组成
1)ECMAScript(ECMA) 提供js语法标准
包括:
变量
数据类型
关键字
操作符(var)
语句
数组
面向对象
2)DOM,提供访问和操作网页内容的方法和接口
文档对象模型
js语法标准开发出来的操作元素的js库
3)BOM,提供与浏览器交互的方法和接口
浏览器对象模型
window.alert()
setInterval()
setTimeout()
基本概念(ECMA)
1)语法
1.区分大小写
2.标识符
第一个字符必须是字母、下划线(_)或一个美元符号($)
其他字符可以是字母、下划线、美元符号或数字
3.注释
包括单行注释和块级注释
//单行注释
/* 块级注释*/
4.严格模式
1.可以在脚本顶部添加 "use strict"
2.可以在函数体内部使用:
function doSomething(){
"use strict";
//函数体
}
5.语句
ECMAScript的语句以一个分号结尾;如果省略分号则由解析器确定语句的分号。不推荐省略分号,省略分号会导致解析器要花费更多时去推测分号位置,若通过空格压缩代码会导致压缩错误
2)关键字和保留字
关键字
var、break、 case、 void 、while、 typeof ...
保留字
int、 short、 long、 byte、 abstract、 class ...
3)变量
每个变量仅仅是一个用于保存值的占位符。如 var message
** 注意:用var操作符定义的变量将成为定义该变量的作用域中的局部变量,例如
function test(){
var message="hi"; //局部变量
}
test();
alert(message); //错误!!
在上面的例子中如果省略 var操作符,因而message就成了全局变量。
4)数据类型
5中基本数据类型:Number、String、Boolean、Undefined Null
还有一种复杂数据类型 --Object,Object本质是由一组无序的名值对组成。
4.1 typeof 操作符
对一个值使用typeof操作可能返回下列某个字符串:
* "undefined" --如果这个值未定义
* "boolean" --如果这个值是布尔值
* "string" --如果这个值是字符串
* "number" --如果这个值是数值
* "object" --如果这个值是对象或null
* "function" --如果这个值是函数。
***注意:但是尚未定义(尚未声明)与未初始化的变量执行typeof操作符都会返回undefined值。这个结果有其逻辑上的合理性、因为虽然这两种变量从技术角度看有本质区别,但实际上无论对哪种变量也不肯能执行真正的操作。
4.2 Undefined类型
该类型只有一个值,即underfined,在使用var声明变量但未对其初始化时,这个变量的值就是underfined 例如:
var message;
console.log(message == underfined); //true
==>等价于
var message= underfined;
console.log(message == undefined); //true
***注意:对于尚未定义过的变量,通过控制台打印会报错!
4.3 Null类型
该类型也只有一个值 即null。从逻辑角度来看,null值表示一个空对象指针。因此typeof操作符检测null值时返回"object"
用途:如果定义的变量准备在将来用来保存对象,那么最好将该变量初始化化为null
var car=null;
console.log(car); //"object"
**注意:其实undefined值是派生自null值的,因此
console.log(null==undefiend) //true
4.4 Boolean类型
该类型只有两个字面值:true和false。但这两个值与数字值不是一回事,因此true不一定等于1,而false也不一定等于0.
var found=true;
var lost=false;
如果要将一个值转换成一个boolean值。可以调用Boolean()函数。
各种数据类型的转换规则
boolean true false
String 任何非空字符串 ""(空字符串)
Number 任何非零数字值(包括无穷大) 0和NaN
Object 任何对象 null
Unfefined n/a undefined
** 在if语句中自动执行相应的Boolean转换。
例如:
var message;
if(message){
alert("Value is true");
}
4.5 Number类型
该类型可以表示整数和浮点数值。
var intNum=55 //整数
var octalNum1=070; //八进制数值56
var octalNum2=078 //无效的八进制--解析为 78
4.5.1 浮点数值
1)由于保存浮点数值需要的内存空间是保存整数值的两倍,因此ECMAScript会不失时机地将浮点数值转换为整数值
var floatNum=1.0 //解析为 1
2)对于极大或者极小的数可以用 e 表示(即科学计数法)
var floatNum=3.12e7 //等价于 3.12*10^7
4.5.2 isFinite()
来确定参数是否超出了数字范围,若没有超出返回 true 超出后返回false
正无穷 infinity 负无穷 -infinity
*** 正数除以0返回 Infinity 负数除以0返回-Infinity 0除以0返回NaN
4.5.3 NaN
表示一个非数值的特殊数值。这个数值用来表示一个本来要返回数值的操作数 未返回数值的情况(这样就不会抛出错误,计算机还能继续运行)
**NaN与任何值都不相等,包括NaN本身。
console.log(NaN==NaN) //false
1)isNaN()
任何不能被转换为数值的值都会导致这个函数返回true。
isNaN(NaN) //true
isNaN(10) //false
isNaN("10") //false 可以被转换成数值10
isNaN("blue") //true
isNaN(true) //false 可以被转换成数值 1
4.5.4 数值转换
Number()函数(转型函数)可以用于任何数据类型,而另两个函数则专门用于把字符串转换成数值。
1)Number()函数(转型函数)
如果是Boolean值,true和false将分别被转换为1和0
如果是null值,返回0
如果是undefined返回 NaN
如果是字符串则遵循下列规则
1. 如果字符串中只包含数字 即 "1"会变成1
2. 如果字符串中包含有效的浮点格式,如"1.1"则将其转换为对应的浮点数值
"0011"会变成11 (注意:前导的零被忽略)
3. 如果字符串中包含有十六进制格式则将其转换为相同大小的十进制整数值 即 "oxf"
4. 如果字符串是空的,则返回0
5. 如果字符串中包含除上述之外的字符,则将其转换为NaN
6. 如果是对象,则调用对象的valueof方法,然后依据前面的规则转换返回的值。如果转换的结果是NaN,则调用对象toString()方法,然后再次依据规则转换返回的字符串值。
var num1=Number("hello") //NaN
var num2=Number("") //0
var num3=Number("000011") //11
var num4=Number(true) //1
2)parseInt()函数
该函数是看其是否符合数值模式。它会忽略字符串前面的空格直至找到第一非空格字符,如果第一个字符不是数字字符或者负号,则返回NaN
var num1=parseInt("blue123") //NaN
var num2=parseInt("123blue") //123
var num3=parseInt("0xa") //10(十六进制)
var num4=parseInt("070") //56(八进制)
var num5=parseInt("oxaf") //175
var num6=parseInt("af",16) //175
3)parseFloat()函数
与parseint()函数类似,但区别在于:
1)字符串中第一个小数点是有效的
2)它始终会忽略前导的零,十六进制格式的字符串则始终会被转换为0
3)只解析十进制值,因此它没有第二个参数指定基数的用法
4)字符中如果包括一个可解析为整数的数,则返回整数
var num1=parseFloat("123blue") //123 整数
var num2=parseFloat("0xa") // 0
var num3=parseFloat("22.5") //22.5
var num4=parseFloat("22.34.5") //22.34
var num5=parseFloat("0906.5") //906.5
4.6 String类型
字符串可以由双引号(")或(')表示
****:ECMAScript中的字符串是不可变的,也就是说,字符串一旦创建,他们的值就不能改变,要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。
4.6.1 转换为字符串
1)String()
该函数是转型函数,这个函数能够将任何类型的数值转换为字符串。遵循下列转换规则
如果值有toString()方法,则调用该方法并返回相应的结果
如果值是null,则返回"null";
如果值是undefined,则返回"undefined"
var value1=null;
var value2;
String(value1) //"null"
String(value2) //"undefined"
2)toString()方法
数值、布尔值、对象和字符串值(每个字符串也都有一个toString()方法,该方法返回字符串的一个副本)都有toString()犯法,但null和undefined值没有这个方法。
toString()方法以十进制格式返回数值的字符串表示,但也可以通过传递基数区改变进制格式表示的字符串值
var num=10;
var console.log(num.toString()) //"10"
var console.log(num.toString(2)) //"1010"
var console.log(num.toString(16)) //"a"
3)+ ""
4.7 Object类型
对象其实是一组数据和功能的集合,对象可以通过执行new操作符后跟要创建的对象类型的名称创建即:
var o =new object();
object的每个实例都具有下列属性和方法。
constructor:保存着用于创建当前对象的函数。
hasOwnProperty(propertyName):用于检测给定的属性在当前对象实例中是否存在,其中propertyName必须是字符串
isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型
propertyIsEnumberable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举
toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
toString():返回对象的字符串表示
valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法返回值相同
Object是所有对象的基础,因此所有对象都具有这些基本的属性和方法
5)操作符
5.1.一元操作符
只能操作一个值的操作符叫做一元操作符。
1.1 递增和递减操作符
前置型:应该位于要操作的变量之前,并且先操作后赋值
var num1=2;
var num2=20;
var num3=++num+num2; //等于23
var num4=num1+num2; //等于23
后置型: 应该位于要操作的变量之后,并且先赋值后操作
var num1=2;
var num2=20;
var num3=num+++num2; //22
var num4=num1+num2; //23
**: 后置运算符优先级大于前置
所有的前置和后置操作符对任何值都适用,也就是他们不仅适用于整数,还可以用于字符串、布尔值、浮点数和对象。
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(由于浮点舍入所致)
0--; //值变成数值-2
1.2一元加和减操作符
1.2.1 一元加操作符不会对数值产生影响,但对于非数值时,该操作符就会像Number()转型函数一样对这个值执行转换。
var num=25;
num=+num; //仍是25
var s1="01";
var s2="1.1";
var s3="z";
var b=false;
var f=1.1
s1= +s1; //值变成数值1
s2= +s2; //值变成数值1.1
s3= +s3; //值变成NaN
b= +b; //值变成 0
f= +f; //值仍是1.1
1.2.2 一元减运算符主要用于表示负数(对于数值时);对于非数值时,一元减操作符遵循与一元加操作符相同的规则,最后再将得到的数值转换为负数。
var num=25;
num=-num; //变成-25
var s1="01";
var s2="1.1";
var s3="z";
var b=false;
var f=1.1
s1= -s1; //值变成数值 -1
s2= -s2; //值变成数值 -1.1
s3= -s3; //值变成NaN
b= -b; //值变成 0
f= -f; //值变成了 -1.1
5.2.位操作符
对数值应用位操作符时,首先将64位的数值转换成32位的数值,然后执行位操作,最后再将32位的结果转换回64位数值。对于特殊的NaN和Infinity值应用位操作被当做0来处理。
如果对非数值应用位操作符,会先使用Number()函数将该值转换为一个数值(自动完成),然后再应用位操作。得到的结果将是一个数值。
2.1 按位非(NOT)
按位非操作符由一个破浪线(~)表示,执行按位非的结果就是返回数值的反码。
var num1=25;
var num2= ~num1;
console.log(num2); //-26
2.2 按位与(AND)
按位与操作符由一个和号字符(&)表示,按位与操作就是将两个数值的每一位对齐,然后根据规则进行AND操作,结果就是只有对应位都是1时才返回1,任何一位是0,结果都是0
var result=25 & 3; //该值为 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
2.3 按位或(OR)
按位或操作符由一个竖线符号(|)表示,同样也有两个操作数.结果就是只要有一位是1就返回1,只有两位都是0才返回0
var result=25 | 3; //该值为 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
2.4 按位异或(XOR)
按位异或操作符由一个插入符号(^)表示,结果就是相异为真(两个数值对于位只有一个1),相同为假(对应位都是1或者都是0)
var result=25 ^ 3; //该值为 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
2.5 左移
左移操作符由讲个小于号(<<)表示,这个操作符将数值的所有位向左移动指定位数.
var oldValue=5; //等于二进制101
var newValue=oldValue <<5 //等于二进制10100000 十进制的160
===>等价于 5*2^5
**:左移不会影响操作数的符号位.如果将-2左移5位,结果为-64
2.6 有符号的右移
有符号的右移操作符由两个大于号(>>)表示,这个操作符将数值向右移动,但保留符号位。
var oldValue=64; //等于二进制的1000000
var newValue=oldValue >>5; //等于二进制的10 即十进制的2
2.7 无符号右移
无符号右移操作符由3个大于号(>>>)表示,这个操作符会将数值的所有32位都向右移动,对于正数来说结果与无符号位右移相同;但对于负数来说二进制码当成正数的进制码。
var oldValue=-64; //等于二进制 1111 1111 1111 1111 1111 1111 1100 0000
var oldValue=oldValue >>>5; //等于十进制 134217726
3.布尔操作符
3.1 逻辑非
逻辑非操作符由一个叹号(!)表示,可以应用于ECMAScript中的任何值。无论这个值是什么数据类型。逻辑非操纵符首先会将它的操作数转换为一个布尔值然后再对其求反。
console.log(!false); //true
console.log(!'blue'); //false
console.log(!0); //true
console.log(!NaN); //true
console.log(!""); //true
3.1.1 !!
使用两个逻辑非操作符,实际上就是模拟Boolean()转型函数的行为。会得到该操作数本身的布尔值。
console.log(!!false); //false
console.log(!!""); //false
console.log(!!Infinity); //true
console.log(!!NaN); //false
console.log(!!"12"); //true
3.2 逻辑与
逻辑与操祖符由两个和号(&&)表示,有两个操作数如下所示:
var result= true && false;
该操作符只要有一个为假则结果就为假
该操作符属于短路操作,即如果第一个操作数能够决定结果,那么就不会再对第二个操作数求值。对于逻辑与操作符而言,如果第一个操作数是false,那么无论后面的值是什么。都不会就比较。
简易证明:
var found=false;
var result=(found && someUndefinedValue); //不会发生错误
console.log(result); //false
-----------------------------------------------------------------
var found=true;
var result=(found && someUndefiendValue); //会报错
console.log(result); //不会执行
3.3 逻辑或
逻辑或操作符由两个竖线符号(||)表示,有两个操作数,如下所示:
var result=true || false;
该操作符的只要有一个为真则为真。
如果两个操作数都是null 则返回null;
如果两个操作数都是undefined,则返回undefined
如果两个操作数都是NaN,则返回NaN
如果第一操作数就是对象,则结果是第一个操作数
var found=true;
var result=(found || someUndefinedValue); //不会报错
var console.log(result) //true
4.算术运算符
4.1 乘法
乘法操作符由一个星号(*)表示。例如:
var result=33 * 32;
乘法规则:
如果操作数超出范围结果Infinity或-Infinity
如果有一个操作数是NaN,则结果NaN
如果有一个操作数是Undefined,则结果 NaN
如果是Infinity与0乘,则结果是 NaN
如果Infinity与非0相乘,则结果是Infinity或-Infinity
如果Infinity与-Infinity相乘,则结果是-Infinity
如果有一个操作数不是数值,则后台调用Number()将其转换成数值然后再进行计算
var result=(0/0)*12 //NaN
var result1=(1/0)*0 //NaN
var result2=(1/0)*(-1/0) //-Infinity
var result3="123"*2 //246
4.2 除法
除法操作符由一个斜线符号(/)表示。
如果有一个操作数是NaN,则结果是NaN
如果是Infinity被Infinity除,则结果是NaN
如果是0被0除,则结果是NaN
如果是非零的有限数被零除,则结果是Infinity或-Infinity
如果有一个操作数不是数值,则后台调用Number()将其转换为数值,然后再计算
NaN/1 //NaN
Infinity/Infinity //NaN
1/0 //Infinity
0/0 //NaN
"12"/1 //12
4.3 求模
求模(余数)操作符由一个百分号(%)表示,如下:
var result=35 % 5 //0
如果被除数是无穷大值而除数是有限大的值,则结果是NaN
如果被除数是有限大值而除数是0,则结果是NaN
如果是Infinity被Infinity除,则结果是NaN
如果被除数是有限大而除数是无线大则结果是被除数;
如果被除数是零,则结果是0
如果有一个操作数不是数值,则后台调用Number()将其转为数值。
Infinity % 1 //NaN
1 % Infinity //1
1 % 0 //NaN
Infinity % Infinity //NaN
0 % 12 //0
"12"/2 //0
4.4 加法
NaN+1 //NaN
Infinity+Infinity //Infinity
-Infinity+-Infinity //-Infinity
Infinity+-Infinity //NaN
如果有一个操作数是字符串,那么就要应用如下规则:
如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来
如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来
var result="12"+"123" //"12123"
var result1="12"+2 //"122"
4.5 减法
NaN-1 //NaN
Infinity-Infinity //NaN
-Infinity-Infinity //-Infinity
Infinity--Infinity //Infinity
5 - null //5
5 - "2" //3
5 - "" //5
5.关系操作符
如果操作数都是数值,则执行数值比较
如果两个操作数都是字符串,则比较两个字符串对应的字符编码
如果一个操作数是数字一个是字符,则先将字符转换为数值,在进行比较
如果一个操作是布尔值,先将其转换为数值在进行比较
var result="B"<"a" //true
var result="B".toLowerCase() <"a".toLowerCase() //false
var result1="23"<"3"; //true
var result2="a"<3; //false "a"被转换为NaN
var result2=NaN <3; //false
var result2=NaN>3 //false
var result3=true<2 //true
6.相等操作符
6.1 相等和不相等
这两个操作符都会先转换操作数(通常称为强制转型),然后再比较它们的相等性。
null==undefined true
"NaN"==NaN false
NaN==NaN false
NaN!=NaN true
false==0 true
true==1 true
undefined==0 false
null==0 false
"5"==5 true
6.2 全等和不全等
该操作符不转换操作数,只有两个操作数未经转换就相等的情况下才返回true
null===undefined false
"3"===3 false
7.条件操作符(三目运算符)
var max=(num1>num2)?num1:num2;
max将会保存一个最大值。如果num1>num2则将num1的值赋给max,如果num1的值小于num2则将num2的值赋给max
8.赋值操作符
加/赋值(+=);
减/赋值(-=);
乘/赋值(*=);
除/赋值(/=);
左移/赋值(<<=);
无符号右移(>>>=);
有符号右移(>>=)
9.逗号操作符
使用逗号操作符可以在一条语句中执行多个操作
var num1=1,num2=2,num3=4
6)流控制语句
1. if语句
if(condition){
statement1
}else{
statement2
}
2. do-while语句
在对条件表达式求值前,循环体内的代码至少被执行一次。
do{
statement
}while(expression);
3. while语句
while语句属于前侧试循环语句,即在循环体内的代码被执行之前,就会对出口条件求值。
while(expression){
statement
}
4. for语句
for(initialization;expression;post-loop-expression){
statement
}
for(;;){} //无线循环
若只给出控制表达式实际上就把for循环转换成while循环
var count=10;
var i=0;
for(;i<count;){
i++;
}
5. for-in语句
该语句是一种精准的迭代语句,可以用来枚举对象的属性
for(property in expression){
statement
}
6. label语句
label:statement
7. break和continue语句
break语句会立即退出循环,强制继续执行循环后面的语句。
continue语句也会立即退出循环,但退出循环后从循环的顶部继续执行。
var num=0;
for(var i=1;i<10;i++){
if(i%5==0){
break;
}
num++;
}
console.log(num) //4
var num=0;
for(var i=1;i<10;i++){
if(i%5==0){
continue;
}
num++;
}
console.log(num) //8
8. switch语句
该语句在比较值时使用的是全等操作符,因此不会发生类型转换(即 字符串"10"不等于数值10)
switch(expression){
case value:statement
break;
case value:statement
break;
case value:statement
break;
default: statement
}
7)函数
function functionName(arg0,arg1,...,argN){
statements
}
严格模式对函数有一些限制:
1,不能把函数命名为eval或arguments
2.不能把参数命名为eval或arguments
3.不能出现两个命令参数同名的情况
1.理解参数
ECMAscript中的参数在内部是用一个数组来表示的。函数接收到的始终都是这个数组,而不关心数组中包含哪些参数.这也就是说给函数传递参数不是必须的。实际上,在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。
function say(name,message){
console.log("Hello"+name+","+message);
}
function say(){
console.log("Hello"+arguments[0]+","+arguments[1]);
}
2.没有重载
ECMAscript函数没有签名,因此其参数是由包含零个或多个值的数组来表示的,而没有函数签名则真正意义上的重载是不能实现的,但我们可以通过arguments来模拟重载
function doAdd(){
if(arguments.length==1){
return arguments[0]+10;
} else if(arguments.length==2){
return arguments[0]+arguments[1]
}
}
doAdd(10) //20
doAdd(12,10) //22