# JavaScript
JavaScript 是 web 開發者必學的三種語言之一:
- *HTML* 定義網頁的內容
- *CSS* 規定網頁的布局
- *JavaScript* 對網頁行為進行編程
## 什么是JavaScript?
? JavaScript:一種直譯式腳本語言,是一種動態類型、弱類型、基于原型的語言,內置支持類型。它的解釋器被稱為JavaScript引擎,為瀏覽器的一部分,廣泛用于客戶端的腳本語言,最早是在[HTML](https://baike.baidu.com/item/HTML)(標準通用標記語言下的一個應用)網頁上使用,用來給HTML網頁增加動態功能。
? JavaScript的組成:
- 核心(*ECMAScript*)
- 文檔對象模型(*DOM*)
- 瀏覽器對象模型(*BOM*)
? JavaScript的特點:
- 腳本語言
- 基于對象
- 簡單
- 動態性
- 跨平臺性
JavaScript的引入方式:
在HTML文件中引入JS有兩種方式:第一種:內嵌式.將JS代碼直接嵌入HTML頁面中。則該JS代碼只對本頁面有效。
使用方法:在HTML頁面中使用<script></script>標簽引入。如下:
```javascript
<script>
</script>
```
? 第二種:外聯式。獨立稱為一個以.js為后綴的文件,并在HTML頁面中引入.
```javascript
<script src="../js/文件名.js" type"text/javascript" charset="utf-8"></script>
```
## JS基本語法
### 1 定義變量
#### 1)變量命名
? 與代數一樣,JavaScript 變量可用于存放值(比如 x=2)和表達式(比如 z=x+y)。變量可以使用短名稱(比如 x 和 y),也可以使用描述性更好的名稱(比如 age, sum, totalvolume)。
- 變量必須以字母開頭
- 變量也能以 $ 和 _ 符號開頭(不過我們不推薦這么做)
- 變量名稱對大小寫敏感(y 和 Y 是不同的變量)
提示:JavaScript 語句和 JavaScript 變量都對大小寫敏感。
#### 2)變量的聲明
var 變量名;//JS變量可以不聲明,直接使用。默認值:undefined
#### 3)變量的取值
var 變量名 =值;//JS變量是弱類型,即同一個變量可以洗存放不同類型數據。
```javascript
var num = 'string';//單引號與雙引號都可以表示字符串
```
### 2 數據類型
#### 六種數據類型
- ***undefined***:Undefined類型只有一個值,即undefined.l? 當聲明的變量未初始化時,該變量的默認值是 undefined。
- ***Null類型*** :另一種只有一個值的類型是 Null,它只有一個專用值 null,即它的字面量。值 undefined 實際上是從值 null 派生來的,因此 ECMAScript 把它們定義為相等的。
- ***Boolean類型*** :它有兩個值 true 和 false (即兩個 Boolean 字面量)。
- ***Number類型*** :任何數字都是number類型。
- ***String類型*** :字符或字符串。
- ***Object類型*** :對象類型,
```
String字符串:
--在js中字符串需要使用引號引起來
--使用雙引號或單引號都可以,但不能混著用
--引號不能嵌套,雙引號不能放雙引號,單引號不能放單引號,但兩者可以相互嵌套
```
### 3 運算符
#### 1)算數運算符
| 運算符 | 描述 |
| ------ | ------ |
| + | 加 |
| - | 減 |
| * | 乘 |
| / | 除 |
| % | 求余數 |
| ++ | 累加 |
| -- | 遞減 |
#### 2)賦值運算符
| 運算符 | 描述 |
| ------ | -------------- |
| = | 賦值 |
| += | 先加再賦值 |
| -= | 先減再賦值 |
| *= | 先乘再賦值 |
| %= | 先求余數再賦值 |
| /= | 先除再賦值 |
#### 3)比較運算符
| 運算符 | 描述 |
| ------ | ------------------------------- |
| == | 判斷是否等于 |
| === | 不進行數據類型轉換,判斷是否相等 |
| != | 判斷不等于 |
| > | 大于 |
| < | 小于 |
| >= | 大于等于 |
| <= | 小于等于 |
#### 4)邏輯運算符
| 運算符 | 描述 |
| ------ | :---------------------------------------------: |
| && | 邏輯與。兩個表達式均為true則結果為true |
| \|\| | 邏輯或。兩個表達式只要有一個為true,則結果為true |
| ! | 取反。 |
### 4 基本操作
#### 1) 獲取頁面元素
javascript主要是通過三種方法獲取:
```javascript
var id=document.getElementById("id") //根據元素ID值獲取
var name=document.getElementsByName("name") //根據元素NAME屬性值獲取,得到一個數組,需遍歷
var tarname=document.getElementsByTarName("tarname") //根據元素名獲取,得到一個數組,需遍歷
```
#### 2) 輸出操作
JavaScript 能夠以不同方式“顯示”數據:
- 使用 window.alert() 彈出警告框
- 使用 document.write() 向頁面中寫內容
- 使用 innerHTML 輸出HTML 元素
- 使用 console.log() 寫入瀏覽器控制臺
```html
<!DOCTYPE html>
<html>
<body>
<h1>我的第一張網頁</h1>
<p>我的第一個段落</p>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = 5 + 6;
document.write(5 + 6);
alert("你好!");
console.log("20")//日志會寫入瀏覽器控制臺,不會顯示在頁面上
</script>
</body>
</html>
```
### 5 類型轉換
#### 1) 其他類型轉換為Number
```javascript
/*
* 將其他的數據類型轉換為Number
* 轉換方式一:
* 使用Number()函數
* - 字符串 --> 數字
* 1.如果是純數字的字符串,則直接將其轉換為數字
* 2.如果字符串中有非數字的內容,則轉換為NaN
* 3.如果字符串是一個空串或者是一個全是空格的字符串,則轉換為0
* - 布爾 --> 數字
* true 轉成 1
* false 轉成 0
*
* - null --> 數字 0
*
* - undefined --> 數字 NaN
*
* 轉換方式二:
* - 這種方式專門用來對付字符串
* - parseInt() 把一個字符串轉換為一個整數
* - parseFloat() 把一個字符串轉換為一個浮點數
*/
var a = "123";
//調用Number()函數來將a轉換為Number類型
a = Number(a);
a = '1358';
a=parseInt(a);
/*
* parseFloat()作用和parseInt()類似,不同的是它可以獲得有效的小數
*/
a = "123.456";
a = parseFloat(a);
/*
* 如果對非String使用parseInt()或parseFloat()
* 它會先將其轉換為String然后在操作
*/
```
#### 2) 強制轉換
```javascript
/*
* 強制類型轉換
* - 指將一個數據類型強制轉換為其他的數據類型
* - 類型轉換主要指,將其他的數據類型,轉換為
* String Number Boolean
*
*/
a = undefined;
a = String(a); // "undefined" 強制轉換
```
### 6 進制
```javascript
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
//2 8 16 10
//0b 開頭 0B 表示二進制 。
//0 開頭 表示 8進制
//0x 開頭 0X 表示16進制
var a = 12;
var b = 070;
//alert(b); 56
var date1 = new Date();
//alert(Boolean(date1));
//當一個字符串 做 - * / 運算的時候 也會自動轉換成 number 類型 。
var str = "123";
result = str/1;
//alert( typeof result)
//alert(result)
var result = 1 + +"2" +3 ;
alert(result)
//++ --
</script>
</head>
<body>
</body>
</html>
```
### 7 超鏈接
超鏈接作用:1、跳轉頁面 2、找到錨點 3、發送郵件,打電話 4、觸發JavaScript...
```javascript
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="js/test.js" type="text/javascript" charset="utf-8">
</script>
<script type="text/javascript">
function cn(){
alert("內部的JS")
}
//超鏈接 1.跳轉頁面 2.找到錨點 3.發送郵件,打電話 4.觸發javaScript...
</script>
</head>
<body>
<p id='#'>首部</p>
<button onclick="alert('你點我了。!')">點我</button>
<a href="javascript:on()">點我</a>// 觸發js
<a href="javascript:alert('點我了 。。走你')">點我</a>
<a href="http://www.baidu.com">百度</a>// 跳轉頁面
<a href='#'>haha</a> //找到錨點
</body>
</html>
```
### 8 標識符
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
/*
* 標識符
* - 在JS中所有的可以由我們自主命名的都可以稱為是標識符
* - 例如:變量名、函數名、屬性名都屬于標識符
* - 命名一個標識符時需要遵守如下的規則:
* 1.標識符中可以含有字母、數字、_、$
* 2.標識符不能以數字開頭
* 3.標識符不能是ES中的關鍵字或保留字
* 4.標識符一般都采用駝峰命名法
* - 首字母小寫,每個單詞的開頭字母大寫,其余字母小寫
* helloWorld xxxYyyZzz
*
* - JS底層保存標識符時實際上是采用的Unicode編碼,
* 所以理論上講,所有的utf-8中含有的內容都可以作為標識符
*/
/*var if = 123;
var 小明 = 123;
console.log(if);*/
</script>
</head>
<body>
</body>
</html>
```
### 9 區分大小寫
```javascript
/* var variable
var a
var A
* 1.JS中嚴格區分大小寫
* 2.JS中每一條語句以分號(;)結尾
* - 如果不寫分號,瀏覽器會自動添加,但是會消耗一些系統資源,
* 而且有些時候,瀏覽器會加錯分號,所以在開發中分號必須寫
* 3.JS中會忽略多個空格和換行,所以我們可以利用空格和換行對代碼進行格式化
*
*/
```
## JS進階用法
### 1 創建對象
```javascript
<script type="text/javascript">
/*
new 表示在堆中新開辟一個空間 。
*
* */
//方式一 用new關鍵字創建obj對象
var obj = new Object();
obj.name = "tom";
obj.age = 20;
//alert(obj.name)
//方式二 直接用var創建對象,對象中也可以創建對象
//在js中,數組用[]裹起來,數組之間用,隔開
var obj2 = {
name:"張三",
age:20,
friend:[{
name:"tom",
age:30
},{
name:"tom2",
age:30
},{
name:"tom3",
age:30
},{
name:"tom4",
age:30
}],
var:"abc",
play:function(a,b){
alert("玩游戲!"+(a+b))
}
}
//alert(obj2.name)
//obj2.play(10,20)
//alert(obj2.friend.name);
//alert(obj2.var)
//alert("haha" in obj2);
var abc = "123";
var efg = "234";
efg = "hhh";
//alert(abc);
//alert(efg);
var jack = obj2;
jack.name="杰克";
//alert(obj2.name);
//alert(abc==efg);
alert(jack == obj)
</script>
```
### 2 創建函數
**函數是由事件驅動的或者當它被調用時執行的可重復使用的代碼塊**
#### 1) 兩種聲明方法
```javascript
//在函數中 如果變量沒有用var 聲明 。 在調用完一次函數之后,會把這個變量 提升成全局變量。
//1、聲明式函數
function 函數名(["參數列表"]){
//函數體
}
<script>
test(12);
function test(age){
console.log(age);}
//test(12)
</script>
//2、賦值式函數
var 函數名 = function(["參數列表"]){
//函數體
}
<script>
var gh = function(name) {
alert(name)
}
gh("tim");
</script>
```
#### 2) 調用函數
```javascript
// 直接調用
函數名(實參列表);
<script>
function my (a, b) {
return a * b;
}
my (10, 2);
// my (10, 2) 返回 20
</script>
//在方法中調用
定義名稱.函數名();
<script type="text/javascript">
var myObject = {
firstName: "zhang",
lastName: "san",
fullName: function() {
return this.firstName+""+this.lastName;
}}
alert(myObject.fullName());
</script>
//在構造函數中調用 用new關鍵字創造一個對象,這個對象繼承了函數的方法和屬性
<script type="text/javascript">
function Function(arg1, arg2) {
this.firstName = arg1;
this.lastName = arg2;
}
var x = new Function(“zhang", “san");
x.firstName;
</script>
//遞歸調用 在函數內部調用函數本身
function 函數名(){
代碼
函數名();
}
<script type="text/javascript">
function sum(num) {
if(num <= 1) {
return 1;
} else {
return num + sum(num - 1);
}}
console.log(sum(5));
</script>
```
#### 3) 參數
參數類型 :
形參:定義函數時使用的參數,接收調用該函數時傳遞的參數
實參:調用函數時傳遞給函數的實際參數
#### 4) 直執行函數
```javascript
//( 函數 )( 函數的參數 。 ) 用括號括起來的函數表示直接調用自己,就會直接執行這個函數
// (function a(){
// alert("哈哈")
// })();
(function b(c,d){
alert(c+d)
})(10,20);
```
### 3 continue break return
```javascript
//return 1. 表示方法的返回值 。 2. 表示跳出方法 。
function sum(a,b,c){
return a+b+c;
alert("123");
}
//var r = sum(10,20,30);
//alert(r);
//continue 只能用在循環結構 。 結束本次循環回到循環頭部繼續下次循環。
//break 表示強制跳出本層循環 。 只跳一層循環。
//當return 用在循環結構中的時候,不管多少層循環 。 直接全部跳出 。
```
### 4 this用法
```javascript
<script type="text/javascript">
var a = 10;
function fun(){
//this 誰調用方法,this就代表這個方法的調用者 。
alert( "哈哈" );
alert(this.a)//this 帶指 window對象 。
}
fun();//window.
var obj = {
name:"張三",
play:function(){
alert("張三 play...");
alert(this.name) //this指obj這個對象
}
}
obj.play();
</script>
```
### 5 原型函數prototype 構造函數constructor
**構造函數,就是提供一個生成對象的模板,并描述對象的基本結構的函數**
構造函數也是一個普通函數,創建方式和普通函數一樣,但構造函數習慣上首字母大寫
構造函數和普通函數的區別在于:調用方式不一樣
普通函數的調用方式:直接調用 person();
構造函數的調用方式:需要使用new關鍵字來調用 new Person();
```javascript
<script type="text/javascript">
//構造函數
function Person(name){
this.name=name
}
//每個函數都有一個原型函數
Person.prototype.toString = function(){
return "這個對象的名字是:"+this.name;
}
var p1 = new Person("張三");
alert(p1);
</script>
<script type="text/javascript">
//JS類 。
function Person(){
}
//prototype 類名.protorype 可以訪問到類的原型對象 。
Person.prototype.a="哈哈";
var p1 = new Person();
var p2 = new Person();
//類拿到原型對象 。 類名(構造器名稱).prototype
// 對象.__proto__ 通過這個去拿到原型對象 。
// 10W 中國
alert(Person.prototype == p1.__proto__);
p1.__proto__.a="呵呵";
alert(p2.__proto__.a);
</script>
```
### 7 數組
```javascript
//聲明一維數組 需要用到 new Array()
<script type="text/javascript">
var arr = new Array();
arr[0]=1;
arr[1]=2;
arr[2]=3;
arr[3]=4;
arr[4]=5;
arr.length=10;
for(var s in arr){
alert(s);
}
//alert(arr.length)
</script>
//聲明二維數組
<script type="text/javascript">
//int [] arr = new int [5];
var obj = new Object();
obj.name = "張三。";
var arr = [10,120,32,23,12,true,false,"132",obj];
var arr2 = [[1,2,3],[4,5,6,7,8],[9,0]];
//alert(arr2[0].length)
//alert(arr2[1].length)
// for (var i=0;i<arr2.length;i++) {
// for (var j=0;j<arr2[i].length;j++) {
// alert(arr2[i][j]);
// }
// }
var arr = ["孫悟空","豬八戒","沙和尚"];
var result = arr.push("唐僧","蜘蛛精","白骨精","玉兔精");
//push向數組后加入數據
var result2 = arr.pop();
//pop 刪除并返回最后一個數組元素
//alert(result2);
</script>
//sort 進行排序操作
<script type="text/javascript">
arr = [5,4,2,1,3,6,8,7];
//
arr.sort(function(a,b){
//升序排列
return a - b;
//降序排列
//return b - a;
});
console.log(arr);
</script>
```
## JS DOM操作
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<button id="btn">我是一個按鈕</button>
<!--
我們可以在事件對應的屬性中設置一些js代碼,
這樣當事件被觸發時,這些代碼將會執行
這種寫法我們稱為結構和行為耦合,不方便維護,不推薦使用
<button id="btn" onmousemove="alert('討厭,你點我干嘛!');">我是一個按鈕</button>
-->
<!---->
<script type="text/javascript">
/*
* 瀏覽器已經為我們提供 文檔節點 對象這個對象是window屬性
* 可以在頁面中直接使用,文檔節點代表的是整個網頁
*/
//console.log(document);
//獲取到button對象
var btn = document.getElementById("btn");
// innerTEXT =
// innerHTML =
//修改按鈕的文字
btn.innerHTML = "I'm Button";
//綁定一個單擊事件
//像這種為單擊事件綁定的函數,我們稱為單擊響應函數
btn.onclick = function(){
alert("你還點~~~");
};
</script>
</body>
</html>
```
```html
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
/*
* 瀏覽器在加載一個頁面時,是按照自上向下的順序加載的,
* 讀取到一行就運行一行,如果將script標簽寫到頁面的上邊,
* 在代碼執行時,頁面還沒有加載,頁面沒有加載DOM對象也沒有加載
* 會導致無法獲取到DOM對象
*/
/*
* onload事件會在整個頁面加載完成之后才觸發
* 為window綁定一個onload事件
* 該事件對應的響應函數將會在頁面加載完成之后執行,
* 這樣可以確保我們的代碼執行時所有的DOM對象已經加載完畢了
*
*/
window.onload = function(){
//獲取id為btn的按鈕
var btn = document.getElementById("btn");
//為按鈕綁定一個單擊響應函數
btn.onclick = function(){
alert("hello");
};
};
</script>
</head>
<body>
<button id="btn">點我一下</button>
<!--<script type="text/javascript">
/*
* 將js代碼編寫到頁面的下部就是為了,可以在頁面加載完畢以后再執行js代碼
*/
//獲取id為btn的按鈕
var btn = document.getElementById("btn");
//為按鈕綁定一個單擊響應函數
btn.onclick = function(){
alert("hello");
};
</script>-->
</body>
</html>
```
## JS BOM操作
```javascript
BOM DOM EcmaScript ...
ECMAScript無疑是JavaScript的核心,但是要想在瀏覽器中使用JavaScript,
那么BOM(瀏覽器對象模型)才是真正的核心。
BOM 提供了很多對象,用于訪問瀏覽器的功能,這些功能與任何網頁內容無關。
BOM將瀏覽器中的各個部分轉換成了一個一個的對象,我們通過修改這些對象的屬性,調用他們的方法,從而
控制瀏覽器的各種行為。
window對象是BOM的核心 ,它表示一個瀏覽器的實例。
在瀏覽器中我們可以通過window對象來訪問操作瀏覽器,同時window也是作為全局對象存在的。
全局作用域:
window對象是瀏覽器中的全局對象,因此所有在全局作用域中聲明的變量、對象、函數都會變成window對象的屬性和方法。
* - BOM對象
* Window
* - 代表的是整個瀏覽器的窗口,同時window也是網頁中的全局對象
* Navigator
* - 代表的當前瀏覽器的信息,通過該對象可以來識別不同的瀏覽器
* Location
- 代表當前瀏覽器的地址欄信息,通過Location可以獲取地址欄信息,或者操作瀏覽器跳轉頁面
History
* - 代表瀏覽器的歷史記錄,可以通過該對象來操作瀏覽器的歷史記錄
* 由于隱私原因,該對象不能獲取到具體的歷史記錄,只能操作瀏覽器向前或向后翻頁
* 而且該操作只在當次訪問時有效
/* window.history
* length
* - 屬性,可以獲取到當成訪問的鏈接數量
*/
//alert(history.length);
/*
* back()
* - 可以用來回退到上一個頁面,作用和瀏覽器的回退按鈕一樣
*/
//history.back();
/*
* forward()
* - 可以跳轉下一個頁面,作用和瀏覽器的前進按鈕一樣
*/
//history.forward();
/*
* go()
* - 可以用來跳轉到指定的頁面
* - 它需要一個整數作為參數
* 1:表示向前跳轉一個頁面 相當于forward()
* 2:表示向前跳轉兩個頁面
* -1:表示向后跳轉一個頁面
* -2:表示向后跳轉兩個頁面
*/
* Screen
* - 代表用戶的屏幕的信息,通過該對象可以獲取到用戶的顯示器的相關的信息
*
*
* 這些BOM對象在瀏覽器中都是作為window對象的屬性保存的,
* 可以通過window對象來使用,也可以直接使用
*
*
* window.location
* /*
* 如果直接將location屬性修改為一個完整的路徑,或相對路徑
* 則我們頁面會自動跳轉到該路徑,并且會生成相應的歷史記錄
*/
//location = "http://www.baidu.com";
//location = "01.BOM.html";
/*
* assign()
* - 用來跳轉到其他的頁面,作用和直接修改location一樣
*/
//location.assign("http://www.baidu.com");
/*
* reload()
* - 用于重新加載當前頁面,作用和刷新按鈕一樣
* - 如果在方法中傳遞一個true,作為參數,則會強制清空緩存刷新頁面
*/
//location.reload(true);
/*
* replace()
* - 可以使用一個新的頁面替換當前頁面,調用完畢也會跳轉頁面
* 不會生成歷史記錄,不能使用回退按鈕回退
*/
location.replace("01.BOM.html");
```
## JSON
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<!--
如果需要兼容IE7及以下的JSON操作,則可以通過引入一個外部的js文件來處理
-->
<script type="text/javascript" src="js/json2.js"></script>
<script type="text/javascript">
/*
* JSON ...
*
* var obj = [{
* "name":"zhangsan1",
* "age":"20"
* },{
* "name":"zhangsan2",
* "age":"20"
* }]
*
* JSON
* - JS中的對象只有JS自己認識,其他的語言都不認識
* - JSON就是一個特殊格式的字符串,這個字符串可以被任意的語言所識別,
* 并且可以轉換為任意語言中的對象,JSON在開發中主要用來數據的交互
* - JSON
* - JavaScript Object Notation JS對象表示法
* - JSON和JS對象的格式一樣,只不過JSON字符串中的屬性名必須加雙引號
* 其他的和JS語法一致
* JSON分類:
* 1.對象 {}
* 2.數組 []
*
* JSON中允許的值:
* 1.字符串
* 2.數值
* 3.布爾值
* 4.null
* 5.對象
* 6.數組
*/
//創建一個對象
var arr = '[1,2,3,"hello",true]';
var obj2 = '{"arr":[1,2,3]}';
var arr2 ='[{"name":"孫悟空","age":18,"gender":"男"},{"name":"孫悟空","age":18,"gender":"男"}]';
/*
* 將JSON字符串轉換為JS中的對象
* 在JS中,為我們提供了一個工具類,就叫JSON
* 這個對象可以幫助我們將一個JSON轉換為JS對象,也可以將一個JS對象轉換為JSON
*/
var json = '{"name":"孫悟空","age":18,"gender":"男"}';
/*
* json --> js對象
* JSON.parse()
* - 可以將以JSON字符串轉換為js對象
* - 它需要一個JSON字符串作為參數,會將該字符串轉換為JS對象并返回
*/
var o = JSON.parse(json);
var o2 = JSON.parse(arr);
//console.log(o.gender);
//console.log(o2[1]);
var obj3 = {name:"豬八戒" , age:28 , gender:"男"};
/*
* JS對象 ---> JSON
* JSON.stringify()
* - 可以將一個JS對象轉換為JSON字符串
* - 需要一個js對象作為參數,會返回一個JSON字符串
*/
var str = JSON.stringify(obj3);
//console.log(str);
/*
* JSON這個對象在IE7及以下的瀏覽器中不支持,所以在這些瀏覽器中調用時會報錯
*/
var str3 = '{"name":"孫悟空","age":18,"gender":"男"}';
JSON.parse(str3);
</script>
</head>
<body>
</body>
</html>
```