1 简介
JavaScript,是一种脚本语言,由ECMAScript、DOM和BOM组成。由Numbase公司最早提出,原名C--,之后更名为LiveScript。遵循ES(欧洲计算机制造联合会页面标准ECMAScript)标准,在与微软的JScript进行桌面大战后吞并了JScript,与SUN公司合作最终定名为JavaScript。是一门面向"对象"(其实有些面向过程的概念)的运行在本地客户端浏览器上的解释型(浏览器从上到下解释,没有编译过程,代码运行在HTML代码中)的弱语言。但严格区分大小写,毫无容错性。
浏览器中有两个重要引擎:标签解析器(专门解析HTML标签)、脚本解析器(解析JS脚本)。
目前JavaScript作为ES标准的首选,已经发展到遵循ES6规范。JS的语法不发生改变,变化的是ES的语法规范。
- 与Java的关系?
雷锋与雷峰塔一样,没有任何关系。
1.1 声明变量
变量没有默认值,不赋值时默认为undefined。赋值时ES5是var加变量名,赋值什么都可以,自动判断类别。ES6使用let,与ES5相同,但ES5的var有越级错误,有时外部变量的声明会取代内部变量。
1.2 数据类型
- 基本数据类型:
String、number、boolean、null、undefined - 复合数据类型:
Array(集合中不分类型,数据都可存放)、Object
1.3 引入方式
-
写在要调用这个函数的标签中
见4 常用的条件判断和循环的导入方式 -
外部引入
见5 JS的函数有没有重载?
2 运行过程
首先了解BOM (Browser Object Model浏览器对象模型,将整个浏览器看做一个对象),其中包括window(表示整个浏览器窗口)、document(表示页面上下文)、location(表示浏览器地址栏信息)、history(浏览器历史记录和缓存机制)、navigator(浏览器版本号以及浏览器信息)、screen(用户的显示器信息)、frame(页面框架)。
在BOM七个对象中,window对象是另外六个对象的顶层对象,也是全局变量,所有其它对象通过它延伸出来。所以window在调用方法等时可以不写。例如window.alert()可以省略为alert()。
真正的面向对象语言都不会存在全局变量,这里全局变量的说法让JavaScript是一个面向对象的语言这个说法成为疑点。
当HTML中的标签id重复时,JS取第一个叫这个id的元素加以作用。另外,CSS与JS关系前后无所谓,没有优先级之比。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>运行过程</title>
<script>
/* JS注释与Java的方式完全一致
* onload:在JS中凡是有on前缀的一般称之为事件(event)
* 这里的onload表示页面成功载入
* 下面的脚本表示
* 当整个窗口在成功载入后,立即执行后面的函数
* 我们这里是test函数
* */
window.onload = test;
/*
* function 函数名(实参){
* 要执行的脚本
* }
*
* 注意函数不书写返回值,如果想存在返回值
* 则加return
* */
function test(){
alert("页面加载成功啦!");
}
</script>
</head>
<body>
</body>
</html>
2.1 BOM与DOM的区别
-
Document Object Model(文档对象模型),就是把「文档」当做一个「对象」来看待;Browser Object Model(浏览器对象模型),即把「浏览器」当做一个「对象」来看待。DOM描述了处理网页内容的方法和接口,BOM描述了与浏览器进行交互的方法和接口。
-
DOM是W3C的标准 (所有浏览器公共遵守的标准)。而BOM没有标准,它是各个浏览器厂商根据DOM在各自浏览器上的实现(表现为不同浏览器定义有差别,实现方式不同)
-
DOM是BOM的一个组成部分。在DOM中,文档中的各个组件,可以通过object.attribute形式来访问。一个DOM会有一个根对象,这个对象通常就是document。而BOM除了可以访问文档中的组件之外,还可以访问浏览器的其它组件(BOM另外六个对象)。
-
window 是 BOM 最根本的对象,而非 js 对象;而DOM最根本的对象是document(window.document)
「XOM」的模型中,最应该理解的就是OM(Object Model)。Object Model表示你可以通过像操作对象一样,来操作这个 X。
对象(Object)是在编程领域中指的一种拥有具体数据(Data)并且具有(并不总是)特定行为(Behavior)的东西。例如,一个人 ,就可以看做一个对象。人的年龄、性别、身高、体重就是上文说的具体「数据」,通常将对象拥有的具体数据称作对象的「属性(Attribute)」;而人吃饭,睡觉,行走等能力,就是所说的「行为」,通常,我们把对象的行为称作对象的「方法(Method)」。
对象是可以嵌套的,也就是说,一个对象的属性也可以是对象。「像操作对象一样」最主要就是指访问对象的属性和调用对象的方法。对象的属性可以通过 object.attribute 这种形式来访问,对象的方法可以通过 object.method(arguments) 这种形式来调用。对应到 DOM 中,document 这个根对象就有很多属性,例如 title 就是 document 的一个属性,可以通过 document.title 访问;document 对象也有很多方法,例如 getElementById,可以通过 document.getElementById(nodeId) 调用。
2.2 文档对象模型(document对象)
JS语言无法直接操作HTML内的结构,需要通过一个中间件document对象(封装的DOM模型) 来对页面元素进行增删改查。
浏览器将页面的结构和样式成功载入后,会从上往下解析,根据页面结构和样式内容扫描成一个DOM模型,封装在document对象中。JS再调用document对象对HTML页面进行增删改查 。改动之后,模型发生改动,浏览器按照新的模型来刷新页面使页面结构与模型保持一致。所以,这一切的前提是确保页面结构和样式成功载入。
例:使用document对象新增一行表格
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>文档对象模型(document)</title>
<style>
table,tr,td{
border:solid 2px gray;
}
table{
/*
将table中重合的边框合并为一条单独边框
*/
border-collapse: collapse;
width:300px;
}
</style>
<script>
/*
* window.onload的前提激发事件在这里
* 如果被注释掉,则js脚本无法运行,因为
* 这个前提没了,模型在运行到此句时还没有创建完毕,
* JS无法根据id从模型中拿取元素
* */
/*
* 注意这里直接调用的是匿名函数
* 没有使用函数名
* */
window.onload = function(){
//根据id拿取button元素
let dom_button = document.getElementById("add");
//根据id拿取table
let dom_tb = document.getElementById("tb");
//onclick:当这个对象被点击时
dom_button.onclick = function(){
//通过指定名称创建一个元素
//<tr></tr>
let dom_tr = document.createElement("tr");
//修改已经创建好的tr元素内部的结构
/*
* 添加前:<tr></tr>
* 添加后:<tr><td>我是之后添加得一列</td></tr>
* */
dom_tr.innerHTML = "<td>新增一行</td>";
/*
* 将组装好的tr元素添加到table中
* 注意table中原先的子元素不受影响,直接
* 追加到原先的子元素之后
* */
dom_tb.appendChild(dom_tr);
}
}
</script>
</head>
<body>
/*button标签不能放在表单中,因为它会将表单直接提交*/
<button id="add">添加一行</button>
<table id="tb">
<tr>
<td>我是第一行</td>
</tr>
</table>
</body>
</html>
上面的代码生成的DOM模型如下:
效果:
为了确保结构、样式已加载,再创建DOM模型,更流行将JS脚本放置在body标签关闭前,即放置在全文的最下方。放置在此处不需要添加window.onload激发事件确保已加载完毕, 因为浏览器从上到下解析HTML文件,解析到script标签时,页面结构、样式已加载,DOM模型已建好。放在前面要加onload是因为需要等待页面加载、DOM模型创建完成。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>文档对象模型(document)</title>
<style>
table,tr,td{
border:solid 2px gray;
}
table{
/*
将table中重合的边框合并为一条单独边框
*/
border-collapse: collapse;
width:300px;
}
</style>
</head>
<body>
<button id="add">添加一行</button>
<table id="tb">
<tr>
<td>我是第一行</td>
</tr>
</table>
<script>
let dom_button = document.getElementById("add");
let dom_tb = document.getElementById("tb");
dom_button.onclick = function(){
let dom_tr = document.createElement("tr");
dom_tr.innerHTML = "<td>新增一行</td>";
dom_tb.appendChild(dom_tr);
}
</script>
</body>
</html>
例:使用document对象在页面上展示变量运算
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>变量运算</title>
</head>
<body onload="test()">
<script>
function test(){
let i = 10;
let j = 1.1;
let x = "test";
let y = true;
let z = null;
/*
当true与number类型相加时值为1,null与number相加时为0
与String相加时,显示结果都为拼字符串
*/
document.write(i + "+" + j + "=" + (i + j) + "<br/>");
document.write(i + "+" + x + "=" + (i + x) + "<br/>");
document.write(i + "*" + x + "=" + (i * x) + "<br/>");
document.write(i + "+" + y + "=" + (i + y) + "<br/>");
document.write(i + "+" + z + "=" + (i + z) + "<br/>");
document.write(x + "+" + y + "=" + (x + y) + "<br/>");
document.write(y + "+" + z + "=" + (y + z) + "<br/>");
document.write(z + "+" + j + "=" + (z + j) + "<br/>");
for(let a = 1; a <= 9; a++){
for(let b = 1; b <= a; b++){
//向页面上写入字符串
document.write(b + "*" + a + "=" + (a * b) + "\t");
}
document.write("<br/>");
}
}
</script>
</body>
</html>
3 常用的条件判断和循环
3.1 常用的条件判断
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>常用条件判断</title>
</head>
<!--<body onload="javascript:alert('圣诞节来临啦!')">-->
<!--<body onload="alert('圣诞节来临啦!')">-->
<body onload="test()">
<script>
function test(){
let season = 12;
if(season >= 1 && season <= 3) {
alert("Spring coming");
}else if(season >= 4 && season <= 6){
alert("Summer coming");
}else if(season >= 7 && season <= 9){
alert("Autumn coming");
}else if(season >= 10 && season <= 12){
alert("Winter coming");
}
}
</script>
</body>
</html>
3.2 常用的循环及定义数组的方式
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>常见的循环及定义数组的方式</title>
</head>
<body onload="showArray()">
<script>
function showArray(){
//定义数组的四种方式
/*
let ar = new Array(4);
ar[0] = "test";
ar[1] = 100;
ar[2] = true;
ar[3] = null;
ar[4] = undefined;
let ar = new Array();
ar[0] = "test";
ar[1] = 100;
ar[2] = true;
ar[3] = null;
ar[4] = undefined;
let ar = new Array(["test"], [100], [true], [null], [undefined]);
*/
let ar = ["test", 100, true, null, undefined];
/*
* Java(获取对象长度):
* String length()
* Array length
* List size()
*
* JS(获取对象长度):
* length
*
* */
//遍历方法1
/*for(let i = 0;i<ar.length;i++){
console.log(ar[i]);
}*/
//遍历方法2(这种方法普遍适用)
//ES5 forin进行遍历
//注意这里in之前的key表示索引值
/*for(let key in ar){
console.log(key);
console.log(ar[key]);
}*/
//遍历方法3
//ES6 forof进行遍历
//of之前的value就是值
//此循环不能用于遍历对象字面量和构造方法创建的自定义对象中的属性
//因为自定义对象中无法定义迭代器
for(let value of ar){
//在浏览器控制台上打印
console.log(value);
}
}
</script>
</body>
</html>
4 JS的函数有没有重载?
script/myjs1.js
const STR = "test";
let count = 10;
function func1(){
count++;
return count;
}
function func2(){
let obj = func1();
alert(STR);
alert(obj);
}
script/myjs2.js
function func3(){
alert("我是空参的func3");
}
function func3(flag){
alert("我是有参的func3");
}
/*
* JS没有override与overload
* 只要出现函数名重复的情况,则后写的会覆盖之前写的
* 与内部参数毫无关系
* 这里传递的参数是形参
* */
function func3(flag1, flag2, flag3){
func1();
func2();
console.log(flag1, flag2, flag3);
}
test.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>是否可以重载</title>
</head>
<body>
<!--
onblur:失去焦点
这里括号中传递的参数是实参
-->
测试:<input type="text" name="test1"
onblur="func3(100,'test',true)">
<br>
<!--
src:source的简写表示引入一个独立js文件
注意script标签要么引入,要么直接书写
两者不能共存
-->
<script src="script/myjs1.js"></script>
<script src="script/myjs2.js"></script>
</body>
</html>
5 用于字符串处理的一些方法
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>字符串处理</title>
<style>
div{
width:200px;
height:100px;
background-color:orange;
}
</style>
</head>
<body>
<!--
onmouseover:鼠标滑过
onmouseout:鼠标划出
-->
<div onmouseover="show()">
测试
</div>
<script>
function show(){
let str = "http://www.google.com";
console.log("字符串的长度是" + str.length);
//ES6新特性 模板字符串
/*
* 格式 `${要输出的值}`,简化拼串的复杂程度
* */
console.log(`字符串的长度是${str.length}`);
console.log(`从左往右第一个w的索引值是${str.indexOf("w")}`);
console.log(`从左往右最后一个w的索引值${str.lastIndexOf("w")}`);
console.log(`将e替换为a${str.replace("o","a")}`);
console.log(`根据索引值查找字符${str.charAt(5)}`);
/*
* substring(x,y)
* x:表示起始索引值
* y:表示结束索引值,但是并不包含此索引值对应的字符
* */
console.log(`截取字符串${str.substring(3,6)}`);
//分割字符串
//此处表示在.处分割
let knife = str.split(".");
for(let value of knife){
console.log(value);
}
}
</script>
</body>
</html>