目录
JavaScript简介
JS组成
JS用途
JavaScript书写位置
基本语法
变量
注释
数据类型
number
数值判断
数值转换
string
boolean
操作符(operator)
语句
系统对话框
本章总结
JavaScript是一种解释型脚本语言,目的是能够在客户端的网页中增加动态效果和交互能力,实现了用户与网页之间的一种实时的、动态的交互关系。
它最初是由网景公司设计的,起名为LiveScript,后来Java语言非常红火,网景公司希望借助Java的名气来推广,改名为JavaScript,但是除了语法有点相似,在其他部分基本上没啥关系。
后来,JavaScript被Netscape公司交给ECMA制定标准,成为ECMAScript,最新版ECMAScript6(简称ES6)已经在2015年6月正式发布了。
JS组成:ECMAScript(JS的核心)、DOM(文档对象模型)、BOM(浏览器对象模型)
+ ECMAScript:主要定义了JS的语法
+ DOM:一套操作页面元素的API,DOM可以把HTML看做是文档树,通过DOM提供的API可以对树上的节点进行操作
+ BOM:一套操作浏览器功能的API,通过BOM可以操作浏览器窗口
主要用于网页特效、服务端开发、命令行工具、桌面程序、APP、控制硬件—物联网、游戏开发
写在行内
写在script标签中
由包含的代码就是JavaScript代码,他将直接被浏览器执行。
写入外部js文件中,在页面引入
把代码放在单独的文件中更有利于维护代码,并且多个页面可以各自引用同一个.js文件。
JavaScript语法和Java相似,每个语句以;结束,语句块用{···}。
注意:JavaScript严格区分大小写。
变量的概念: 一个变量就是分配了一个值的参数。使用变量可以方便的获取或者修改内存中的数据
变量的声明: 在声明变量时使用关键字var
,要注意关键字与变量名之间的空格,也可以在一行中声明多个变量,以逗号分隔变量。
var age;
var age, name, sex;
age = 10;
name = 'zs';
注意: 变量名必须是一个JavaScript标识符,应遵循以下标准命名规则:
变量的赋值: 在JavaScript中,使用=
对变量进行赋值。可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同的数据类型的变量,但是只能用var
申明一次。要显示变量,可以用console.log(x)
,打开Chrome的控制台就可以看到结果。
var age;
age = 18;
var age=18;
以//开头直到行末的字符被视为注释,注释是给开发人员看的,JavaScript引擎会自动忽略。
另一种块注释是用/*
···*
/把多行字符包裹起来,视为注释。
例如:
···
JSd的数据类型分为两大类:
JavaScript不区分整数和浮点数,统一用number表示,以下都是合法的number类型:
123;//整数123
0.456;//浮点数0.456
1.2345e3;//等同于1234.5
-99;//负数
NaN;//当无法计算结果是使用NaN表示
Infinity;//表示无限大
number存在精度问题:
0.2 + 0.1 = 0.30000000000000004
0.1 + 0.2 !== 0.3 //true
所以最好不要判断浮点数是否相等。
NaN:Not a Number 不是一个number
NaN==NaN ==>false
isNaN():判断是否是number类型
isNaN(NaN) ===> true
isNaN(10) ===> false
isNaN("10") ===> false //将字符串隐性的转换为number类型
isNaN(false) ===> false //将boolean转为number类型
Number():
转换规则:
boolean => 1 或 0
number => 直接返回
undefined => NaN
null => 0
string => 字符串只包含数字–>十进制数值
字符串包含有效浮点格式–>对应浮点数值
字符串包含十六进制–>十进制
其他格式–>NaN
object =>调用valueOf(),然后依照前面规则转换。如果结果为NaN,调用对象的toString(),然后依照前面的规则转换
console.log(Number(true)); //1
console.log(Number(1)); //1
console.log(Number(undefined)); //NaN
console.log(Number(null)); //0
console.log(Number("123")); //123
console.log(Number('-1')); //-1
console.log(Number("1.1")); //1.1
console.log(Number("011")); //11
console.log(Number(".1")); //0.1
console.log(Number("0xf")); //15
console.log(Number("123a")); //NaN
console.log(Number("a123")); //NaN
console.log(Number("a.1")); //NaN
console.log(Number("0xabc")); //2748
console.log(Number("0xabg")); //NaN
console.log(Number("")); //0
0x
开头所组成的字符串,符合要求可看作十六进制数,然后进行转换,结果为十进制parseInt("1234blue"); //1234
parseInt(""); //NaN
parseInt("0xA"); //10
parseInt("070"); //70
parseInt(true); //NaN
parseInt("22.5"); //22
parseInt(22.5); //22
parseInt("a123"); //NaN
在ECMAScript 3中,parseInt(“070”);的结果为56,因为他将以0开头的看作八进制进行转换,而ES5已经不具备解析八进制的能力,所以我们可以通过给parseInt()传递参数来解决这个问题(通过参数来说明要转换的数据是几进制)
parseInt("070",8); //56
parseInt("AF",16); //175
parseFloat("0xA"); //0
parseFloat("22.34.5"); //22.34
parseFloat("3.125e7"); //31250000
parseFloat("123a"); //123
parseFloat(true); //NaN
+"123" //123
-"123" //123
+ true //1
+"123abc" //NaN
-0
操作时,也会隐性的进行数值转换 '123'-0 //123
true-0 //1
'123abc'-0 //NaN
用于表示由零个或多个16位Unicode字符组成的字符序列,即字符串。字符串是以单引号'或双引号"括起来的任意文本,比如'abc'、"xyz"等等。 单引号和双引号只是一种表示方式,不是字符串的一部分,所以,字符串'abc'中只有a、b、c这3个字符。
特点: 不可变的
当重新为一个字符串赋值时,实际上是重新开辟内存空间,例如:
var lang="Java";
lang=lang+"Script";
以上代码是先创建一个空间存放字符串“Java”,接着在运行到下一行代码时,在内存中重新开辟一个空间,存放的是"JavaScript",变量lang指向新开辟的空间。这些操作都是后台发生的,影响网站性能,所以一般代码中不要写大量的字符串拼接。
转为字符串
转为字符串的方法有:
var num=10;
num.toString(); //"10"
num.toString(2); //"1010"
num.toString(8); //"12"
num.toString(10); //"10"
num.toString(16); //"a"
String():
在不知道转换值是不是null、undefined时,可以使用String()转换
转换规则:
如果值有toString()方法,调用toString()(没有参数)并返回
如果是null,返回"null"
如果是undefined,返回"undefined"
String(10); //"10"
String(true); //'true'
String(null); //'null'
18+"" //"18"
true+"" //'true'
布尔值和布尔代数的表示完全一样,一个布尔值只有true和false两种值,区分大小写。可以直接用true和false表示布尔值,也可以通过布尔运算算出来:
转为boolean值
Boolean()
将一个值转换为其对应的boolean值
转为false的值:
布尔值经常用在条件判断句中。
null和undefined
null表示一个“空”的值,他和0以及空字符串’‘不同,0是一个数值,’'表示长度为0的字符串,而nul表示空。
undefined表示“未定义”。
object
一组数据和功能的集合。可以通过执行new操作符后跟要创建的对象类型的名称来创建,而创建Object类型的实例并为其添加属性或方法。
var student={
name:'LullabyLY',
age:20,
num:xxxxxxxx
};
//也可以是
var student=new Object();
student.name='LullabyLY';
...
要获取一个对象的属性,我们用对象变量.属性名的方法:
student.name;//'LullabyLY'
student.num;//xxxxxxxx
object的每个实例都有下列属性或方法:
typeof
获取变量类型,返回的值是string类型
结果有:
typeof 10 //"number"
typeof "10" //"string"
function fn(){
...
}
typeof fn //"function"
//age未声明
typeof age //"undefined"
typeof null //"object"
typeof undefined //"undefined"
typeof将null的类型定为object是因为 null被认为是空的对象引用
操作符包括:
一元操作符
一元操作符只有一个操作数
1.递增(++)和递减(–)操作符
可用于字符串、布尔值、浮点数、整数和对象,操作数自加1或自减1
分为:前置型、后置型
在语句中,前置型先进行自加或自减,再执行操作
var age=29;
++age; //30
--age; //29
在语句中,先进行操作,再进行自加或自减
var age=29;
age++; //30
age--; //29
单独看不能发现两者的区别,看以下例子,能够明显的看出前置与后置的区别:
var age1=29;
var anotherAge1= --age + 2; //30
var age2=29;
var anotherAge2= age-- + 2; //31
递增和递减操作遵循规则:
应用于包含有效数字字符的字符串时,先将其转换为数字值,再执行加减1的操作
应用于不包含有效数字字符的字符串时,将变量的值设置为NaN
应用于boolean值时,先将其转换为数值,在执行操作
应用于浮点数时,直接执行操作
应用于对象时,先调用valueOf(),如果结果正确,直接执行操作;如果结果为NaN,调用toString()在执行操作
2.一元加减操作
一元加(+)、减(-)操作符:
一元减操作符主要用于表示负数,一元减操作符的转换规则和一元加操作符一样
var s1 = +"01"; //1
var s2 = +1.1; //1.1
var s3 = +"1.1"; //1.1
var s4 = +"z; //NaN
var s5 = +false; //0
var s6 = {
valueOf:function(){
return -1;
}
};
s6=+s6; //-1
var s1 = -"01"; //-1
var s2 = -1.1; //-1.1
var s3 = -"1.1"; //-1.1
var s4 = -"z; //NaN
var s5 = -false; //0
var s6 = {
valueOf:function(){
return -1;
}
};
s6=-s6; //1
位操作符
按内存中表示数值的位来操作数值,先将64位的值转换为32位,执行位操作,再转换回64位数值
NaN、Infinity当0来处理,非数值调用Number()
返回数值的反码。本质: 操作数的负值减1。
按位非是数值表示的最底层执行操作,所以速度比取负减1更快
var num=25;
num=~num; //-26
有两个操作数。本质: 将两个数值的每一位对齐,对相同位置上的两个数执行AND操作:
1 & 1=>1
1 & 0=>0
0 & 1=>0
0 & 0=>0
var result=25 & 3; //1
以上例子是将25和3转换位二进制,逐位进行AND操作
var result=25 | 3; //27
var result=25 ^ 3; //26
var num=2;
num=num<<5; //64
以上例子是将2转为二进制10,将10向左移动5位,添0,即1000000,就是二进制的64
var num=64;
num=num>>5; //2
var num=-2;
num=num>>5; //-1
var num=-64;
num=num>>>5; //134217726
布尔操作符(逻辑运算符)
true && true => true
true && false => false
false && true => false
false && false => false
逻辑与操作可以应用于任何类型的操作数,而不仅仅是布尔值,在有一个操作数不是布尔值的情况下,逻辑与操作不一定返回布尔值:
1.如果第一个操作数是对象,则返回第二个操作数
2.如果第二个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才返回该对象
3.如果两个操作数都是对象,则返回第二个操作数
4.如果第一个操作数是null,则返回null
5.如果第一个操作数是NaN,则返回NaN
6.如果第一个操作数是undefined,则返回undefined
逻辑与是短路操作,即如果第一个操作数能够决定结果,那么就不会对第二个操作数求值。逻辑与操作中,当第一个操作数是false时,则无论第二个操作数是什么值,结果都是false
var found=true;
var result=found&&someElement; //报错
var found=false;
var result=found && someElement; //不会发生错误,result为false
true || true => true
true || false =>true
false || true => true
false || false => false
与逻辑与相似,如果有一个操作数不是布尔值,则结果不一定是布尔值:
1.如果第一个操作数是对象,则返回第一个操作数
2.如果第一个操作数的求值结果为false,则返回第二个操作数
3.如果两个操作数都是对象,则返回第一个操作数
4.如果两个操作数都是null,则返回null
5.如果两个操作数都是NaN,则返回NaN
6.如果两个操作数都是undefined,则返回undefined
逻辑或也是短路操作
var found=true;
var result=found&&someElement; //报错
var found=false;
var result=found && someElement; //不会发生错误,result为false
将他的操作数转为一个布尔值,然后求其反
1.如果操作数是对象,则返回false
2.如果操作数是一个空字符串,则返回true
3.如果操作数是一个非空字符串,则返回false
4.如果操作数是0,则返回true
5.如果操作数是任意非0数值(包括Infinity),则返回false
6.如果操作数是null,则返回true
7.如果操作数是NaN,则返回true
8.如果操作数是undefined,则返回true
!false; //true
!"blue"; //false
!0; //true
!NaN; //true
!""; //true
!12345; //false
!!
模拟Boolean()转型函数,获得一个值对应的布尔值
乘性操作符
用于计算两个操作数的乘积
处理特殊值的规则:
1.有一个操作数是NaN===>NaN
2.Infinity * 0==>NaN
3.Infinity * 非0数值===>Infinity/-Infinity(取决于符号)
4.Infinity * Infinity===>Infinity
5.乘积超过数值的表示范围 ,返回Infinity/-Infinity(取决于符号)
6.如果有一个操作数不是数值,在后台调用Number(),然后应用上面的规则
处理特殊值的规则:
1.有一个操作数是NaN===>NaN
2.0 / 0,返回NaN
3.非0数值 * 0,返回Infinity/-Infinity(取决于符号)
4.Infinity / Infinity,返回NaN
5…Infinity /任意非0数值,返回Infinity/-Infinity(取决于符号)
6.乘积超过数值的表示范围 ,返回Infinity/-Infinity(取决于符号)
7.如果有一个操作数不是数值,在后台调用Number(),然后应用上面的规则
返回余数
处理特殊值的规则:
1.被除数无穷大而除数有限大(无穷大%有限大),返回NaN
2.有限大的值 % 0,返回NaN
3.被除数有限大除数无穷大,返回被除数
4.Infinity % Infinity,返回NaN
5.0%任意数,返回0
6.如果有一个操作数不是数值,在后台调用Number(),然后应用上面的规则
加性操作符
如果两个操作数都是数值,执行常规的加法计算,然后根据规则返回结果
1.如果有一个操作数是NaN,则返回NaN
2.Infinity + Infinity = Infinity
3.-Infinity + -Infinity = -Infinity
4.Infinity + -Infinity = NaN
5.+0 + +0 = +0
6.-0 + -0 = -0
7.+0 + -0 = +0
8.有一个操作数是字符串:①如果两个操作数都是字符串,则第二个操作数与第一个操作数拼接起来;②如果只有一个操作数是字符串,则将另一个操作数转换为字符串,饭后拼接起来
9.如果有一个操作数是对象、数值、或布尔值,则调用他们的toString()方法取得对应的字符串值,在应用前面的规则
10.对于null、undefined,调用String()获得字符串值
var num=5+5; //10
var result=5+"5"; //55
var num1=5;
var num2=10;
var message="The sum of 5 and 10 is "+num1+num2;
//"The sum of 5 and 10 is 510"
规则:
1.如果有一个操作数是NaN,则返回NaN
2.Infinity - Infinity = NaN
3.-Infinity - -Infinity = NaN
4.Infinity - -Infinity = Infinity
5.-Infinity - Infinity = -Infinity
6.+0 - +0 = +0
7.-0 - +0 = -0
8.-0 - -0 = +0
9.有一个操作数是字符串、布尔值、null或undefined:先在后台调用Number()函数将其转换为数值,然后根据前面的规则执行
10.如果有一个操作数是对象,则调用valueOf()取得该对象的数值,如果得到NaN,则减法结果为NaN;如果没有valueOf(),则调用toString()方法取得对应的字符串值,并将其转换为数值。
var num1=5-true; //4
var num2=NaN-1; //NaN
var num3=5-3; //2
var num4=5-""; //5
var num5=5-"2"; //3
var num6=5-null; //5
关系操作符
小于(<)、大于(>)、小于等于(<=)、大于等于(>=)
相等运算符
实际上,JavaScript允许对任意数据类型作比较,但特别要注意相等于算符。JavaScript在设计时,有两种比较运算符:
第一种是==,它会自动转换类型再比较。!=:不相等
第二种是===,他不会自动转换类型,如果两个表达式(包括他们的数据类型)相等,则结果为true。!==:不全等
注意: NaN与其他的值都不想等,包括他自己,唯一能判断NaN的方法是通过isNaN()函数:
isNaN(NaN);//true
最后要注意的浮点数的比较:
Math.abs(1/3-(1-2/3))<0.0000001;//true
1.如果有一个布尔值,将布尔值转换为数值
2.有一个字符串,另一个是数值,则将字符串转换为数值
3.一个是对象,另一个不是,则调用valueOf(),将得到的值按照 前面的规则执行
4.null和undefined是相等的
5.在比较相等前,不能将null和undefined转换为其他值
6.有一个是NaN,则结果是 false
7.两个操作数都是对象,则比较他们是不是同一个对象
null==undefined //true
"NaN"==NaN //false
5==NaN //false
NaN==NaN //false
NaN!=NaN //true
false==0 //true
true==1 //true
true==2 //false
undefined==0 //false
null==0 //false
"5"==5 //true
null===undefined //false
条件操作符
条件操作符就是三元表达式。
variable=boolean_expression?true_value:false_value
var max=(num1>num2)?num1:num2
上面的例子是说,当num1大于num2时,max等于num1,否则等于num2
赋值操作符
简单的赋值操作符就是=,其作用就是把右边的值赋给左边的变量
复合赋值操作符:
逗号操作符
使用逗号操作符可以在一条语句中执行多个操作
var num1=1,num2=9,num4=8;
var num=(5,6,7,2,0);//num=0
运算符的优先级
ECMA-262规定了一组语句,也叫做流控制语句
if (/* 条件表达式 */) {
// 执行语句
}
if (/* 条件表达式 */){
// 成立执行语句
} else {
// 否则执行语句
}
if (/* 条件1 */){
// 成立执行语句
} else if (/* 条件2 */){
// 成立执行语句
} else if (/* 条件3 */){
// 成立执行语句
} else {
// 最后默认执行语句
}
do {
// 循环体;
} while (循环条件);
代码示例:
// 初始化变量
var i = 1;
var sum = 0;
do {
sum += i;//循环体
i++;//自增
} while (i <= 100);//循环条件
// 当循环条件为true时,执行循环体,
// 当循环条件为false时,结束循环。
while (循环条件) {
//循环体
}
代码示例:
// 计算1-100之间所有数的和
// 初始化变量
var i = 1;
var sum = 0;
// 判断条件
while (i <= 100) {
// 循环体
sum += i;
// 自增
i++;
}
console.log(sum);
while和do…while一般用来解决无法确认次数的循环。for循环一般在循环次数确定的时候比较方便
for循环语法:
// for循环的表达式之间用的是;号分隔的,千万不要写成,
for (初始化表达式1; 判断表达式2; 自增表达式3) {
// 循环体4
}
执行顺序:1243 ---- 243 -----243(直到循环条件变成false)
案例:
//打印正方形
// 使用拼字符串的方法的原因
// console.log 输出重复内容的问题
// console.log 默认输出内容介绍后有换行
var start = '';
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
start += '* ';
}
start += '\n';
}
console.log(start);
迭代语句,用来枚举对象的属性
在使用for-in循环之前,先检测该对象的值是否是null、undefined,对象若为null、undefined,不执行for-in循环体
语法:
for(property in expression) statement
实例:
循环输出对象的值
var o={
name:"ly",
age:23,
sex:'女'
}
for(var key in o){
console.log(o[key]);
}
可以在代码中添加标签,以便将来使用
语法:
label:statement
示例
start:for(var i=0;i
这个示例中定义的start标签可以在将来由break、continue语句引用。加标签的语句一般都要与for循环语句配合使用
实例:
var num = 0;
outPoint:
for (var i = 0 ; i < 10 ; i++){
for (var j = 0 ; j < 10 ; j++){
if( i == 5 && j == 5 ){
break outPoint;
}
num++;
}
}
alert(num);
var num=0;
for(var i=1;i<10;i++){
if(i%5==0){
break;
}
num++;
}
alert(i); //4
var num=0;
for(var i=1;i<10;i++){
if(i%5==0){
continue;
}
num++;
}
alert(i); //8
with (expression) statement;
实例:
var qs=location.search.substring(1);
var url=location.href;
//用with语句
with(location){
var qs=search.substrinf(1);
var uel=href;
严格模式下不允许使用with语句,将视为语法错误
语法格式:
switch (expression) {
case 常量1:
语句;
break;
case 常量2:
语句;
break;
case 常量3:
语句;
break;
…
case 常量n:
语句;
break;
default:
语句;
break;
}
break可以省略,如果省略,代码会继续执行下一个case
switch 语句在比较值时使用的是全等操作符, 因此不会发生类型转换(例如,字符串’10’ 不等于数值 10)
函数
函数对任何语言来说都是核心的概念。通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。ECMAScript中的函数由function关键字来声明,后跟一组参数以及函数体。
语法:
function functionName(arg0,arg1...){
statement
}
示例:
function sayHi(name,message){
alert("Hello "+name+","+message);
}
sayHi("ly","how are you?");//函数的调用
返回值
ECMAScript中的函数定义时可以有返回值,也可以没有返回值。当函数执行完的时候,并不是所有时候都要把结果打印。我们期望函数给我一些反馈(比如计算的结果返回进行后续的运算),这个时候可以让函数返回一些东西。也就是返回值。函数通过return返回一个返回值
返回值语法:
//声明一个带返回值的函数
function 函数名(形参1, 形参2, 形参...){
//函数体
return 返回值;
}
//可以通过变量来接收这个返回值
var 变量 = 函数名(实参1, 实参2, 实参3);
函数的调用结果就是返回值,因此我们可以直接对函数调用结果进行操作。
返回值详解:
如果函数没有显示的使用 return语句 ,那么函数有默认的返回值:undefined
如果函数使用 return语句,那么跟再return后面的值,就成了函数的返回值
如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值也是:undefined
函数使用return语句后,这个函数会在执行完 return 语句之后停止并立即退出,也就是说return后面的所有其他代码都不会再执行。
参数
ECMAScript不介意传递的参数的个数,也不在乎参数的数据类型。ECMAScript中的参数是由一个数组来表示的,函数体内部可以通过arguments对象来访问这个参数数组。arguments对象只是与数组类似(不是Array实例)。
- 形式参数:在声明一个函数的时候,为了函数的功能更加灵活,有些值是固定不了的,对于这些固定不了的值。我们可以给函数设置参数。这个参数没有具体的值,仅仅起到一个占位置的作用,我们通常称之为形式参数,也叫形参。
- 实际参数:如果函数在声明时,设置了形参,那么在函数调用的时候就需要传入对应的参数,我们把传入的参数叫做实际参数,也叫实参。
var x = 5, y = 6;
fn(x,y);
function fn(a, b) {
console.log(a + b);
}
//x,y实参,有具体的值。函数执行的时候会把x,y复制一份给函数内部的a和b,函数内部的值是复制的新值,无法修改外部的x,y
函数没有重载
变量预解析
变量提升:把变量的声明提升到当前作用域的最上面,不包括赋值
函数提升:将函数的声明提升到当前作用域的最上面,不包括调用
在与解析过程中,如果函数名和变量名相同,函数优先
输出undefined
var a=5;
function num(){
alert(a);
var a=10;
}
num();
/*
* 预解析过程:
* var a;
* function num(){
* var a;
alert(a);
a=10;
}
* a=5;
* num();
* 所以,在调用函数时,先在局部作用域查找a,有a,此时a没有赋值,所以是undefined
* */
输出
ƒ b() {
console.log(b);
}
1
console.log(b);
function b() {
console.log(b);
}
var b=1;
console.log(b);
/*
* 预解析:
* 在预解析过程中,如果函数名和变量名相同,函数优先
* var b;
*function b() {
console.log(b);
}
* console.log(b);
b=1;
console.log(b);*/
输出
1
1
1
1
1
报错
f1();
console.log(y);
console.log(z);
console.log(x);
function f1() {
var x=y=z=1;
console.log(x);
console.log(y);
console.log(z);
}
/*
* var x=y=z=1;
* var x=1;
* y=1;
* z=1;
* */
练习小作业: