1. js简介
JavaScript是世界上最流行的语言之一,是一种运行在客户端的脚本语言(不需要编译,运行过程中由js解释器即js引擎逐行来进行解释并执行),现在也可以基于node.js技术进行服务器端编程。
2. js组成
(1)ECMAScript:由ECMA国际进行标准化的一门编程语言,规定了js的编程语法和基础核心知识,是所有浏览器厂商共同遵守的一套js语法工业标准。
(2)DOM:document object model,文档对象模型,W3C组织推荐的处理可拓展标记语言的标准编程接口,通过DOM提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)。
(3)BOM:browser object model,浏览器对象模型,它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构,通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等。
3. js执行过程:分为预解析,代码执行两步。
(1)预解析:程序在执行过程,会先将代码读取到内存中检查,所有的声明在此时进行标记,所谓的标记就是让js解释器知道有这个名字,后面在使用名字的时候,不会出现未定义的错误,这个标记过程就是提升。
变量(标识符)声明让解释器知道有这个名字,但没有任何数据与之对应;函数声明与函数表达式(不提升)有区别,函数声明是单独写在一个结构中,不存在任何语句(赋值等)、逻辑判断等结构中,函数声明包含两部分,首先告诉解释器有这个名字存在,然后告诉解释器对应的函数体。
js引擎把js里面所有的var还有function提升到当前作用域的最前面,分为变量预解析(变量提升)和函数预解析(函数提升),变量提升就是把所有变量声明提升到当前的作用域最前面,不提升赋值操作;函数提升就是把所有函数声明提升到当前的作用域最前面,不调用函数,所以function 函数名(形参1,形参2,...) {}会将整个函数声明提升,var 变量名 = function() {}仅提升变量声明部分。
<script type="text/javascript">
var num = 1;
function num() {
alert(num);
}
num();
// 1.预解析代码,提升名字
// 1.1提升名字num
// 1.2提升函数名,但名字已经存在,因此只做第二步,让名字与函数体对应
// 1.3结论:代码中有一个函数num
// 2.执行代码
// 2.1赋值语句,num赋值为1
// 2.2覆盖了函数
// 2.3调用num,由于num中存储的是数字1,因此报错num不是函数
</script>
<script>
var num = 123;
function foo() {
console.log(num);
var num = 456;
console.log(num);
}
foo();
// 1.预解析,提升num名字和foo函数
// 2.执行第一句:num = 123;
// 3.执行函数调用:
// 3.1函数调用进入函数的一瞬间也需要预解析,解析的是变量名num
// 3.2在函数内部是一个独立地空间,允许使用外部的数据,但是现在num声明同名,即覆盖外面
// 3.2执行第一句打印num,没有数据undefined
// 3.3执行第二句赋值:num = 456
// 3.4执行第三句打印num,结果456
</script>
(2)代码执行:按照代码书写顺序从上往下执行。
<script>
function f1() {
var a = b = c = 9; // 相当于var a = 9; b = 9; c = 9; b和c直接赋值,没有var声明,全局变量
// 集体声明 var a = 9, b = 9, c = 9;此处声明有var
}
f1();
console.log(c); // 9
console.log(b); // 9
console.log(a); // 报错
</script>
4. js书写位置
(1)行内式js:推荐使用单引号,仅在少数特殊情况下使用。
<input type="button" value="点我试试" onclick="alert('Hello World')" />
(2)内嵌js(常用)
<script>
alert('Hello World~!');
</script>
(3)外部js文件
<script src="my.js"></script>
5. 注释
<script>
// 单行注释
/* 多行注释
多行注释
*/
</script>
6. 异常处理
(1)概念:程序运行过程中出现的错误,在js中出现异常后,浏览器会给出一段错误,就是错误消息,错误消息由错误类型和错误信息构成,常见的异常有两大类,运行环境的多样性和语法代码错误。
(2)try-catch:如果try中出现了错误,try里面出现错误的语句后面的代码都不再执行,直接跳转到catch里面,catch中处理错误消息,然后继续执行后面的代码,如果try中没有出现错误,那么不走catch直接执行后面的代码。
<script>
try {
console.log( abc );
} catch(e) { // error或者exception
console.log('异常啦');
}
</script>
(3)throw是抛出异常的语法,其后跟一个对象,即错误消息对象,一般用'new Error( '错误消息' )'来创建,也支持任意对象,多层函数调用时,抛出的异常如果没有被处理,会层层向外层的调用函数传递。
<script>
function showMessage( msg ) {
if( typeof msg !== 'string' ) { // 限制只能是文本字符串
throw new Error('该参数不是一个字符串'); // 抛出异常后将不再继续执行
}
console.log(msg);
}
</script>
(4)try-catch-finally
<script>
try {
// 可能出现错误的代码
} catch(e) {
// 如果出现错误将执行的代码
} finally {
// 结束try这个代码块之前执行,即不论是否异常均需要执行
}
</script>
7. js输入输出语句
方法 | 说明 | 归属 |
---|---|---|
alert(msg) | 浏览器弹出警示框 | 浏览器 |
console.log(msg) | 浏览器控制台打印输出信息 | 浏览器 |
prompt(info) | 浏览器弹出输入框,用户可以输入,返回的是字符串型 | 浏览器 |
8. 流程控制
(1)顺序结构
(2)分支结构:① if(条件表达式){ 语句1 } else if { 语句2 } else { 语句3 };② 三元表达式(条件表达式?表达式1:表达式2);③ switch(表达式){ case value:执行语句1;break;default:执行最后的语句;},当全等时执行。
(3)循环结构:① for(初始化变量;条件表达式;操作表达式){ 循环体 };② while(条件表达式){ 循环体 };③ do { 循环体 } while (条件表达式)。
(4)continue关键字用于立即跳出本次循环,继续下一次循环,循环体中continue后的语句少执行一次;break关键字用于立即跳出整个循环;还可以作为标记语言,相当于goto。
9. 变量
(1)变量声明的特殊情况
情况 | 说明 | 结果 |
---|---|---|
var age; console.log(age); | 只声明,不赋值 | undefined |
console.log(age); | 不声明,不赋值,直接使用 | 报错 |
age = 10; console.log(age); | 不声明,只赋值 | 10 |
(2)变量命名规范:由字母、数字、下划线、美元符号$组成;严格区分大小写;不能以数字开头;不能是关键字、保留字;变量名必须有意义;遵循驼峰命名法,首字母小写,后面单词的首字母需要大写。
(3)全局变量和局部变量:没有块级作用域,即{}内部声明的变量,{}外部也可以使用。
<script>
var num1 = 10; // 全局变量,只有浏览器关闭时才会销毁,占用资源
function fun(aru) { // 函数的形参也看做是局部变量
var num2 = 20; // 局部变量,程序执行完即销毁,节约资源
num3 = 30; // 只赋值未声明的变量视为全局变量
}
console.log(num2); // 报错,未声明
console.log(num3); // 30
</script>
(4)作用域链:当函数多层嵌套,且不同函数内声明有相同的变量时,内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,即就近原则。