add: 函数的定义
This commit is contained in:
parent
0ff9b66135
commit
0bbb6c66de
@ -1,4 +1,21 @@
|
||||
|
||||
## 前言
|
||||
|
||||
关于函数的核心内容:
|
||||
|
||||
- 函数有哪几种定义和调用方式
|
||||
|
||||
- this:函数内部的 this 指向、如何改变 this 的指向。
|
||||
|
||||
- 函数的严格模式
|
||||
|
||||
- 高阶函数:函数作为参数传递、函数作为返回值传递
|
||||
|
||||
- 闭包:闭包的作用
|
||||
|
||||
- 递归:递归的两个条件
|
||||
|
||||
- 深拷贝和浅拷贝的区别
|
||||
|
||||
## 函数的介绍
|
||||
|
||||
@ -27,13 +44,13 @@ function sayHello(){
|
||||
}
|
||||
```
|
||||
|
||||
## 函数的定义
|
||||
|
||||
|
||||
## 函数的定义和调用
|
||||
### 方式一:函数声明(命名函数)
|
||||
|
||||
### 第一步:函数的定义
|
||||
|
||||
**方式一**:使用`函数声明`来创建一个函数。语法:
|
||||
使用`函数声明`来创建一个函数(也就是 function 关键字)。语法:
|
||||
|
||||
|
||||
```javascript
|
||||
@ -45,7 +62,7 @@ function 函数名([形参1,形参2...形参N]){ // 备注:语法中的中括
|
||||
举例:
|
||||
|
||||
```javascript
|
||||
function sum(a, b){
|
||||
function fun1(a, b){
|
||||
return a+b;
|
||||
}
|
||||
```
|
||||
@ -62,10 +79,12 @@ function sum(a, b){
|
||||
|
||||
PS:在有些编辑器中,方法写完之后,我们在方法的前面输入`/**`,然后回车,会发现,注释的格式会自动补齐。
|
||||
|
||||
**方式二**:使用`函数表达式`来创建一个函数。语法:
|
||||
### 方式二:函数表达式(匿名函数)
|
||||
|
||||
使用`函数表达式`来创建一个函数。语法:
|
||||
|
||||
```javascript
|
||||
var 函数名 = function([形参1,形参2...形参N]){
|
||||
var 变量名/函数名 = function([形参1,形参2...形参N]){
|
||||
语句....
|
||||
}
|
||||
```
|
||||
@ -73,17 +92,59 @@ var 函数名 = function([形参1,形参2...形参N]){
|
||||
举例:
|
||||
|
||||
```javascript
|
||||
var fun3 = function() {
|
||||
var fun2 = function() {
|
||||
console.log("我是匿名函数中封装的代码");
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
从方式二的举例中可以看出:所谓的“函数表达式”,其实就是将匿名函数赋值给一个变量。
|
||||
|
||||
当然,我们还有方式三:使用构造函数来创建一个对象。这种方式,用的少。
|
||||
### 方式三:使用构造函数 new Function()
|
||||
|
||||
### 第二步:函数的调用
|
||||
使用构造函数`new Function()`来创建一个对象。这种方式,用的少。
|
||||
|
||||
语法:
|
||||
|
||||
```javascript
|
||||
var 变量名/函数名 = new Function('形参1', '形参2', '函数体']);
|
||||
```
|
||||
|
||||
注意,这里是直接将函数体放在**字符串**里包裹起来,放在 Function 的最后一个参数的位置;而且,形参也必须放在**字符串**里。
|
||||
|
||||
代码举例:
|
||||
|
||||
```javascript
|
||||
var fun3 = new Function('a', 'b', 'console.log("我是函数内部的内容"); console.log(a + b);');
|
||||
|
||||
fun3(1, 2); // 调用函数
|
||||
```
|
||||
|
||||
打印结果:
|
||||
|
||||
```
|
||||
我是函数内部的内容
|
||||
3
|
||||
```
|
||||
|
||||
**分析**:
|
||||
|
||||
方式3的写法很少用,原因如下:
|
||||
|
||||
- 不方便书写:写法过于啰嗦和麻烦。
|
||||
|
||||
- 执行效率较低:首先需要把字符串转换为 js 代码,然后再执行。
|
||||
|
||||
### 总结
|
||||
|
||||
1、**所有的函数,都是 `Fuction` 的“实例”**(或者说是“实例对象”)。函数本质上都是通过 new Function 得到的。
|
||||
|
||||
2、函数既然是实例对象,那么,**函数也属于“对象”**。还可以通过如下特征,来佐证函数属于对象:
|
||||
|
||||
- 我们直接打印某一个函数,比如 `console.log(fun2)`,发现它的里面有`__proto__`。(这个是属于原型的知识,后续再讲)
|
||||
|
||||
- 我们还可以打印 `console.log(fun2 instanceof Object)`,发现打印结果为 `true`。这说明 fun2 函数就是属于 Object。
|
||||
|
||||
## 函数的调用
|
||||
|
||||
函数调用的语法:
|
||||
|
||||
@ -267,6 +328,11 @@ function fn(){
|
||||
|
||||
我们可以这样说,如果直接是`fn()`,那就说明是函数调用。如果是`XX.fn()`的这种形式,那就说明是**方法**调用。
|
||||
|
||||
## 构造函数、原型对象、对象实例之间的关系
|
||||
|
||||
暂略。
|
||||
|
||||
|
||||
## 我的公众号
|
||||
|
||||
想学习<font color=#0000ff>**代码之外的技能**</font>?不妨关注我的微信公众号:**千古壹号**(id:`qianguyihao`)。
|
||||
|
@ -3,7 +3,8 @@
|
||||
|
||||
## 作用域(Scope)的概念
|
||||
|
||||
作用域是一个变量或函数的作用范围。作用域在**函数定义**时,就已经确定了。
|
||||
通俗来讲,作用域是一个变量或函数的作用范围。作用域在**函数定义**时,就已经确定了。
|
||||
|
||||
|
||||
### 作用域的分类
|
||||
|
||||
@ -13,7 +14,10 @@
|
||||
|
||||
- 函数作用域
|
||||
|
||||
在函数作用域中可以访问到全局作用域的变量,在全局作用域中无法访问到函数作用域的变量。
|
||||
### js 是函数级别作用域
|
||||
|
||||
|
||||
js 是函数级别作用域:在内部作用域中可以访问到外部作用域的变量,在外部作用域中无法访问到内部作用域的变量。
|
||||
|
||||
代码举例:
|
||||
|
||||
@ -32,11 +36,7 @@ console.log(b); // 报错:Uncaught ReferenceError: b is not defined。说明
|
||||
|
||||
定义在函数作用域的变量,叫「局部变量」。
|
||||
|
||||
### 执行上下文
|
||||
|
||||
当**函数执行**时,会创建一个执行期上下文的内部对象。每调用一次函数,就会创建一个新的上下文对象,他们之间是相互独立的。当函数执行完毕,它所产生的执行期上下文会被销毁。参考链接:<https://www.cnblogs.com/chenyingjie1207/p/9966036.html>
|
||||
|
||||
**作用域的上下级关系:**
|
||||
### 作用域的上下级关系
|
||||
|
||||
当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用(**就近原则**)。如果没有则向上一级作用域中寻找,直到找到全局作用域;如果全局作用域中依然没有找到,则会报错 ReferenceError。
|
||||
|
||||
@ -84,6 +84,24 @@ console.log(b); // 报错:Uncaught ReferenceError: b is not defined。说明
|
||||
|
||||
![](http://img.smyhvae.com/20180314_2136.png)
|
||||
|
||||
|
||||
举例3:
|
||||
|
||||
```javascript
|
||||
foo();
|
||||
|
||||
function foo() {
|
||||
if (false) {
|
||||
var i = 123;
|
||||
}
|
||||
console.log(i);
|
||||
}
|
||||
```
|
||||
|
||||
打印结果:undefined。注意,打印结果并没有报错,而是 undefined。这个例子,再次说明了:变量 i 在函数执行前,就被提前声明了,只是尚未被赋值。
|
||||
打印结果:
|
||||
|
||||
|
||||
### 函数的声明提前
|
||||
|
||||
**函数声明**:
|
||||
@ -136,7 +154,7 @@ console.log(b); // 报错:Uncaught ReferenceError: b is not defined。说明
|
||||
|
||||
```
|
||||
|
||||
上方代码中,foo()的打印结果是`1`。如果去掉第一行代码,打印结果是`Uncaught ReferenceError: a is not defined`
|
||||
上方代码中,执行foo()后,打印结果是`1`。如果去掉第一行代码,打印结果是`Uncaught ReferenceError: a is not defined`
|
||||
|
||||
**提醒2**:定义形参就相当于在函数作用域中声明了变量。
|
||||
|
||||
|
35
04-JavaScript基础/12-作用域链.md
Normal file
35
04-JavaScript基础/12-作用域链.md
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
## 一些概念
|
||||
|
||||
### 作用域和作用域链
|
||||
|
||||
**作用域**:
|
||||
|
||||
每个 JS 函数都是一个对象,对象中有些属性我们可以访问,有些属性我们不可以访问。无法访问的这些属性仅供 JS 引擎存取,[[scope]] 属性就是其中之一。
|
||||
|
||||
[[scope]]就是我们所说的作用域,其中存储了执行期上下文的集合。
|
||||
|
||||
|
||||
|
||||
**作用域链**:
|
||||
|
||||
[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。
|
||||
|
||||
|
||||
### 执行期上下文
|
||||
|
||||
当**函数执行**时(准确来说,是在函数发生预编译的前一刻),会创建一个执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境。
|
||||
|
||||
每调用一次函数,就会创建一个新的上下文对象,他们之间是相互独立且独一无二的。当函数执行完毕,它所产生的执行期上下文会被销毁。
|
||||
|
||||
## 最后一段
|
||||
|
||||
备注:本文的内容还有待完善。
|
||||
|
||||
|
||||
|
||||
## 参考链接
|
||||
|
||||
- <https://www.cnblogs.com/chenyingjie1207/p/9966036.html>
|
||||
|
||||
|
0
04-JavaScript基础/14-闭包.md
Normal file
0
04-JavaScript基础/14-闭包.md
Normal file
@ -79,10 +79,32 @@ window.open('你所要跳转的新页面');
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 2019-12-10-JavaScript 新特性:Optional Chaining(可选链式调用)语法
|
||||
|
||||
以往写代码,我们一般都这么写:
|
||||
|
||||
```javascript
|
||||
if (result && result.user && result.user.name && result.user.name.length) {
|
||||
console.log('qianguyihao');
|
||||
}
|
||||
```
|
||||
|
||||
有了 Optinal Chain 语法之后,就简洁很多了,可以这么写:
|
||||
|
||||
|
||||
```javascript
|
||||
if (result?.user?.name?.length) {
|
||||
console.log('qianguyihao');
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
参考链接:
|
||||
|
||||
- 了解 JavaScript 新特性:Optional Chaining:<https://www.infoq.cn/article/2JDORgXrU6VmZ7jlyuFD>
|
||||
|
||||
- 原文链接: https://v8.dev/features/optional-chaining
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user