作用域

首先先介绍一下作用域等一些基础概念。

每个JavaScript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供JavaScript引擎存取,[[scope]]就是其中一个。

[[scope]] : 指的就是我们所说的作用域,其中存储了执行期上下文的集合

作用域链 : [[scope]] 中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链接叫做作用域链。

运行期上下文  : 当函数执行时,会创建一个称为执行期上下文的内部对象(AO)。一个执行期上下文定义了一个函数执行的环境,函数每次执行时对应的执行环境都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生的执行上下文被销毁。

查找变量  :从作用域链的顶端依次向下查找。

下面举一些例子:

function a(){function b(){function c(){}c();}b();
}
a();a defined a.[[scope]] ----> 0 : GO          //a定义的时候产生GO对象
a doing   a.[[scope]] ----> 0 : aAO           //a执行的时候新产生AO对象1 : GOb defined  b.[[scope]] ----> 0 : aAO            //子级b定义会继承父级a运行时产生的对象1 : GO
b doing    b.[[scope]] ---->  0 : bAO            //子级b新产生AO对象1 : aAO 2 : GO c defined  c.[[scope]] ---->  0 : bAO            //c定义时会继承b运行时产生的属性1 : aAO 2 : GO
c doing     c.[[scope]] ----> 0 : cAO            //c执行时同时又产生新的AO1 ;bAO 2 : aAO 3 : GO 

立即执行函数

之前学过函数的定义、函数表达式,还有一种函数叫做立即执行函数。

立即执行函数:函数执行过后立即被销毁。

立即执行函数的官方写法:

// 立即执行函数的官方写法
(function() {} ());  W3C建议此种
(function() {})();

针对初始化功能的函数,可以有参数。

var num = function (a,b){return a + b;
}(1,2);(function abc(){var a = 123;var b = 234;console.log(a+b);
}())

只有表达式才能被执行符号执行,能被执行符号执行的表达式,函数名字会被自动忽略。

function test(){console.log("a");
}()    会出现语法解析错误,因为括号前面是函数声明(+ function test( ){console.log('a');
}())                    -------->打印出a

下面是一道曾阿里面试题

function test(a, b, c, d){console.log(a + b + c + d);
}(1, 2, 3, 4);// 不报错也没有执行      

下面是几道经典的例题,可以参考一下:

function test(){var arr = [];for(var i = 0; i < 10; i ++){arr[i] = function (){console.log(i);}}return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++){myArr[j]();
}  
// 输出:10个10

那么采用立即执行函数呢?会有怎样的结果呢?

function test(){var arr = [];for(var i = 0; i < 10; i ++){(function(j){arr[i] = function (){console.log(j + " ");}}(i))}return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++){myArr[j]();
} 
// 输出结果  0 1 2 3 4 5 6 7 8 9 

大家可以自行思考一下。

闭包

闭包的现象:当内部函数保存到外部时会产生闭包。

闭包会导致原有的作用域链不释放,造成内存泄漏

(内存泄漏:内存占用(比如:手握沙子,握得越紧手里剩得就越少))

闭包触发的情况:

两个或多个函数互相嵌套,把里面的函数保存到外部,这样的情况一定会产生闭包。从外面还可以调用里面的函数。

闭包的作用:

实现公有变量

eg:函数累加器

可以做缓存(存储结构)

eg:eater

可以实现封装,属性私有化

eg:person()

模块化开发,防止污染全局变量

// 函数累加器
function add(){var count = 0;function demo(){count ++;console.log(count);}return demo;
}
var counter = add();
counter();
counter();
counter();
counter();
counter();
counter();// eater
function test(){var food = "apple";var obj = {eatFood : function (){if(food != ""){console.log("I am eating  " + food);food = "";}else{console.log("There is nothing!");}},pushFood : function (myFood){food = myFood;}}return obj;
}
var person = test();
person.eatFood();
person.eatFood();
person.pushFood('banana');
person.eatFood();
 闭包:可以实现封装,属性(变量)私有化//属性(变量)私有化:别人访问不出来,只有自己设置方法让显式才能访问比如以下例子的prepareWife例如:function Deng(name, wife){var prepareWife = "xiaozhang";this.name = name;this.wife = wife;this.divorce = function (){this.wife = prepareWife;}this.changePrepareWife = function (target){prepareWife = target;}this.sayPrepareWife = function(){console.log(prepareWife);}}var deng = new Deng('deng', 'xiaoliu');   //将方法实例化对象

以上例子中我们用deng.prepareWife是访问不出来的,只能是调用sayPrepareWife方法才能实现。

这就将PrepareWife实现了私有化,实际是存在的,只是访问不出来,只能通过自身设置的方法才能访问,这就防止了污染全局变量。

附加一个逗号操作符:

先看前面的表达式,再看后面的表达式,把后面表达式的计算结构返回

例题:

var f =(function f(){return "1";},function g(){return 2;}
)();
console.log(typeof(f)); // -------numbervar x = 1;
if(function f(){}){x += typeof f;
}
console.log(x);
// --------> 1undefined

