函数的声明方法
1、具名函数:
1 | function x(输入1,输入2){ |
2、匿名函数:(需要给一个变量)
1 | var x |
3、把具名函数赋值给变量:
1 | var x = function y(){ |
4、使用window.Function函数对象
1 | // new Function('x','y','return x + y') |
5、箭头函数(也属于匿名函数)
1 | // (x,y) => {return x + y} |
6、函数的name属性
1 | function f1(){} |
函数的this和arguments
函数本质是:调用call;用于反复调用的代码块。
f:函数对象;f.call():执行这个函数体。
1 | f.call(asThis,input1,input2) |
其中f.call的第一个参数可以用this得到;f.call的第二个以及后面的参数可以用arguments得到,并以伪数组形式呈现。
1 | f.call(undefined,'x','y','z'){ |
函数的调用栈(Call Stack)
JavaScript的函数调用栈(Call Stack)其实就是一种解析器去处理程序的机制,它是栈数据结构。它能追踪子程序的运行状态。当函数调用的时候,就把该函数push到调用栈,结束时候,就从栈顶端移除。遵循FILO(先进后出)原则。另外当递归压栈时,容易造成stack overflow。
这个网站 可以可视化帮助理解调用栈。
函数的作用域(Function Scope)
JavaScript 语言特有的”链式作用域”结构(chain scope),子对象会就近原则,一级一级地向上寻找最近父对象的变量。与全局作用域一样,函数作用域内部也会产生“变量提升”现象。
立即执行函数(IIFE):是一个在定义时就会立即执行的JavaScript函数。当函数变成立即执行的函数表达式时,表达式中的变量不能从外部访问。
1 | //使用方法 |
闭包:
1 | !function(){ |
1 | function foo(){ |
以上两组代码都形成了一个闭包:「函数」和「函数内部能访问到的变量」(也叫环境)的总和,就是一个闭包。
闭包的用处有,一个是可以读取函数内部的变量,一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在,不会在调用结束后,被垃圾回收机制回收。另一个用处,是封装对象的私有属性和私有方法。
由于外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大。因此不能滥用闭包,否则会造成网页的性能问题。