# 你真的知道函数吗？

原文地址：<https://www.cnblogs.com/xxcanghai/p/4991870.html>

说起函数，自然是function ,对于函数的创建也不陌生。可是还是遇到一些让自己突然对函数function 产生怀疑的调用，打破了自己固有的对函数的理解。

这个区别看似微不足道，但在某些情况下确实是一个难以察觉并且“致命“的陷阱。出现这个陷阱的本质原因体现在这两种类型在函数提升和运行时机（解析时/运行时）上的差异。

当然我们最后要给一个总结：Javascript中**函数声明**和**函数表达式**是存在区别的，**函数声明**在JS**解析时**进行函数提升，因此在同一个作用域内，不管函数声明在哪里定义，该函数都可以进行调用。而**函数表达式**的值是在JS**运行时**确定，并且在表达式赋值完成后，该函数才能调用。这个微小的区别，可能会导致JS代码出现意想不到的bug，让你陷入莫名的陷阱中。

## 创建函数的方式：

1. **声明函数 ：函数体加函数名**

```javascript
  function fun (){

    return 1+3 ;
  }

  fun.name == fun ; //true
```

1. **匿名函数表达式   :访问不到函数名**&#x20;

```javascript
var fun1 = function (){

    return 1+4;
}

fun1.name == undefined;
```

### 3.具名函数表达式 : 带名称的函数表达式，但是不能通过这个名称访问到它，因为还是属于函数表达式,但是可以在内部访问到

```javascript
var fun1  = function fun(){
    console.log(fun);
    fun.name == fun // fun
    return 1+1 ;
}
fun.name == undefined;//true
fun1.name == undefined;//true
console.log(fun); // underfind
```

**4.构造函数Function : 实例化 Function ,也属于匿名函数**

```javascript
var a="str";
var fun  = new Function ("return "+a);
//通常可以用这个方法来解析不规范的json字符串,成为规范的json

var jsonStr="{name:'test',}"; //不规范的不能用JSON.parse();
var json = (new Function(str){ 'retrun ' +a })(jsonStr);
```

**5.立即执行函数IIFE,也是属于函数表达式，可以带名称，但是规则和函数表达式一样，不能访问到名称**

```javascript
!function(a){
    console.log(a);
}(34);

+function(a){
    console.log(a);
}(56);

(function(a){
    console.log(a);
})(45);

(function fun1(a){
    console.log(a);
})(45);
```

构造函数的new ，注意 new 后面的函数带括号与不带括号的区别是一个有参数一个没有参数。其实都是进行实例操作

```javascript
function Test(){

    this.age = 33 ;
}

Test.say = function(){

    this.text = "我是类的静态属性";
}

Test.prototype.say = function(){

    this.text = "我是实例的属性";


    console.log(124);

}

const a = new Test();
const b = new Test ;

b instanceof Test // true ;
```

对于new 关键字后面的函数的，值得注意的是执行顺序，

```javascript
const c = new Test.say();
const d = new Test().say();
const e= new new Test().say();
```

c 是把Test的静态属性say当作构造函数的实例

d 是调用的Test的实例的say方法

e 可以这样分解，先 new 一个 Test的实例，然后把这个实例的say方法当作构造函数 在new 一个实例；


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sekin.gitbook.io/myjs/chapter1/ni-zhen-de-zhi-dao-han-shu-ma-ff1f.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
