[toc]
# 每日英語
1. `clipboard` 剪切板
2. `declaration` 聲明
3. `hoisting` 提升
4. `factorial` 階乘
5. `Range` 范圍
6. `Maximum` 最大值
7. `call` 調用
8. `stack` 棧(內存)
9. `queue` 隊列
10. `heap` 堆
11. `exceeded` 超越,超限
12. `overflow` 溢出
# 日歷功能
## 為 div 添加文字
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
#div1 {
width: 200px;
height: 150px;
border: 1px #000 solid;
word-wrap: break-word;
overflow-y: auto;
}
</style>
<script>
window.onload = function() {
var oDiv = document.getElementById("div1");
var oBtn = document.getElementById("btn1");
var oTxt = document.getElementById("txt1");
oBtn.onclick = function() {
oDiv.innerHTML = oTxt.value;
};
};
</script>
</head>
<body>
<input type="text" id="txt1" />
<input type="button" id="btn1" value="設置文字" />
<div id="div1"></div>
</body>
</html>
```
## 注意 innerHTML 和 innerText 的區別
> innerHTML 會解析 html 代碼
> innerText 會原樣輸出
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
#div1 {
width: 200px;
height: 150px;
border: 1px #000 solid;
word-wrap: break-word;
overflow-y: auto;
}
</style>
<script>
window.onload = function() {
var oDiv = document.getElementById("div1");
var oBtn = document.getElementById("btn1");
var oTxt = document.getElementById("txt1");
oBtn.onclick = function() {
oDiv.innerText = oTxt.value;
// oDiv.innerHTML = oTxt.value;
};
};
</script>
</head>
<body>
<input type="text" id="txt1" />
<input type="button" id="btn1" value="設置文字" />
<div id="div1"></div>
</body>
</html>
```
## 先做`onmouseover`的效果
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link href="calendar.css" rel="stylesheet" type="text/css" />
<script>
window.onload = function() {
var oDiv = document.getElementById("tab");
var aLi = oDiv.getElementsByTagName("li");
var oTxt = oDiv.getElementsByTagName("div")[0];
for (var i = 0; i < aLi.length; i++) {
aLi[i].onmouseover = function() {
for (var i = 0; i < aLi.length; i++) {
aLi[i].className = "";
}
this.className = "active";
};
}
};
</script>
</head>
<body>
<div id="tab" class="calendar">
<ul>
<li class="active">
<h2>1</h2>
<p>JAN</p>
</li>
<li>
<h2>2</h2>
<p>FER</p>
</li>
<li>
<h2>3</h2>
<p>MAR</p>
</li>
<li>
<h2>4</h2>
<p>APR</p>
</li>
<li>
<h2>5</h2>
<p>MAY</p>
</li>
<li>
<h2>6</h2>
<p>JUN</p>
</li>
<li>
<h2>7</h2>
<p>JUL</p>
</li>
<li>
<h2>8</h2>
<p>AUG</p>
</li>
<li>
<h2>9</h2>
<p>SEP</p>
</li>
<li>
<h2>10</h2>
<p>OCT</p>
</li>
<li>
<h2>11</h2>
<p>NOV</p>
</li>
<li>
<h2>12</h2>
<p>DEC</p>
</li>
</ul>
<div class="text">
<h2>1月活動</h2>
<p>快過年了,大家可以商量著去哪玩吧~</p>
</div>
</div>
</body>
</html>
```
## 再改標題(注意, 有個小問題)
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link href="calendar.css" rel="stylesheet" type="text/css" />
<script>
window.onload = function() {
var oDiv = document.getElementById("tab");
var aLi = oDiv.getElementsByTagName("li");
var oTxt = oDiv.getElementsByTagName("div")[0];
for (var i = 0; i < aLi.length; i++) {
aLi[i].index = i;
aLi[i].onmouseover = function() {
for (var i = 0; i < aLi.length; i++) {
aLi[i].className = "";
}
this.className = "active";
console.log(i);
oTxt.innerHTML =
"<h2>" +
this.index +
1 +
"月活動</h2> <p>快過年了,大家可以商量著去哪玩吧~</p>";
// oTxt.innerHTML = "<h2>" + (this.index + 1) + "月活動</h2> <p>快過年了,大家可以商量著去哪玩吧~</p>";
};
}
};
</script>
</head>
<body>
<div id="tab" class="calendar">
<ul>
<li class="active">
<h2>1</h2>
<p>JAN</p>
</li>
<li>
<h2>2</h2>
<p>FER</p>
</li>
<li>
<h2>3</h2>
<p>MAR</p>
</li>
<li>
<h2>4</h2>
<p>APR</p>
</li>
<li>
<h2>5</h2>
<p>MAY</p>
</li>
<li>
<h2>6</h2>
<p>JUN</p>
</li>
<li>
<h2>7</h2>
<p>JUL</p>
</li>
<li>
<h2>8</h2>
<p>AUG</p>
</li>
<li>
<h2>9</h2>
<p>SEP</p>
</li>
<li>
<h2>10</h2>
<p>OCT</p>
</li>
<li>
<h2>11</h2>
<p>NOV</p>
</li>
<li>
<h2>12</h2>
<p>DEC</p>
</li>
</ul>
<div class="text">
<h2>1月活動</h2>
<p>快過年了,大家可以商量著去哪玩吧~</p>
</div>
</div>
</body>
</html>
```
## 最后改內容
> 最后的`+=`代表字符串拼接
> 注意修改默認的 div 文字為數組的第一項
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link href="calendar.css" rel="stylesheet" type="text/css" />
<script>
window.onload = function() {
var aDatas = [
"一月首陽,猶有寒霜,唯有梅花獨自香",
"早春二月, 春意漸濃, 往事隨風...",
"春天來了,萬物復蘇, 又到了交配的季節...",
"人間四月天, 承載著歲月的滄桑, 承載著如詩的心語",
"除了誘惑, 我還有什么不能抗拒? 五月, 情竇初開...",
"六月的風, 纏綿, 六月的雨, 熱情...",
"七月的風和八月的雨,卑微的喜歡和遙遠的你",
"七月的風和八月的雨,滿滿的功課和無聊的假期...",
"九月江南花事休, 芙蓉宛轉在中洲. 美人笑隔盈盈水, 落日還生渺渺愁",
"十月了, 小伙伴們已經迫不及待的要給祖國慶生了!",
"十一月來了, 丹桂飄香、秋風蕭瑟、黃葉遍地",
"冰雪林中著此身,不同桃李混芳塵。"
];
var oDiv = document.getElementById("tab");
var aLi = oDiv.getElementsByTagName("li");
var oTxt = oDiv.getElementsByClassName("text")[0];
for (var i = 0; i < aLi.length; i++) {
aLi[i].aaa = i;
// aLi[i].aaa1 = i + 1;
aLi[i].onmouseover = function() {
for (var i = 0; i < aLi.length; i++) {
aLi[i].className = "";
}
this.className = "active";
oTxt.innerHTML = "";
oTxt.innerHTML +=
"<h2>" + (this.aaa + 1) + "月活動</h2>";
oTxt.innerHTML += "<p>" + aDatas[this.aaa] + "</p>";
};
}
};
</script>
</head>
<body>
<div id="tab" class="calendar">
<ul>
<li class="active">
<h2>1</h2>
<p>JAN</p>
</li>
<li>
<h2>2</h2>
<p>FER</p>
</li>
<li>
<h2>3</h2>
<p>MAR</p>
</li>
<li>
<h2>4</h2>
<p>APR</p>
</li>
<li>
<h2>5</h2>
<p>MAY</p>
</li>
<li>
<h2>6</h2>
<p>JUN</p>
</li>
<li>
<h2>7</h2>
<p>JUL</p>
</li>
<li>
<h2>8</h2>
<p>AUG</p>
</li>
<li>
<h2>9</h2>
<p>SEP</p>
</li>
<li>
<h2>10</h2>
<p>OCT</p>
</li>
<li>
<h2>11</h2>
<p>NOV</p>
</li>
<li>
<h2>12</h2>
<p>DEC</p>
</li>
</ul>
<div class="text">
<h2>1月活動</h2>
<p>一月首陽,猶有寒霜,唯有梅花獨自香</p>
</div>
</div>
</body>
</html>
```
# 什么是函數
- 函數實際上是對象。每個函數都是 Function 類型的實例,而且都與其他引用類型一樣具有屬性和方法。
- 由于函數是對象,因此函數名實際上也是一個指向函數對象的指針
- 函數通常是使用函數聲明語法定義的,如下面的例子所示。
## 定義函數的三種方式
```javascript
function sum(num1, num2) {
return num1 + num2;
}
```
- 這與下面使用函數表達式定義函數的方式一樣。
```javascript
var sum = function(num1, num2) {
return num1 + num2;
};
```
- `function` 關鍵字后面沒有函數名。(匿名函數)
- 這是因為在使用函數表達式定義函數時,沒有必要使用函數名——通過變量 sum 即可以引用函數。
- 另外,還要注意函數末尾有一個分號,就像聲明其他變量時一樣。
* 最后一種定義函數的方式是使用 Function 構造函數。 Function 構造函數可以接收任意數量的參數
* 最后一個參數始終都被看成是函數體,而前面的參數則枚舉出了新函數的參數。
```javascript
var sum = new Function("num1", "num2", "return num1 + num2"); // 不推薦
```
- 從技術角度講,這是一個函數表達式
- 不推薦讀者使用這種方法定義函數,因為這種語法會導致解析兩次代碼(影響性能)
- 第一次是解析常規 ECMAScript 代碼
- 第二次是解析傳入構造函數中的字符串
- 這種語法對于理解“函數是對象,函數名是指針”的概念倒是非常直觀的。
- 由于函數名僅僅是指向函數的指針,因此函數名與包含對象指針的其他變量沒有什么不同。
- 換句話說,一個函數可能會有多個名字
```javascript
function sum(num1, num2) {
return num1 + num2;
}
console.log(sum(10, 10));
var anotherSum = sum;
console.log(anotherSum(10, 10));
```
## 請大家思考一個問題
```javascript
function sum(num1, num2) {
return num1 + num2;
}
console.log(sum(10, 10));
var anotherSum = sum;
console.log(anotherSum(10, 10));
sum = null;
console.log(anotherSum(10, 10));
```
```javascript
function sum(a, b) {
return a + b;
}
console.log(sum()); // undefined+undefined = NaN
var anotherSum = sum();
console.log(anotherSum); // NaN
```
```javascript
function sum(a, b) {
return a + b;
}
console.log(sum()); // undefined+undefined = NaN
var anotherSum = sum();
console.log(anotherSum(10, 10)); // error, NaN不是一個函數
```
- 使用不帶圓括號的函數名是訪問函數指針,而非調用函數
# 函數沒有重載
## 什么是重載?
> 方法名相同, 但是參數類型或參數個數不同的兩個或者多個方法, 形成重載的關系
> 同一個函數, 參數不同, 干不同的事情
```javascript
function addParams(param1, param2) {
console.log("字符串相加!");
console.log(param1 + param2);
}
function addParams(param1, param2) {
console.log("數字相加");
console.log(param1 + param2);
}
addParams("123", "1");
addParams(123, 1);
```
**相當于這樣...**
```javascript
var addParams = function(param1, param2) {
console.log("字符串相加!");
console.log(param1 + param2);
};
var addParams = function(param1, param2) {
console.log("數字相加");
console.log(param1 + param2);
};
addParams("123", "1");
addParams(123, 1);
```
```javascript
function addStrParams(param1, param2) {
console.log("字符串相加!");
console.log(param1 + param2);
}
function addNumParams(param1, param2) {
console.log("數字相加");
console.log(param1 + param2);
}
addStrParams("123", "1");
addNumParams(123, 1);
```
### javascript 模擬重載
```javascript
function addParams(param1, param2) {
if (typeof param1 === "string" && typeof param2 === "string") {
console.log("字符串相加!");
}
if (typeof param1 === "number" && typeof param2 === "number") {
console.log("數字相加!");
}
console.log(param1 + param2);
}
addParams("123", "1");
addParams(123, 1);
```
# 函數聲明與函數表達式(為什么函數可以先調用后聲明)
什么是函數聲明, 什么是函數表達式?
先看一個小栗子
```javascript
function hello() {
console.log("hello world");
}
hello(); // "hello world"
```
```javascript
hello(); // "hello world"
function hello() {
console.log("hello world");
}
```
**順便插一句, 代碼壓縮的注釋問題**
```javascript
hello(); /* "hello world" */
function hello() {
console.log("hello world");
}
```
```javascript
var hello = function() {
console.log("hello world");
};
hello(); // "hello world"
```
```javascript
hello();
var hello = function() {
console.log("hello world");
};
```
```javascript
console.log(a);
var a = 123;
```
```javascript
var a;
console.log(a);
a = 123;
```
```javascript
var hello; // undefined
hello();
hello = function() {
console.log("hello world");
};
```
- 解析器在向執行環境中加載數據時,對函數聲明和函數表達式并非一視同仁。
- 解析器會率先讀取函數聲明,并使其在執行任何代碼之前可用(可以訪問)
> 函數聲明提升 (`function declaration hoisting`)
- 函數表達式,則必須等到解析器執行到它所在的代碼行,才會真正被解釋執行
# 函數的內部屬性
## arguments
- 在函數內部,有兩個特殊的對象: arguments 和 this 。
- arguments 它是一個類數組對象,包含著傳入函數中的所有參數(所有數字求和)。
- 雖然 arguments 的主要用途是保存函數參數, 但這個對象還有一個名叫 callee 的屬性,該屬性是一個指針,指向擁有這個 arguments 對象的函數。
- `arguments.callee`代表函數本身, 代表當前函數, 或者代表`這個`函數
> 來一個階乘(`factorial`)
```javascript
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * factorial(num - 1);
}
}
console.log(factorial(5));
```
如果改名字了呢?
```javascript
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * factorial(num - 1);
}
}
console.log(factorial(5));
var trueFactorial = factorial;
factorial = function() {
return 0;
};
console.log(trueFactorial(5));
console.log(factorial(5));
```
解決方案(解耦)
> 解除函數體代碼和函數名的耦合狀態
```javascript
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
console.log(factorial(5));
```
```javascript
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
console.log(factorial(5));
var trueFactorial = factorial;
factorial = function() {
return 0;
};
console.log(trueFactorial(5));
console.log(factorial(5));
```
## this
### 到底什么是 this
> this 引用的是函數據以執行的環境對象 ——(當在網頁的全局作用域中調用函數時, this 對象引用的就是 window )
> 當前發生事件的元素
> 調用函數之前, this 的值并不確定,因此 this 可能會在代碼執行過程中引用不同的對象
```javascript
window.color = "red";
var obj = {
color: "blue"
};
function sayColor() {
console.log(this.color);
}
sayColor();
window.sayColor();
window.alert("hello world");
obj.sayColor = sayColor;
obj.sayColor();
```
### 函數的調用者(this)和函數的引用者(caller)
```javascript
function outer() {
inner();
}
function inner() {
console.log(inner.caller);
}
outer();
```
當然也可以使用`arguments.callee`
```javascript
function outer() {
inner();
}
function inner() {
console.log(arguments.callee.caller);
}
outer();
```
> 注意`循環引用`會導致棧溢出
```javascript
function outer() {
inner();
}
function inner() {
console.log(arguments.callee.caller());
}
outer();
```
# 函數的屬性和方法
## length
> length 屬性表示函數希望接收的命名參數的個數
> string.length
> array.length
```javascript
function sayName(name) {
console.log(name);
}
function sum(num1, num2) {
return num1 + num2;
}
function sayHi() {
console.log("hi");
}
console.log(sayName.length);
console.log(sum.length);
console.log(sayHi.length);
```
# 模擬塊級作用域
什么是塊級作用域?
js 沒有塊級作用域會有什么結果?
```javascript
var arr = [
"The",
"quick",
"brown",
"fox",
"jumps",
"over",
"the",
"lazy",
"dog"
];
for (var index = 0; index < arr.length; index++) {
console.log(arr[index]);
}
console.log(index);
```
不只是 js, php 和 python 都沒有塊級作用域
## 解決方案
1. 函數是私有空間
```javascript
var arr = [
"The",
"quick",
"brown",
"fox",
"jumps",
"over",
"the",
"lazy",
"dog"
];
(function() {
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
})();
console.log(i);
```
2. let
```javascript
var arr = [
"The",
"quick",
"brown",
"fox",
"jumps",
"over",
"the",
"lazy",
"dog"
];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
console.log(i);
```
- 每日單詞
- JavaScript 入門
- JavaScript 基礎
- JavaScript 基礎回顧
- JavaScript 函數
- 匿名函數,多維數組,數據類型轉換
- JavaScript 類型轉換, 變量作用域
- js 運算符(一)
- js 運算符(二)
- js 流程控制語句
- JavaScript 掃盲日
- JavaScript 牛刀小試(一)
- JavaScript 牛刀小試(二)
- JavaScript 再談函數
- JavaScript-BOM
- JavaScript-定時器(一)
- JavaScript-定時器(二)
- 番外-輪播圖源碼
- JavaScript 輪播圖和 DOM 簡介
- JavaScript-DOM 基礎-NODE 接口-屬性
- JavaScript-DOM 基礎-NODE 接口-方法
- NodeList-接口-HTMLCollection-接口
- Document 節點
- CSS 復習與擴展(一)
- CSS 復習與擴展(二)
- 走進 jQuery 的世界
- 使用 jquery
- 使用 jquery-2
- jquery 中高級
- jquery 備忘清單-1
- jquery 備忘清單-2
- 聊聊 json
- jquery 備忘清單-3