We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JS自执行函数又称为IIFE,在我们开发过程中会使用到大量的自执行函数。
使用建议:在使用只执行函数前面加上 “ ; ”,避免压缩或者打包时变为函数。
首先我们要了解一般情况下什么是函数声明语句,什么是函数表达式语句,以便于接下来的实验。
辨别方法:以“function”开头的有名称的函数是函数声明语句。
function a();//函数声明语句 var a = function();//函数表达式语句
下面我们在分析一道面试题:
var a = function(){} var b = function(){} console.log(a()+b());//输出结果是NaN
因为解释器会把前面的a()认为是一个语句块的结束,后面的‘+’一元运算符有把后面b()转换为数字这么一个功能,所以得到的结果是NaN。
因此我们在做自执行函数的时候,要把函数的声明变为函数表达式,这样就不会影响输出的结果了。
方法1:
(function(){ })();
方法2:
(function(){ }() );
方法3(通过操作符):但是这种方法仍然会占用命名空间,所以不建议使用。
var a = function (){ console.log(2) }()
方法4(通过操作符)与或操作符:
false || function (){ console.log(2) }() true && function (){ console.log(2) }() 0 , function (){ console.log(2) }()
注:通过操作符实现自执行函数一般使用在打包工具里面,比如webpack打包后会经常看到 ” 0,functtion(){}()“
方法5:(一元运算符)一元运算符仍然可以将函数声明转换为函数表达式,在bootstrap框架中常用。
! function (){ console.log(2) }() -function (){ console.log(2) }() +function (){ console.log(2) }()
方法6:new一个匿名函数,后面可省略括号。(不建议使用,会产生争议)
new function (){ console.log(2) };//在不传参的情况下使用new也可以自执行,可以去掉小括号,不常用。
以上方法性能比较:
除了一元运算符的时候性能偏低,因为要进行一次数字类型的转换,其他的都可以。
我们要了解,为什么使用自执行函数,确切的说是自执行函数的优点以及缺点:
比如jq里面暴露给全局作用域$和query两个变量,为了解决这个问题,我们可以将window.jq作为一个实参传递给一个立即执行的匿名函数。这样的话,我们再次命名$或者query就不会有冲突了。
$
query
(function(){})(bb()) console.log(12) function bb(){ console.log(22) };//打印顺序是22,12
这就叫做UMD通用模块规范,在实际开发过程中被广泛应用。
作用域的内部可以访问到外部,外部不可以访问到内部,js作用域的缺陷就是没有块级作用域。
比如:
for (var i = 0; i <6; i++) { } console.log(i);//打印出来的是6,在for循环外面仍然可以访问到变量i。
三个特殊的语句可以欺骗语法分析:
evel(); //内部存放js代码可被执行 with(object instance) { //代码块 }; // with 语句可以方便地用来引用某个特定对象中已有的属性, // 但是不能用来给对象添加属性。要给对象创建新的属性,必须明确地引用该对象。 try { // 此处是可能产生例外的语句 } catch(error) { // 此处是负责例外处理的语句 } finally { // 此处是出口语句 }
所以在ES3下,严格来说js是没有块级作用域的,但是以上三种方法可以实现块级作用域的效果。
常用的有try catch,把要声明的变量放在try里面,然后当一个错误抛出,让cath接住使用。缺点:1.多个块级作用域需要多个嵌套;2.性能问题。
匿名自执行函数只能模拟块级作用域,并非真正的作用域。
let定义的作用域是块级作用域,但不要轻易使用,针对开发场景来选择。
比如有个人写了这样一段代码:undefined=true,再早之前undefined是可以被赋值的,所以这段代码不会报错,但是这样会致使你下面的一些判断出错
这时候如果使用匿名自执行函数就可以解决:
(function(undefined){ console.log(undefined) }())
了解他的优点之后我们才可以在正确的场景使用IIFE。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
JS自执行函数又称为IIFE,在我们开发过程中会使用到大量的自执行函数。
IIFE写法:
使用建议:在使用只执行函数前面加上 “ ; ”,避免压缩或者打包时变为函数。
首先我们要了解一般情况下什么是函数声明语句,什么是函数表达式语句,以便于接下来的实验。
辨别方法:以“function”开头的有名称的函数是函数声明语句。
下面我们在分析一道面试题:
因为解释器会把前面的a()认为是一个语句块的结束,后面的‘+’一元运算符有把后面b()转换为数字这么一个功能,所以得到的结果是NaN。
因此我们在做自执行函数的时候,要把函数的声明变为函数表达式,这样就不会影响输出的结果了。
方法1:
方法2:
方法3(通过操作符):但是这种方法仍然会占用命名空间,所以不建议使用。
方法4(通过操作符)与或操作符:
注:通过操作符实现自执行函数一般使用在打包工具里面,比如webpack打包后会经常看到 ” 0,functtion(){}()“
方法5:(一元运算符)一元运算符仍然可以将函数声明转换为函数表达式,在bootstrap框架中常用。
方法6:new一个匿名函数,后面可省略括号。(不建议使用,会产生争议)
以上方法性能比较:
除了一元运算符的时候性能偏低,因为要进行一次数字类型的转换,其他的都可以。
应用:
我们要了解,为什么使用自执行函数,确切的说是自执行函数的优点以及缺点:
1.避免作用域命名污染
2.提升性能(减少了对作用域的查找)
3.避免全局命名冲突
比如jq里面暴露给全局作用域
$
和query
两个变量,为了解决这个问题,我们可以将window.jq作为一个实参传递给一个立即执行的匿名函数。这样的话,我们再次命名$或者query就不会有冲突了。4.有利于代码压缩(可以用简单字符串代替)
5.保存闭包状态
6.颠倒代码执行顺序
这就叫做UMD通用模块规范,在实际开发过程中被广泛应用。
7.模仿块级作用域
作用域的内部可以访问到外部,外部不可以访问到内部,js作用域的缺陷就是没有块级作用域。
比如:
三个特殊的语句可以欺骗语法分析:
所以在ES3下,严格来说js是没有块级作用域的,但是以上三种方法可以实现块级作用域的效果。
常用的有try catch,把要声明的变量放在try里面,然后当一个错误抛出,让cath接住使用。缺点:1.多个块级作用域需要多个嵌套;2.性能问题。
匿名自执行函数只能模拟块级作用域,并非真正的作用域。
let定义的作用域是块级作用域,但不要轻易使用,针对开发场景来选择。
8.填坑(加载第三方插件时候的一些问题)
比如有个人写了这样一段代码:undefined=true,再早之前undefined是可以被赋值的,所以这段代码不会报错,但是这样会致使你下面的一些判断出错
这时候如果使用匿名自执行函数就可以解决:
了解他的优点之后我们才可以在正确的场景使用IIFE。
The text was updated successfully, but these errors were encountered: