diff --git a/04-JavaScript基础/17-函数.md b/04-JavaScript基础/13-函数.md
similarity index 93%
rename from 04-JavaScript基础/17-函数.md
rename to 04-JavaScript基础/13-函数.md
index b01a3d7..ae46480 100644
--- a/04-JavaScript基础/17-函数.md
+++ b/04-JavaScript基础/13-函数.md
@@ -44,15 +44,12 @@ function sayHello(){
}
```
-## 函数的定义
-
-
-### 方式一:函数声明(命名函数)
+## 函数的定义/声明
+### 方式一:利用函数关键字自定义函数(命名函数)
使用`函数声明`来创建一个函数(也就是 function 关键字)。语法:
-
```javascript
function 函数名([形参1,形参2...形参N]){ // 备注:语法中的中括号,表示“可选”
语句...
@@ -84,7 +81,7 @@ PS:在有些编辑器中,方法写完之后,我们在方法的前面输入
使用`函数表达式`来创建一个函数。语法:
```javascript
-var 变量名/函数名 = function([形参1,形参2...形参N]){
+var 变量名 = function([形参1,形参2...形参N]){
语句....
}
```
@@ -97,6 +94,15 @@ var fun2 = function() {
};
```
+解释如下:
+
+
+- 上面的 fun2 是变量名,不是函数名。
+
+- 函数表达式的声明方式跟声明变量类似,只不过变量里面存的是值,而函数表达式里面存的是函数。
+
+- 函数表达式也可以传递参数。
+
从方式二的举例中可以看出:所谓的“函数表达式”,其实就是将匿名函数赋值给一个变量。
### 方式三:使用构造函数 new Function()
@@ -111,7 +117,6 @@ var 变量名/函数名 = new Function('形参1', '形参2', '函数体');
注意,Function 里面的参数都必须是**字符串**格式。也就是说,形参也必须放在**字符串**里;函数体也是放在**字符串**里包裹起来,放在 Function 的最后一个参数的位置。
-
代码举例:
```javascript
@@ -147,7 +152,6 @@ fun3(1, 2); // 调用函数
## 函数的调用
-
### 方式1:普通函数的调用
函数调用的语法:
@@ -281,7 +285,6 @@ new Fun3();
-
**形参:**
- 概念:形式上的参数。定义函数时传递的参数,当时并不知道是什么值。
@@ -332,7 +335,7 @@ helloworld
- 如果实参的数量多余形参的数量,多余实参不会被赋值。
-- 如果实参的数量少于形参的数量,多余的形参会被定义为 undefined。表达式的运行结果为 NaN
+- 如果实参的数量少于形参的数量,多余的形参会被定义为 undefined。表达式的运行结果为 NaN。
代码举例:
@@ -377,7 +380,7 @@ return 的作用是结束方法。
- return 的值将会作为函数的执行结果返回,可以定义一个变量,来接收该结果。
-- 在函数中,return后的语句都不会执行(函数在执行完 return 语句之后停止并立即退出)
+- 在函数中,return后的语句都不会执行(函数在执行完 return 语句之后停止并立即退出函数)
- 如果return语句后不跟任何值,就相当于返回一个undefined
@@ -387,7 +390,6 @@ return 的作用是结束方法。
- return 只能返回一个值。如果用逗号隔开多个值,则以最后一个为准。
-
## 函数名、函数体和函数加载问题(重要,请记住)
我们要记住:**函数名 == 整个函数**。举例:
@@ -420,7 +422,6 @@ function fn(){
- return :1、退出循环。2、返回 return 语句中的值,同时结束当前的函数体内的代码,退出当前函数。
-
## 立即执行函数
现有匿名函数如下:
@@ -469,15 +470,15 @@ function fn(){
## arguments 的使用
-当我们不确定有多少个参数传递的时候,可以用 **arguments** 来获取。在 JavaScript 中,arguments 实际上是当前函数的一个**内置对象**。所有函数都内置了一个 arguments 对象,arguments 对象中存储了**传递的所有实参**.
+当我们不确定有多少个参数传递的时候,可以用 **arguments** 来获取。在 JavaScript 中,arguments 实际上是当前函数的一个**内置对象**。所有函数都内置了一个 arguments 对象(只有函数才有 arguments 对象),arguments 对象中存储了**传递的所有实参**.
arguments的展示形式是一个**伪数组**。伪数组具有以下特点:
-- 可以进行遍历;length 属性。
+- 可以进行遍历;具有数组的 length 属性。
- 按索引方式存储数据。
-- 不具有数组的 push、pop 等方法。
+- 不具有数组的 push()、pop() 等方法。
**代码举例**:利用 arguments 求函数实参中的最大值
@@ -486,6 +487,7 @@ arguments的展示形式是一个**伪数组**。伪数组具有以下特点:
```javascript
function getMaxValue() {
var max = arguments[0];
+ // 通过 arguments 遍历实参
for (var i = 0; i < arguments.length; i++) {
if (max < arguments[i]) {
max = arguments[i];
diff --git a/04-JavaScript基础/18-作用域.md b/04-JavaScript基础/14-作用域.md
similarity index 56%
rename from 04-JavaScript基础/18-作用域.md
rename to 04-JavaScript基础/14-作用域.md
index ee3371a..66d2da8 100644
--- a/04-JavaScript基础/18-作用域.md
+++ b/04-JavaScript基础/14-作用域.md
@@ -3,21 +3,21 @@
## 作用域(Scope)的概念
-通俗来讲,作用域是一个变量或函数的作用范围。作用域在**函数定义**时,就已经确定了。
+- **概念**:通俗来讲,作用域是一个变量或函数的作用范围。作用域在**函数定义**时,就已经确定了。
+- **目的**:为了提高程序的可靠性,同时减少命名冲突。
### 作用域的分类
-在js中,一共有两种作用域:
+在 JS 中,一共有两种作用域:(ES6 之前)
-- 全局作用域
+- 全局作用域:作用于整个 script 标签内部,或者作用域一个独立的 JS 文件。
-- 函数作用域
+- 函数作用域(局部作用域):作用于函数内的代码环境。
-### js 是函数级别作用域
+### 作用域的访问关系
-
-js 是函数级别作用域:在内部作用域中可以访问到外部作用域的变量,在外部作用域中无法访问到内部作用域的变量。
+在内部作用域中可以访问到外部作用域的变量,在外部作用域中无法访问到内部作用域的变量。
代码举例:
@@ -32,9 +32,31 @@ foo();
console.log(b); // 报错:Uncaught ReferenceError: b is not defined。说明 外层作用域 无法访问 内层作用域 里的变量
```
-定义在全局作用域的变量,叫「全局变量」。
+### 变量的作用域
-定义在函数作用域的变量,叫「局部变量」。
+根据作用域的不同,变量可以分为两类:全局变量、布局变量。
+
+**全局变量**:
+
+- 在全局作用域下声明的变量,叫「全局变量」。在全局作用域的任何一地方,都可以访问这个变量。
+
+- 在全局作用域下,使用 var 声明的变量是全局变量。
+
+- 特殊情况:在函数内不使用 var 声明的变量也是全局变量(不建议这么用)。
+
+**局部变量**:
+
+- 定义在函数作用域的变量,叫「局部变量」。
+
+- 在函数内部,使用 var 声明的变量是局部变量。
+
+- 函数的**形参**也是属于局部变量。
+
+从执行效率来看全局变量和局部变量:
+
+- 全局变量:只有浏览器关闭时才会被销毁,比较占内存。
+
+- 局部变量:当其所在的代码块运行结束后,就会被销毁,比较节约内存空间。
### 作用域的上下级关系
@@ -56,36 +78,39 @@ console.log(b); // 报错:Uncaught ReferenceError: b is not defined。说明
- 创建的**函数**都会作为window对象的方法保存。
-全局作用域中的变量都是全局变量,在页面的任意的部分都可以访问的到。
### 变量的声明提前(变量提升)
使用var关键字声明的变量( 比如 `var a = 1`),**会在所有的代码执行之前被声明**(但是不会赋值),但是如果声明变量时不是用var关键字(比如直接写`a = 1`),则变量不会被声明提前。
-举例1:
+**举例1**:
```javascript
console.log(a);
var a = 123;
```
-
打印结果:undefined。注意,打印结果并没有报错,而是 undefined,说明变量 a 被提前声明了,只是尚未被赋值。
-
-举例2:
+**举例2**:
```javascript
console.log(a);
a = 123; //此时a相当于window.a
```
-程序会报错:
+程序会报错:`Uncaught ReferenceError: a is not defined`。
-![](http://img.smyhvae.com/20180314_2136.png)
+**举例3**:
+```javascript
+ a = 123; //此时a相当于window.a
+ console.log(a);
+```
-举例3:
+打印结果:123。
+
+**举例4**:
```javascript
foo();
@@ -99,7 +124,7 @@ function foo() {
```
打印结果:undefined。注意,打印结果并没有报错,而是 undefined。这个例子,再次说明了:变量 i 在函数执行前,就被提前声明了,只是尚未被赋值。
-打印结果:
+
### 函数的声明提前
@@ -125,7 +150,7 @@ function foo() {
使用`函数表达式`创建的函数`var foo = function(){}`,**不会被声明提前**,所以不能在声明前调用。
-很好理解,因为此时foo被声明了(这里是变量声明),且为undefined,并没有把 `function(){}` 赋值给 foo。
+很好理解,因为此时foo被声明了(这里只是变量声明),且为undefined,并没有把 `function(){}` 赋值给 foo。
所以说,下面的例子,会报错:
@@ -135,11 +160,11 @@ function foo() {
**提醒1**:在函数作用域中,也有声明提前的特性:
-- 函数中,使用var关键字声明的变量,会在函数中所有的代码执行之前被声明
+- 函数中,使用var关键字声明的变量,会在函数中所有的代码执行之前被声明。
- 函数中,没有var声明的变量都是**全局变量**,而且并不会提前声明。
-举例1:
+举例:
```javascript
var a = 1;
@@ -154,7 +179,7 @@ function foo() {
```
-上方代码中,执行foo()后,打印结果是`1`。如果去掉第一行代码,打印结果是`Uncaught ReferenceError: a is not defined`
+上方代码中,执行foo()后,函数里面的打印结果是`1`。如果去掉第一行代码,执行foo()后,函数里面的打印结果是`Uncaught ReferenceError: a is not defined`。
**提醒2**:定义形参就相当于在函数作用域中声明了变量。
@@ -167,6 +192,72 @@ function foo() {
fun6(123);//打印结果为123
```
+## JavaScript 没有块级作用域(ES6之前)
+
+在其他编程语言中(如 Java、C#等),存在块级作用域,由`{}`包括起来。比如在 Java 语言中,if 语句里创建的变量,只能在if语句内部使用:
+
+```java
+if(true){
+ int num = 123;
+ system.out.print(num); // 123
+}
+system.out.print(num); // 报错
+```
+
+但是,在 JS 中没有块级作用域(ES6之前)。举例如下:
+
+```javascript
+if(true){
+var num = 123;
+ console.log(123); //123
+}
+
+console.log(123); //123(可以正常打印)
+
+```
+
+## 作用域链
+
+引入:
+
+- 只要是代码,就至少有一个作用域
+
+- 写在函数内部的局部作用域
+
+- 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
+
+基于上面几条内容,我们可以得出作用域链的概念。
+
+**作用域链**:内部函数访问外部函数的变量,采用的是链式查找的方式来决定取哪个值,这种结构称之为作用域链。查找时,采用的是**就近原则**。
+
+代码举例:
+
+```javascript
+var num = 10;
+
+function fn() {
+ // 外部函数
+ var num = 20;
+
+ function fun() {
+ // 内部函数
+ console.log(num);
+ }
+ fun();
+}
+fn();
+
+```
+
+打印结果:20。
+
+
+
+
+
+
+
+
## 我的公众号
想学习**代码之外的技能**?不妨关注我的微信公众号:**千古壹号**(id:`qianguyihao`)。
diff --git a/04-JavaScript基础/20-作用域链.md b/04-JavaScript基础/20-作用域链.md
deleted file mode 100644
index bfcb47b..0000000
--- a/04-JavaScript基础/20-作用域链.md
+++ /dev/null
@@ -1,35 +0,0 @@
-
-## 一些概念
-
-### 作用域和作用域链
-
-**作用域**:
-
-每个 JS 函数都是一个对象,对象中有些属性我们可以访问,有些属性我们不可以访问。无法访问的这些属性仅供 JS 引擎存取,[[scope]] 属性就是其中之一。
-
-[[scope]]就是我们所说的作用域,其中存储了执行期上下文的集合。
-
-
-
-**作用域链**:
-
-[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。
-
-
-### 执行期上下文
-
-当**函数执行**时(准确来说,是在函数发生预编译的前一刻),会创建一个执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境。
-
-每调用一次函数,就会创建一个新的上下文对象,他们之间是相互独立且独一无二的。当函数执行完毕,它所产生的执行期上下文会被销毁。
-
-## 最后一段
-
-备注:本文的内容还有待完善。
-
-
-
-## 参考链接
-
--
-
-
diff --git a/04-JavaScript基础/20-执行期上下文.md b/04-JavaScript基础/20-执行期上下文.md
new file mode 100644
index 0000000..48b9341
--- /dev/null
+++ b/04-JavaScript基础/20-执行期上下文.md
@@ -0,0 +1,15 @@
+
+
+## 执行期上下文
+
+当**函数执行**时(准确来说,是在函数发生预编译的前一刻),会创建一个执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境。
+
+每调用一次函数,就会创建一个新的上下文对象,他们之间是相互独立且独一无二的。当函数执行完毕,它所产生的执行期上下文会被销毁。
+
+
+
+## 参考链接
+
+-
+
+
diff --git a/04-JavaScript基础/25-数组简介.md b/04-JavaScript基础/25-数组简介.md
index 13b37a0..faf02d3 100644
--- a/04-JavaScript基础/25-数组简介.md
+++ b/04-JavaScript基础/25-数组简介.md
@@ -143,6 +143,8 @@ console.log(JSON.stringify(arr));
可以使用`length`属性来获取数组的长度(即“元素的个数”)。
+数组的长度是元素个数,不要跟索引号混淆。
+
语法:
```javascript