闭包还有一些知识有待补充,等后面学习继续补充。

JS作用域、立即执行函数、闭包相关推荐

  1. JS中自动执行函数小结

    JS中自动执行函数小结 请看以下两个函数: 1.function a(){ 2.    alert("a") 3.} 1.var b= function(){ 2.    aler ...

  2. 前端工程师地基 深入理解闭包 作用域 立即执行函数

    闭包 一.作用域初探 作用域定义:变量(变量作用于又称上下文)和函数生效(能被访问)的区域 互相嵌套的函数,里面可以访问外面的,外面不能访问里面 外面不访问里面演示: var a = 123; fun ...

  3. JS 的立即执行函数

    1.定义 IIFE:Immediately Invoked Function Expression,意为立即调用的函数表达式,也就是说:声明函数的同时立即调用这个函数.对比一下,这是不采用IIFE时的 ...

  4. js中立即执行函数会预编译吗_js变量提升和函数提升

    把变量提升函数提升拿出来讲,一看就知道是老前端搬砖工了,其实这些js的基础本质的东西,很有必要去了解,可以活跃思维,而且可以在研究这个的过程中,找到当初设计这门语言的人的想法,然后让自己不仅仅是对这个 ...

  5. 2020-06-28 html的实现页面锁屏 + css的BFC与float + js的立即执行函数写法 + 颜色搭配

    2020-06-28 题目来源:http://www.h-camel.com/index.html [html] 实现一个页面锁屏的功能 锁屏的最终效果就是退出登录,思路是 点击锁屏按钮等操作时 使t ...

  6. JS高级-自执行函数-垃圾回收机制及内存管理

    自执行函数 函数分为两种: (1)一般函数 预解析后通过函数调用 函数名( ) 执行 (2)自执行函数 js引擎一遇到整个函数就立马执行 代码如下: js中的垃圾回收机制及内存管理 内存管理 (1)全 ...

  7. JS模块化(立即执行函数)

    JavaScript的模块化 //用立即执行函数制造的模块是JS最常用的模块(模块是实现特定功能的一组属性和方法的封装, //可以独立完成一些功能,且有私有成员)之宽放大模式(允许模块所需参数为空,比 ...

  8. js中自执行函数的作用

    当一个页面两个人写定义的相同的变量名就会发生冲突 污染全局 自执行函数的作用就出来了,自执行函数里面是一个单独的作用域不会影响其他的也不会污染全局 (function(){ })(); //建立一个单 ...

  9. js实现自动执行函数

    1.setInterval 间隔一段时间执行函数,执行多次(一直执行) js代码: //每隔一秒自动执行方法(多次执行) var c=0; function showLogin() {alert(c+ ...

  10. js中立即执行函数会预编译吗_JavaScript预编译过程

    什么是预编译? 当js代码执行时有三个步骤: 1.语法分析,这个过程检查出基本的语法错误. 2,预编译,为对象分配空间. 3,解释执行,解释一行执行一行,一旦出错立即停止执行. 预编译发生在代码执行的 ...

最新文章

  1. 【组合数学】递推方程 ( 常系数线性非齐次递推方程求解 | 递推方程标准型及通解 | 递推方程通解证明 )
  2. what should you do if you want to have a high efficiency for communication
  3. 怎么安装python的包_python下如何安装.whl包?
  4. 又一门国产数据库语言诞生了,比SQL还好用
  5. 1c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afx.h(24) : fatal error C1189: #err
  6. VSCode LaTex 安装
  7. 驱动人生8新版助力电脑性能起飞
  8. nmon监控工具使用(打开nmon文件出现  运行时错误13类型不匹配)
  9. 580集photoshop顶尖视频教程送给你,设计总监手把手带你学ps!
  10. Python中Print()函数的用法___实例详解(全,例多)
  11. 算法导论15.1动态规划之钢条切割
  12. 剑与家园服务器维护,剑与家园合服爆料 合服规则介绍
  13. Salesforce触发器面试题
  14. php日志写什么内容,Monolog-PHP日志类库介绍
  15. java实训答辩ppt_实训项目答辩.ppt
  16. protect 和 private 的区别
  17. rviz--显示类型-Marker
  18. 2020IDEA如何设置自动换行
  19. Springboot整合JPA
  20. excel自动排班有假期_Excel中的假期周末标志

热门文章

  1. 【设计模式自习室】详解代理模式
  2. AI人工智能财税机器人真的能代替人吗
  3. 市场调研-基于细胞的海鲜市场现状及未来发展趋势
  4. R语言实现偏最小二乘回归法 partial least squares (PLS)回归
  5. 101种在家就能做的网上生意
  6. 网络技能大赛-2019年国赛真题[2019年全国职业技能大赛高职组计算机网络应用赛项真题-H卷]AC/AP/EG部分答案详解
  7. 密码学、电子签名、电子信封以及密钥安全等
  8. Emacs教程(一)
  9. 推荐算法总结以及概要
  10. 软件工程基础复习_4.1