[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