🌞

JS对象分类之函数

1. 函数的定义

函数体里面是普通的操作语句,不是对象的键值对。

1) 构造函数

(完整详细的写法,但很少用)

1
sum = new Function('a', 'b', 'console.log(a); return a + b');

2) 具名函数

(有名字的函数)

1
2
3
function sum(a,b){
   return a + b;
}  

3) 匿名函数

(没有名字的函数,也叫函数表达式)该方法创建的函数sum不会挂到window上

1
2
3
4
5
6
7
8
let sum = function(a,b){
    return a + b;
}  

let sum = function fn(a,b){
    return a + b;
} 
fn(1,2) //语法错误,fn不存在,如果函数定义在等号右边则是以表达式的方式存在,其fn函数的作用域也只在表达式右边,不是全局,出了表达式就不存在。

4) 箭头函数(没有this和arguments属性)

ES6函数定义新语法,sum不会挂到window上,且箭头函数没有this和arguments属性

1
2
3
4
5
6
7
8
9
let sum = (a,b)=> a+b //函数体只有一个语句时,箭头左边是传入参数,右边是函数体

//返回对象
(错误) let fn = (x)=> {name: x} //若返回值为一个对象时,花括号默认是代码块标志,
(正确) let fn = (x)=> ({name: x}) //给对象加个括号,标明里面是一个整体,即可正确返回对象

let sum = (a,b)=> {
    return a + b;
} //函数体有多个语句
每个函数都有返回值,若不写return,默认返回一个undefined,并且返回值是在函数执行时返回
任何函数的构造函数都是自己

2. 函数自身属性

1) name

name这个属性值就是函数本身的名字

2) length

该属性是用来记录函数的形参个数,其属性值是number类型的数字,是形参个数。

3) arguments (箭头函数没有该属性)

在JS中,函数的定义中形参可以不写,在函数调用时可以直接传参,函数会接收传进来的参数,并且依次放进函数的arguments属性里,arguments属性值看似是个数组,但其实说对象更准确,里面数据是按照数组存储的方式存储的,所以arguments就是数组里提到的伪数组。当调用函数test(1,2)时,输出arguments组成如下所示:

1
2
3
4
5
6
7
8
arguments(2){
    0: 1
    1: 2
    length: 2
    callee: ƒ test()
    Symbol(Symbol.iterator): ƒ values()
    __proto__: Object		
}

**总结一句就是:**arguments是包含了函数所有参数的伪数组

伪数组不具有数组的公共属性,如push、pop等,如想把伪数组变成数组,可通过Array.from实现。

4) caller

3. 函数公共属性

4. 闭包

4.1 什么是闭包

如果一个函数用到了外部的变量,那么这个函数加这个变量就叫做闭包

未完待续。。。。

5. 调用栈

5.1 什么是调用栈

JS引擎在执行一个函数前,需要把函数所在的环境push到一个数组里,这个数组叫做调用栈。等函数执行完了,就会把环境pop弹出来,然后return到之前的环境,继续执行后续代码

6. 立即执行函数

6.1 来源

在JS中,在函数外用var声明一个变量得到的是一个全局变量,那么如何得到一个局部变量呢?只用通过在函数内声明一个变量才能得到一个局部变量,如下所示:

1
2
3
4
function fn(){
    var a;
}
fn();

那么a就是局部变量了,可是函数fn却是局部变量啊,为了得到一个局部变量,定义了一个全局函数变量,得不偿失,因此,就想到声明一个匿名函数如下:

1
2
3
function(){
    var a;
}

那么问题来了,匿名函数咋执行啊,没有名字怎么执行函数得到局部变量啊,因此就将函数的声明和执行统一在一起了,形成:

1
2
3
function(){
    var a;
}();

但是这样一来,JS认为该语法是错误的,是不对的,经过实验发现,如果在该函数面前加一个操作符,如+、-等就可成功运行了,也可以用括号将其括起来,如下:

1
2
3
4
5
6
7
(function(){
    var a;
}());

!function(){
    var a;
}();

6.2 结论

但经过测试,最保险的方法有如下两种:

  1. 在前面加感叹号

  2. 用括号将其包起来,但是要保证前一个语句后有分号隔开。

这样的函数就是立即执行函数。

updatedupdated2020-02-012020-02-01