本文目录
- 1.基础概念
- 2.变量
- 3.类型转换
- 4.运算符
- 5.数字处理方法
- 6.流程控制
- 7.日期
- 8.Math对象
- 9.Boolean
- 10.异常处理
- 11.作用域
- 12.对象
1.基础概念
1.1.在页面上的输出方式
编程就是编写命令让计算机运行并得到想要的结果的一个过程,有些时候,需要在页面上输出程序的运行结果,用于调试程序,查找错误,下面来学几个输出结果的方法:
在网页中输出,显示在浏览器的body里面
输出纯文本
document.write("hello world");
输出html代码,这里的输出相当于把里面h1元素发给浏览器,浏览器会把h1元素解析生成具体的样式
document.write("hello world
")
document.write会重写页面,所以这种方法基本只会用于学习和测试使用。
- 弹出框输出
alert("hello world");
这里输出会在页面运行的时候,弹出一个对话框,里面输出hello world
- 浏览器控制台输出
这里以google为例 打开控制台的方法:在运行的页面上右键->检查->点击下面的Console
console.log("hello world");
使用console.log()命令,输出的内容都在控制台显示
1.2.输入内容
var num = prompt('请输入数字:')
alert(num)
//num即为用户输入的内容
不管输入的内容是什么,获取到的默认是字符串类型。
1.3.关键字
关键字就是JavaScript语言自身需要使用的一些单词,这些单词具有特殊的意义以及用法,因此,在程序中定义某个名称表示某种东西的时候就不能使用关键字了,会和这些关键字本身具有的意义用法起冲突,常用的关键字有 default、this、while、for、in、break、do、new、switch、var、let、const、function、case、null、undefined等等。
1.4.注释
注释就是对程序代码对一种注解,方便别人或者自己能够清晰的阅读代码,这里介绍两种注释:单行注释、多行注释
//这里是单行注释,单行注释,只能写在一行里面
/*
*这里是多行注释
*多行注释可以写在多行
多行注释以“/” 开头
*多行注释以“*/"结尾
*/
1.5.区分大小写
JavaScript 是一门区分大小写到语言。因此,就需要在编程中保持名称到一致,比如,在JavaScript中,如果this 被写成了This,因为是区分大小写到语言,this和This并不相等,在该用this到地方,用成This,程序就会出错
需要注意的是:html和css对大小写都不敏感,因此在html和css命名的时候应避免出现大小写。
1.6.运算符
运算符就是用来表示具体运算规则的符号,例如数学计算中的加减乘除就是具体的运算规则,我们分别用“+ - * /”等符号来表示
- 算术运算符
console.log(97%10);//输出7
console.log(100%10);//输出0
console.log(-97%10); //输出-7
console.log(97%-10); //输出7
%表示求两个数相除的余数,符号和被除数一致
- 比较运算符
比较运算符就是比较两个数据之间的大小,是否相等,最终得到一个布尔型的值。比较运算符包括:==, != ,> ,>=, <, <=, ===(全等于),!==(不全等于)
var a=5;
var b=6;
console.log(a>b);//false
console.log(a
比较运算符中,需要注意的是== 和 ===的区别,两个等号只是比较两边的值是否相等,三个等号不仅要比较两边的值是否相等,还要看两边的类型是否一样,只有类型和值都一样了才返回true
2.变量
声明变量的时候没有赋值,默认输出undefined
通过var 声明一个变量
var user; //默认输出undefined
可以同时声明多个变量
var user,email,password;
同时声明多个变量,并且赋值
var user="zhangsan",password="123456",email="[email protected]"
变量命名规范
1.变量名可以使用字母、数字、下划线
2.变量名只能以字母或下划线开头
3.变量名不能使用关键字和保留字,比如if else var function for switch等等
以上是强制要求,以下是大家约定俗成的规矩,这些规矩将极大提高你的代码编写或者交接或者改错效率
1.变量名做到见词达意,比如height,weight看到就知道一个是身高一个是体重,而如果你使用a,b就无从判断
2.多个单词的组合使用小驼峰(比如studentName)或者下划线(比如student_name),有些时候也会使用大驼峰(比如StudentName),也叫帕斯卡命名法。
3.虽然变量名并不是说只能用字母数字下划线,比如可以使用中文,但是 仍旧建议不要使用那三种之外的字符作为变量名的一部分
3.类型转换
3.1.强制类型转换
强制类型转换就是使用固定的方法强制把某种类型转换成另一种类型。
1.强制转换成数字类型
parseFloat和parseInt的用法一样,不同的是parseFloat可以保留小数
Number函数也是将变量转换成数字,与上面两个函数不同的是,Number只能转纯字符数字,如果字符串中只要是带有其他字符的,都会被转换成NaN
2.强制转换成字符串类型
var a=12;
a= String(a);
console.log(typeof a); //输出string
总结:转换成字符串比较简单,只需要用String(变量名)就可以了
3.强制转换成布尔值类型
因为布尔值非真即假,大多数转换结果都是真,只有少部分特殊的数据转换成假,所以布尔值转换,只需要记住哪些转换成假值就行了
总结:转换成假值(flase)的情况不多,有数字的0、-0、‘’空字符串、null、undefined、NaN,其他的数据都会被转换成true
3.2.自动类型转换
自动类型转换就是JavaScript程序在运行的过程中,根据上下文的环境,自动将类型转换成统一类型进行运算。
当value1-value2的时候是做减法运算,所以会把字符串value1和字符串value2都转换成数字进行运算,同理,value1-value4也是一样,都转换成了数字进行运算,并且是自动转换的,转换的依据就是正在做减法运算,减法运算两边必须是数字才能进行,自动类型转换的使用场景还很多。
注意
加法会优先进行拼接,比如3+‘2’,结果会变成字符串 32
+‘123’ 或者在一个变量前用加号,可以隐式转换为数字类型
4.运算符
4.1 .算数运算符
算数运算符主要有:+ - * / % ++ --,这些符号主要是用来做数字方面等运算。
自增自减运算符:
var a=1;
var b=a;
a=b++; //a=1 b=2 这一步的时候先把b赋值给a 所以a=1,b自己加1 所以b=2
b=a++; //b=1 a=2 //这一步的时候先把a=1赋值给b 覆盖来上一步b=2,所以b又等于1,然后a自己加1 a=2
a=++b; //a=2 b=2 //这一步先让b自加1等于2 然后赋值给a
console.log(a,b); //输出结果 2 2
总结:
- ++表示自己加1,-- 表示自己减1,
- 放在前面: 先自身运算,再和其他的运算符运算.
- 放在后面:先和其他的运算符运算,再自身运算
4.2.比较运算符
比较运算符就是比较两个数据之间的大小,是否相等,最终得到一个布尔型的值。比较运算符包括:==, !=, > ,>= ,< ,<= ,===(全等于) ,!==(不全等于)
var a=5;
var b=6;
console.log(a>b);//false
console.log(a
总结:比较运算符中,需要注意的是== 和 ===的区别,两个等号只是比较两边的值是否相等,三个等号不仅要比较两边的值是否相等,还要看两边的类型是否一样,只有类型和值都一样了才返回true
var a=5;
var b = "5";
console.log(a==b); //true
console.log(a===b);//false
==的坑:
console.log(0 == false) //true
4.3.三目运算符
三目运算符也叫条件运算符或者三元运算符,是用来做条件判断的,语法结构:条件?表达式1:表达式2
4>5?console.log(4):console.log(5);//5
5>4?console.log(4):console.log(5);//4
总结:三目运算符由?:组成,如果问号前面的值为true,就执行问号后面,冒号前面的代码,如果问号前面的值为false,就执行冒号后面的代码
4.4.逻辑运算符
逻辑运算符主要是用来判断一个或者多个条件同时或者其中之一是否成立。主要包括:&(与) ||(或) ! (非)
总结:1、&&表示与,也就是并且的意思,就是说运算符两边必须都要满足条件才为真,只要有假值的情况,整个结果就为假;2、||表示或的意思,就是说两边只要有一个满足条件,那么整个结果就为真,当两边都为假的时候才为假;3、!表示取反,原来为真取反为假,原来为假取反为真;4、简单记法:&& 有假为假,|| 有真为真;5、逻辑运算符会出现短路的情况,当&&前面的代码为假的时候,&&后面的代码不执行,当||前面的代码为真的时候,||后面的代码不执行
4.5.字符串链接符
字符串连接符只有一个符号“+”,JavaScript 中字符串连接符和加法中的加号一样,因此,在使用的时候需要特别注意。字符串连接符就是用来连接字符串的,类似与数学中的加法,把几个字符串拼凑在一起,行程一个更长的字符串
var a=10;
var b=10;
var c=“30“;
console.log(a+b);//输出20 此时+代表数学中的加号
console.log(a+c);//输出1030,此时+代表字符串连接符号,把a转换成来字符串 然后做连接运算
总结:字符串连接符通常用来连接变量和字符串,或者一些字符串的累加
4.6.赋值运算符
赋值运算符主要是用来给变量赋值的,常用的有以下几种:
+=: a+=b ➔ a=a+b;
-=: a-=b ➔ a=a-b;
*=: a*=b ➔ a=a*b;
/=: a/=b ➔ a=a/b;
%=: a%=b ➔ a=a%b;
总结:=号是最简单的赋值运算符,如果前面加上另外一个运算符,那么就相当于简写形式,最终表示成 a +=b -> a=a+b
4.7. 运算符的优先级
运算符的优先级就是在一个复杂的算式中到底应该先算哪个后算哪个的问题。
总结:
1、优先级越高的优先运算,不用死记,可以使用()提升优先级
2、赋值优先级最低
3、先乘除后加减
5.数值处理方法
5.1.toString()
数字类型的值调用toString(),返回值是转换后的字符串,但是在其中传入一个数字参数,也可以进行进制转换。
如:
var myNumber = 128;
myNumber.toString(16); // 返回 80
myNumber.toString(8); // 返回 200
5.2.指定小数位数
返回值是转换后的字符串,不改变原数值
参数只有一个,返回值包含了参数指定位数小数的数字
var x = 9.656;
x.toFixed(0); // 返回 10
x.toFixed(2); // 返回 9.66
x.toFixed(4); // 返回 9.6560
x.toFixed(6); // 返回 9.656000
toFixed(2) 非常适合处理金钱。
5.3.转为指定长度
toPrecision()
返回值是转换后的字符串,不改变原数值
参数只有一个,返回值包含了参数指定长度的数字
var x = 9.656;
x.toPrecision(); // 返回 9.656
x.toPrecision(2); // 返回 9.7
x.toPrecision(4); // 返回 9.656
x.toPrecision(6); // 返回 9.65600
6.流程控制
程序的流程控制就是指程序运行时,个别指令运行或求值的顺序。复杂的程序时由若干个基本结构组成,每个基本结构可以包含一条或者若干条语句。程序中语句的执行顺序称为程序结构,如果程序语句是按照书写顺序执行的,则称之为顺序结构,如果是按照某个条件来决定是否执行,则称之为选择结构,如果某些语句要反复执行多次,则称之为循环结构。程序的运行顺序就是由这3大结构控制着,所有大语句都离不开这3大结构。学会来这3大结构,就可以写出比较复杂的大程序了。
6.1.选择结构
if语句
if语句也叫做条件分支语句
//if语句语法结构:
if(条件表达式){
` 这里是表达式成立后执行的代码
}
if...else语句
if(条件表达式){
表达式成立执行这里的代码
}else{
表达式不成立执行这里的代码
}
if..else if...else if..else语句
//语法结构:
if(条件1){
代码(进程)1
}elseif(条件2){
代码(进程)2
}elseif(条件N){
代码(进程)N
}else{
以上条件都不满足,执行这里代码
}
switch语句
//语法结构:
switch(状态值){
case 状态值1:
code..1
break;
case 状态值2:
code..2
break;
case 状态值N:
code..3
break;
default:
code..4
break;
//(break在最后面可以省略,放在前面不可以省略)
}
switch的特点
1.swith之后必须有case或者default
/**
* 输入1--4分别再对应输出 春夏秋冬 ,其他的输出 “未知季节”
*/
var num = prompt('请输入:');
switch (num){
document.write('错误的写法');//这里写代码会报错
case 1:
//当用户输入1的时候,执行这里的代码
document.write('春');
break;
case 2:
//当用户输入2的时候,执行这里的代码
document.write('夏');
break;
case 3:
//当用户输入3的时候,执行这里的代码
document.write('秋');
break;
case 4:
//当用户输入4的时候执行这里的代码
document.write('冬');
break;
default:
//以上情况都不满足的时候,执行这里的代码
document.write('未知季节');
break;
}
2.break可以不写,但是后面的case会继续执行,直到遇到break或者等程序执行完毕
/**
* 输入1--4分别再对应输出 春夏秋冬 ,其他的输出 “未知季节”
*/
var num = prompt('请输入:');
switch (num){
case 1:
//当用户输入1的时候,执行这里的代码
document.write('春');
//break; 如果这里不要break,用户输入1以后,最后输出等结果会是春和夏,遇到break结束
case 2:
//当用户输入2的时候,执行这里的代码
document.write('夏');
break;
case 3:
//当用户输入3的时候,执行这里的代码
document.write('秋');
break;
case 4:
//当用户输入4的时候执行这里的代码
document.write('冬');
break;
default:
//以上情况都不满足的时候,执行这里的代码
document.write('未知季节');
break;
}
3.default可以出现在switch的任何位置.但还是其他没有匹配上才执行default
/**
* 输入1--4分别再对应输出 春夏秋冬 ,其他的输出 “未知季节”
*/
var num = prompt('请输入:');
switch (num){
default://如果default放在这里,必须加上break
//以上情况都不满足的时候,执行这里的代码
document.write('未知季节');
break;
case 1:
//当用户输入1的时候,执行这里的代码
document.write('春');
break;
case 2:
//当用户输入2的时候,执行这里的代码
document.write('夏');
break;
case 3:
//当用户输入3的时候,执行这里的代码
document.write('秋');
break;
case 4:
//当用户输入4的时候执行这里的代码
document.write('冬');
break;
}
switch语句主要是表示在某些状态下做出具体反应,又叫作状态分支语句,当不知道条件,但是知道用户输入的状态的时候,用switch状态分支会更好。以上语句的写法都是固定的,必须严格按照语法规则来写。
6.2.循环结构
for循环语句
//语法结构:
for(初始化表达式;条件表达式;条件改变表达式){
循环体;
}
实例:
//输出1-100的整数
for(var i=1;i<100;i++){
document.write(i+"
");
}
while循环语句
语法结构:
while(条件表达式){
循环体
}
实例:
var i=1; //这里类似于for循环的初始化表达式
while(i<100){ //这里为条件表达式
console.log(i);
i++;//条件改变表达式
}
总结:while循环的特点就是,当条件表达式为真的时候就执行循环体里面的内容,为假的时候就退出循环,因此,一定要搞清楚,在什么时候结束循环,不然会写出死循环代码
练习题:
一张纸的厚度是0.01毫米,对折多少次后能超过1米?
解答:
var paper = 0.01;//纸的初始厚度
var count = 0;//统计折纸次数
while(paper<1000){
paper = paper*2;
count++
}
console.log(count);
总结:while和for都可以用来做循环,那么它们各自的应用场景是什么呢?什么情况下用for,什么情况下用while?从上面的代码我们可以知道,使用for循环的话得先知道要循环多少次,这个次数是已经知道了的,而while的特点就是只要条件表达式为真就循环,否则就退出,所以,我们得出一个常用的结论,当知道循环次数的时候,用for循环要方便一些,当不知道次数,但是知道条件表达式什么时候为false,这个时候可以用while更方便一些。
do...while循环语句
语法结构:
do{
循环体
}while(条件表达式);
实例:
var i=1;
do{
console.log(i);
i++;
}while(i<=10);
总结:do while循环和while循环的用法差不多,只是do while循环比较粗暴,一上来不管三七二十一就先执行一次,执行完成了以后再去问问条件表达式是否满足条件,所以说do while循环执行循环体的次数是大于等于1次,而while循环比较温柔,先上来问问条件表达式可不可以执行,所以执行循环体的次数是大于等于0次
break,continue语句
//break;表示跳出当前循环
/**
* 当i=5时,跳出循环
*/
for(var i = 0;i<10;i++){
if(i==5){
break;//结束当前for循环,也就是说循环i只加到5就被结束掉了
}
console.log(i);
}
/**
*当i=5时,跳出本次循环
*/
for(var i=0;i<10;i++){
if(i==5){
continue;//结束本次循环,继续下次循环
}
console.log(i);
}
总结:continue和break都是用来跳出循环的,只是跳出的位置不同,break直接把循环结束掉了,而continue只是结束掉了一次循环,后面的循环还要继续。
循环嵌套
循环嵌套就是循环中有循环,这种结构需要等内层循环执行完成后才能执行外层循环。
//练习:在网页中输出99乘法表
for(var i=1;i<=9;i++){
for(var k=1;k<=i;k++){
document.write(i+"x"+k+"="+k*i+" ");
}
document.write("
");
}
7.日期
7.1 new Date()
new Date() 用当前日期和时间创建新的日期对象:
var d = new Date();
日期对象是静态的。计算机时间正在滴答作响,但日期对象不会。
new Date(year, month, ...)
new Date(year, month, ...) 用指定日期和时间创建新的日期对象。
7个数字分别指定年、月、日、小时、分钟、秒和毫秒(按此顺序):
var d = new Date(2018, 11, 24, 10, 33, 30, 0);
注释:JavaScript 从 0 到 11 计算月份。
7个数字可以依次减少,但是最少也需要有年和月
如果只提供一个参数,则将其视为毫秒。
一位和两位数年份将被解释为 19xx 年:如
var d = new Date(9, 11, 24);
//Fri Dec 24 1909 00:00:00 GMT+0800 (中国标准时间)
**new Date(dateString) **
new Date(dateString) 从日期字符串创建一个新的日期对象:
var d = new Date("October 13, 2014 11:13:00");
Mon Oct 13 2014 11:13:00 GMT+0800 (中国标准时间)
注:JavaScript 将日期存储为毫秒,并且js存储的日期在输出时会自动转换成字符串
new Date(milliseconds)
var d = new Date(100000000000);
//Sat Mar 03 1973 17:46:40 GMT+0800 (中国标准时间)
7.2 日期格式
JavaScript ISO 日期
ISO 8601 是表现日期和时间的国际标准。
ISO 8601 语法 (YYYY-MM-DD) 也是首选的 JavaScript 日期格式:
var d = new Date("2018-02-19");
//Mon Feb 19 2018 08:00:00 GMT+0800 (中国标准时间)
完整的日期加时、分和秒
写日期也可以添加时、分和秒 (YYYY-MM-DDTHH:MM:SS):
var d = new Date("2018-02-19T12:00:00");
//Mon Feb 19 2018 12:00:00 GMT+0800 (中国标准时间)
日期和时间通过大写字母 T 来分隔。
在某些浏览器中,不带前导零的月或会产生错误
7.3 获取日期方法
日期方法允许您获取并设置日期值(年、月、日、时、分、秒、毫秒)
getDate() | 以数值返回天(1-31) |
---|---|
getDay() | 以数值获取周名(0-6) |
getFullYear() | 获取四位的年(yyyy) |
getHours() | 获取小时(0-23) |
getMilliseconds() | 获取毫秒(0-999) |
getMinutes() | 获取分(0-59) |
getMonth() | 获取月(0-11) |
getSeconds() | 获取秒(0-59) |
getTime() | 获取时间(从 1970 年 1 月 1 日至今,单位毫秒) |
设置日期方法
方法 | 描述 |
---|---|
setDate() | 以数值(1-31)设置日 |
setFullYear() | 设置年(可选月和日) |
setHours() | 设置小时(0-23) |
setMilliseconds() | 设置毫秒(0-999) |
setMinutes() | 设置分(0-59) |
setMonth() | 设置月(0-11) |
setSeconds() | 设置秒(0-59) |
setTime() | 设置时间(从 1970 年 1 月 1 日至今的毫秒数) |
比较日期
var today, someday, text;
today = new Date();
someday = new Date();
someday.setFullYear(2049, 0, 16);
if (someday > today) {
text = "今天在 2049 年 1 月 16 日之前";
} else {
text = "今天在 2049 年 1 月 16 日之后";
}
document.getElementById("demo").innerHTML = text;
//今天在 2049 年 1 月 16 日之前
8.Math对象
JavaScript Math 对象
Math.PI; // 返回 3.141592653589793
8.1 四舍五入取整
Math.round(x) 的返回值是 x 四舍五入为最接近的整数
Math.round(6.8); // 返回 7
Math.round(2.3); // 返回 2
8.2 上舍取整
Math.ceil(x) 的返回值是 x 上舍入最接近的整数
Math.ceil(6.4); // 返回 7
8.3 下舍取整
Math.floor(x) 的返回值是 x 下舍入最接近的整数
Math.floor(2.7); // 返回 2
8.4 x的y次幂
Math.pow(x, y) 的返回值是 x 的 y 次幂
8.5 求平方根
Math.sqrt(x) 返回 x 的平方根
8.6 求绝对值
Math.abs(x) 返回 x 的绝对(正)值
8.7 求随机数0-1
Math.random() 返回介于 0(包括) 与 1(不包括) 之间的随机数
Math.floor(Math.random() * 10); // 返回 0 至 9 之间的数
Math.floor(Math.random() * 10) + 1; // 返回 1 至 10 之间的数
9.Boolean
所有具有“真实”值的即为 True
var a= "" //空字符串
var b=" " //空格
console.log(Boolean(a))
//false
console.log(Boolean(b))
//true
var a={
name:"zhangsan",
age:18
}
console.log(a.hi)
//undefined
哪些值为false呢?
0(零)的布尔值为 false
-0 (负零)的布尔值为 false
""(空值)的布尔值为 false
undefined 的布尔值是 false
null 的布尔值是 false
false 的布尔值是 false
NaN 的布尔值是 false
一如既往需要多注意的new,new出来的对象就算内容相同,也是===不成立的对象
var x = false;
var y = new Boolean(false);
// typeof x 返回 boolean
// typeof y 返回 object
10.异常处理
try 语句使您能够测试代码块中的错误。
catch 语句允许您处理错误。
throw 语句允许您创建自定义错误。
finally 使您能够执行代码,在 try 和 catch 之后,无论结果如何。
实例:
我们通过 adddlert 编写警告代码来故意制造了一个错误:
因为adddlert 是一个未被定义的方法,所以直接调用肯定会报错,而这个错误会被catch到
JavaScript 将 adddlert 捕获为一个错误,然后执行代码来处理该错误,这个时候,控制台不会报错。
10.1 try和catch
try 语句允许您定义一个代码块,以便在执行时检测错误。
catch 语句允许你定义一个要执行的代码块,如果 try 代码块中发生错误。
JavaScript 语句 try 和 catch 成对出现:
try {
供测试的代码块
}
catch(err) {
处理错误的代码块
}
10.2 抛出错误
当发生错误时,JavaScript 通常会停止并产生错误消息。
技术术语是这样描述的:JavaScript 将抛出异常(抛出错误)。
JavaScript 实际上会创建带有两个属性的 Error 对象:name 和 message。
10.3 throw 语句
throw 语句允许您创建自定义错误。
从技术上讲您能够抛出异常(抛出错误)。
异常可以是 JavaScript 字符串、数字、布尔或对象:
throw "Too big"; // 抛出文本
throw 500; //抛出数字
如果把 throw 与 try 和 catch 一同使用,就可以控制程序流并生成自定义错误消息。
10.4 输入验证案例
本例会检查输入。如果值是错误的,将抛出异常(err)。
该异常(err)被 catch 语句捕获并显示一条自定义的错误消息:
请输入 5 - 10 之间的数字:
10.5 finally 语句
try {
供测试的代码块
}
catch(err) {
处理错误的代码块
}
finally {
无论 try / catch 结果如何都执行的代码块
}
实例
function myFunction() {
var message, x;
message = document.getElementById("message");
message.innerHTML = "";
x = document.getElementById("demo").value;
try {
if(x == "") throw "是空的";
if(isNaN(x)) throw "不是数字";
x = Number(x);
if(x > 10) throw "太大";
if(x < 5) throw "太小";
}
catch(err) {
message.innerHTML = "错误:" + err + ".";
}
finally {
document.getElementById("demo").value = "";
}
}
10.6 Error 对象
JavaScript 拥有当错误发生时提供错误信息的内置 error 对象。
error 对象提供两个有用的属性:name 和 message。
属性 | 描述 |
---|---|
name | 设置或返回错误名 |
message | 设置或返回错误消息(一条字符串) |
error 的 name 属性可返回六个不同的值:
错误名 | 描述 |
---|---|
EvalError | 已在 eval() 函数中发生的错误,新版javascript已被SyntaxError代替 |
RangeError | 已发生超出数字范围的错误 |
ReferenceError | 已发生非法引用,如使用(引用)了尚未声明的变量 |
SyntaxError | 已发生语法错误 |
TypeError | 已发生类型错误 |
URIError | 在 encodeURI() 中已发生的错误 |
11.作用域
11.1 局部变量
JavaScript 拥有函数作用域:每个函数创建一个新的作用域。
在 JavaScript 函数中声明的变量,会成为函数的局部变量。
局部变量的作用域是局部的:只能在函数内部访问它们。
11.2 全局变量
函数之外声明的变量,会成为全局变量。
全局变量的作用域是全局的:网页的所有脚本和函数都能够访问它。
在 HTML 中,全局作用域是 window。所有全局变量均属于 window 对象。
var carName = "porsche";
// 此处的代码能够使用 window.carName
11.3 块级作用域
使用 let 在块中({})重新声明变量不会重新声明块外的变量,这和es5之前不同
使用var
var x = 10;
// 此处 x 为 10
{
var x = 6;
// 此处 x 为 6
}
// 此处 x 为 6
使用let
var x = 10;
// 此处 x 为 10
{
let x = 6;
// 此处 x 为 6
}
// 此处 x 为 10
在函数内声明变量时,使用 var 和 let 很相似,它们都有函数作用域
var和let、const的几大区别
- let、const拥有块级作用域
- let、const不能重复声明
- let、const声明不会被提前
11.4 自动全局
如果您为尚未声明的变量赋值,此变量会自动成为全局变量。
这段代码将声明一个全局变量 carName,即使在函数内进行了赋值。
myFunction();
// 此处的代码能够使用 carName 变量
function myFunction() {
carName = "porsche";
}
//所以即使在函数内部声明变量,也一定要用var
11.5 函数参数
函数参数也是函数内的局部变量。
11.6 变量提升Hoisting
提升(Hoisting)是 JavaScript 将声明移至顶部的默认行为。
Hoisting(对很多开发者来说)是 JavaScript 的一种未知的或被忽视的行为。
如果开发者不理解 hoisting,程序也许会包含 bug(错误)。
为了避免 bug,请始终在每个作用域的开头声明所有变量。
由于这就是 JavaScript 解释代码的方式,请保持这个好习惯。
严格模式中的 JavaScript 不允许在未被声明的情况下使用变量。
11.7严格模式
通过在脚本或函数的开头添加 "use strict"; 来声明严格模式。
在脚本开头进行声明,拥有全局作用域(脚本中的所有代码均以严格模式来执行):
在函数中声明严格模式,拥有局部作用域(只有函数中的代码以严格模式执行):
11.8 浮点问题
JavaScript 中的数字均保存为 64 位的浮点数(Floats)。
所有编程语言,包括 JavaScript,都存在处理浮点值的困难:
var x = 0.1;
var y = 0.2;
var z = x + y // z 中的结果并不是 0.3
为了解决上面的问题,请使用乘除运算:
var z = (x * 10 + y * 10) / 10; // z 中的结果将是 0.3
12.对象
12.1 对象字面量
var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"};
12.2 关键词new
var person = new Object();
person.firstName = "Bill";
person.lastName = "Gates";
person.age = 50;
person.eyeColor = "blue";
12.3 对象构造器
function Person(first, last, age, eye) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eye;
}
//这是一个典型的对象构造器
//建议用大写首字母对构造器函数命名
//我们可以使用new关键词调用构造器函数可以创建相同类型的对象
var myFather = new Person("Bill", "Gates", 62, "blue");
var myMother = new Person("Steve", "Jobs", 56, "green");
//除了对象之外,其它类型的数据不建议用new调用内置构造器来创建对象
不好的示范
var x1 = new Object(); // 一个新的 Object 对象
var x2 = new String(); // 一个新的 String 对象
var x3 = new Number(); // 一个新的 Number 对象
var x4 = new Boolean(); // 一个新的 Boolean 对象
var x5 = new Array(); // 一个新的 Array 对象
var x6 = new RegExp(); // 一个新的 RegExp 对象
var x7 = new Function(); // 一个新的 Function 对象
var x8 = new Date(); // 一个新的 Date 对象
应该下面这样做,可以让代码运行速度更快,同时避免很多麻烦
var x1 = {}; // 新对象
var x2 = ""; // 新的原始字符串
var x3 = 0; // 新的原始数值
var x4 = false; // 新的原始逻辑值
var x5 = []; // 新的数组对象
var x6 = /()/ // 新的正则表达式对象
var x7 = function(){}; // 新的函数对象
12.4 对象原型
我们已经认识到,您无法为已有的对象构造器添加新属性:
Person.nationality = "English";
上面这行代码添加的只是构造函数的静态属性
如需向构造器添加一个新属性,则必须把它添加到构造器函数:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
this.nationality = "English"; //新增加的
}
我们所创建的所有 JavaScript 对象都从原型继承属性和方法。
如果我们必须为对象构造器添加新属性,则可以用prototype
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
Person.prototype.nationality = "English";
//同样,也可以为构造器添加方法
Person.prototype.name = function() {
return this.firstName + " " + this.lastName;
};
请只修改您自己创建的构造器的原型。绝不要修改标准 JavaScript 对象的原型。