1. 常见函数
//函数声明:使用function关键字声明一个函数,再指定一个函数名,叫函数声明。
function foo(){
var a = 8;
console.log(a);
}
foo(); //调用函数
//函数表达式 :使用function关键字声明一个函数,但未给函数命名,最后将匿名函数赋予一个变量,叫函数表达式,这是最常见的函数表达式语法形式。
var foo = function () {
var a = 8;
console.log(a);
};
foo(); //调用函数
//匿名函数:使用function关键字声明一个函数,但未给函数命名,所以叫匿名函数.
//匿名函数属于函数表达式,匿名函数有很多作用,赋予一个变量则创建函数,赋予一个事件则成为事件处理程序或创建闭包等等。
function () {};
函数声明和函数表达式不同之处在于:
- Javascript引擎在解析javascript代码时会‘函数声明提升’(Function declaration
Hoisting)当前执行环境(作用域)上的函数声明,而函数表达式必须等到Javascirtp引擎执行到它所在行时,才会从上而下一行一行地解析函数表达式。- 函数表达式后面可以加括号立即调用该函数(所有IIFE在函数外面加()以表示其为函数表达式,不是函数声明),函数声明不可以,只能以fnName()形式调用 。
2. IIFE(立即执行函数)
(function foo(){
var a = 8;
console.log(a);
})();
上面函数声明和IIFE两种写法达到的目的是相同的,都是声明了一个函数foo并且随后调用函数foo。
如果只是为了立即执行一个函数,显然IIFE所带来的好处有限。
3. 为什么需要IIFE
实际上,IIFE的出现是为了弥补JS在scope方面的缺陷:JS只有全局作用域(global scope)、函数作用域(function scope),从ES6开始才有块级作用域(block scope)。对比现在流行的其他面向对象的语言可以看出,JS在访问控制这方面是多么的脆弱!那么如何实现作用域的隔离呢?在JS中,只有function才能实现作用域隔离,因此如果要将一段代码中的变量、函数等的定义隔离出来,只能将这段代码封装到一个函数中。
在我们通常的理解中,将代码封装到函数中的目的是为了复用。在JS中,当然声明函数的目的在大多数情况下也是为了复用,但是JS迫于作用域控制手段的贫乏,我们也经常看到只使用一次的函数:这通常的目的是为了隔离作用域了!既然只使用一次,那么立即执行好了!既然只使用一次,函数的名字也省掉了!这就是IIFE的由来。
IIFE 常见形式
(function () {
var aName = "Barry";
})();
aName // 错误,变量未定义( IIFE内部变量在外部无法直接访问)
var result = (function () {
var name = "Barry";
return name;
})();
result; // IIFE定义给一个变量,变量获取的是返回值,而非 IIFE函数
//JSLint 的版本
(function () {
var aName = "Barry";
}());
//Arrow function 版本
(() => {
var aName = "Barry";
})();
//Async function 版本
(async function () {
var aName = "Barry";
})();
(async () => {
var aName = "Barry";
})();
//传入参数
((param1, param2, param3, ...) => {
var aName = "Barry";
})(param1, param2, param3, ...);
//对于常见的(function($){...})(jQuery);即是将实参jQuery传入函数function($){},通过形参$接收
4.其他函数形式
4.1 上述IIFE函数中,最开始的那个括号,可能会由于js中自动分号插入机制而引发问题。例如:
let a = b + c
(() => {
var aName = "Barry";
})(); //可能会出错
//该处有可能被解析为c()而开始执行。所以有的时候,可能会看到这样的写法:;(function (){...}()),前边的分号可以认为是防御型分号。如:
let a = b + c
;(() => {
var aName = "Barry";
})();
4.2 $(function(){...});
是$(document).ready(function(){/*...*/})
的简写形式,是在DOM加载完成后执行的回调函数,并且只会执行一次。在页面中出现多次的话,会按先后顺序依次执行。
$(document).ready(function(){
console.log('a');
})
//等价于
$(function(){
console.log('a');
})
网友评论