javascript的几个知识点scoping, hoisting, IIFE
JavaScript 属于解释型语言,JavaScript 的执行分为:解释和执行两个阶段,这两个阶段所做的事并不一样:
解释阶段:
- 词法分析
- 语法分析
- 作用域规则确定
执行阶段:
- 创建执行上下文
- 执行函数代码
- 垃圾回收
Hoisting--提升
Hoisting的发生范围是函数作用域(function-local scope)。在函数内var定义的变量和函数声名会被提升到该函数作用域的上面。function内的提升的顺序所下:
- this, arguments
- 形参 formal parameters
- 函数声名 function declarations
- 变量声名 variable declarations
举例:
var a = 1;
function test(){
if(!a){
var a = 5;
}
console.log(a);
}
test();
//打印出5这
这是因为当解析器读到if语句时,发现有一个变量声名和定义:var a = 5;于是解析器就把这个变量的声名:var a;提到当前作用域的顶部。上面的代码最后执行是其实是这样的
var a = 1;
function test(){
var a;
if(!a){
a = 5;
}
console.log(a);
}
test();
如果想打印出1的话,需要用let来定义块级变量: let a =5;或者把var a = 5放到一个立即执行函数里。
再举一个函数提升的例子
function test(a){
if(!a){
var a = 5;
}
function a(){}//function declaration
console.log(a);
}
test(0);
//打印出function a(){}
执行的实际代码如下
function test(a){
function a(){}
var a;
if(!a){
a = 5;
}
console.log(a);
}
test(0);
//打印出function a(){}
如果代码做以下修改
function test(a){
if(a){
var a = 5;
}
function a(){}
console.log(a);
}
test(0);
//打印出5
因为a被重新赋值了。
function test(a){
function a(){}
var a;
if(a){
a = 5;
}
console.log(a);
}
test(0);
// if(a)一直是 true,打印出5
声名变量var a,只是让解释器知道有这个a的存在,a到底是什么,就需要对变量进行定义:a=5。如果再给a赋值:a = function(){},那a又被定义为了函数。a到底是什么是由定义来决定的。定义的是什么,输出的就是什么。不为因为再次的声名而改变。如果用函数表达式来定义函数,会出现什么情况:
function test(){
b();
var b = function (){}
}
test()
//会报错“undefined is not a function”
函数表达式时,只用变量名被提升,它定义的函数体依然留在原处。执行的代码是这样的
function test(){
var b;
b();
b = function (){}
}
test()
只对b做了声名,而没有定义,所以执行到b()会报错。
Scoping--作用域
ES6之前只有函数作用域。ES6加入块级作用域。用let声名的变量是块作用域内有效,用var声名的变量在函数作用域与块作用域里有效。
作用域链
作用域内取值是从创建该函数的位置取值,而不是从调用该函数的位置取值。
https://yq.aliyun.com/articles/693736
Execution Context 执行上下文
执行上下文是在执行过程中产生的。
https://juejin.im/post/59e85eebf265da430d571f89?spm=a2c4e.11153940.blogcont685883.21.727f127e0QVeWU
作用域和执行上下文之间最大的区别是:
执行上下文在运行时确定,随时可能改变;作用域在定义时就确定,并且不会改变
IIFE(Immediately Invoked Function Expression)
形式有多种:
(function(){ cosole.log(1); })()
(function(){ console.log(1);}())
+function(){console.log(1);}()
!function(){console.log(1);}()
void function(){console.log(1);}()
这样写是编译不过去的:function(){console.log(1);}()
顾名思义,immediately invoked function expression,是被解析成为一个函数表达式,然后自执行。
立即调用函数有个超强的用法,模块模式,如下
var counter = (function(){
var i = 0;
return {
get: function(){
return i;
},
set: function(val){
i = val;
},
increment: function(){
return ++i;
}
}
}());
counter.get();//0
counter.set(3);
counter.increment();//4
counter.increment();//5
想要扩展counter的方法:
var counter = (function(c){
c.ext= function (){
console.log('extend');
}
return c;
}(counter || {}));
counter.ext();
refer: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.htm
https://yuiblog.com/blog/2007/06/12/module-pattern/
http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html
http://www.cnblogs.com/TomXu/archive/2011/12/30/2288372.htmll
javascript的几个知识点scoping, hoisting, IIFE的更多相关文章
- 理解 JavaScript Scoping & Hoisting(二)
理解 JavaScript Scoping & Hoisting(二) 转自:http://www.jb51.net/article/75090.htm 这篇文章主要介绍了理解 JavaScr ...
- JavaScript算法与数据结构知识点记录
JavaScript算法与数据结构知识点记录 zhanweifu
- JavaScript必须了解的知识点总结。
整理的知识点不全面但是很实用. 主要分三块: (1)JS代码预解析原理(包括三个段落): (2)函数相关(包括 函数传参,带参数函数的调用方式,闭包): (3)面向对象(包括 对象创建.原型链,数据类 ...
- JavaScript必须了解的知识点总结【转】
整理的知识点不全面但是很实用. 主要分三块: (1)JS代码预解析原理(包括三个段落): (2)函数相关(包括 函数传参,带参数函数的调用方式,闭包): (3)面向对象(包括 对象创建.原型链,数据类 ...
- javascript 关于闭包的知识点
javascript 关于闭包的认识 概念:闭包(closure)是函数对象与变量作用域链在某种形式上的关联,是一种对变量的获取机制. 所以要大致搞清三个东西:函数对象(function object ...
- 私人定制javascript中对象小知识点(Only For Me)
废话不多讲,先上笑话,然后再,.看懂这个的说明你的节操已经不再了. 晚饭后去理发店理发...割了吧...老板问我怎么剪,我悠悠的来一句往帅了剪...高潮往往令人想不到....旁边一在焗油烫头发的大妈说 ...
- 读《javascript语法精粹》知识点总结
昨天泡了大半天的读书馆,一口气看完了<javascript语法精粹>这本书,总体来说这本书还是写的不错,难怪那么多的推荐.<javascript语法精粹>主要是归纳与总结了ja ...
- 漫谈JavaScript中的提升机制(Hoisting)
前言 刚接触到JavaScript的时候,便知道JavaScript是按顺序执行的,是如浏览器的解析DOM树一样的流程,解析DOM结构的时候,如果遇到JS脚本或者外联脚本便会停止解析,继续下载脚本之后 ...
- JavaScript学习笔记——对象知识点
javascript对象的遍历.内存分布和封装特性 一.javascript对象遍历 1.javascript属性访问 对象.属性 对象[属性] //字符串格式 //javascript属性的访问方法 ...
随机推荐
- SetFileAttributes 设置属性
#include <Windows.h> #include <tchar.h> int WINAPI _tWinMain(HINSTANCE hInstance, HINSTA ...
- Openstack oslo.config【一】
OpenStack的项目貌似越来越多了,在Grizzly版之前,每个项目都得实现一套处理配置文件的代码.在每个项目的源码中基本上都可以找到openstack/common/cfg.py,inipars ...
- what?iView的DropDown没有element的split-button?提issure?等不及了,自己实现一个
开始正文之前,有必要先说自己实现这个组件的必要性描述. 话说大家做表格时,增删查改按钮都是放在哪里的?最简单的方式应该是这样: 是不是感觉奇丑无比啊,于是改成了这样: 但是这种操作按钮一多后就没位置放 ...
- MVC-Razor视图
Razor 视图引擎 与Aspx开发区别在于代码: 1.Razor 更智能,摒弃了<%%>格式,直接用@符号开启cs代码,遇到html时自动识别 2.遇到如汉字等即非cs代码,又非html ...
- JVM进程启动会启动哪些线程?
首先要明白一点:JVM本身是一个多线程的程序,和我们编写的java应用程序一样,当JVM启动执行时就是在操作系统中启动了一个JVM进程.我们编写的java单线程或多线程应用进程都是在JVM这个程序中作 ...
- 介绍Kubernetes监控Heapster
什么是Heapster? Heapster是容器集群监控和性能分析工具,天然的支持Kubernetes和CoreOS,Kubernetes有个出名的监控agent—cAdvisor.在每个kubern ...
- @Conditional 原理
1,这里讲的是:org.springframework.context.annotation.Conditional 2,在springConfig文件里注册bean @Conditional(Col ...
- python3 error 机器学习 错误
AttributeError: 'NoneType' object has no attribute 'sqrt' 这个错误其实是因为 plt.scatter(x[:,0],x[:,1],x[:,2] ...
- 多态 鸭子类型 反射 内置方法(__str__,__del__) 异常处理
''' 1什么是多态 多态指的是同一种/类事物的不同形态 2 为何要有多态 多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象 多态性的精髓:统一 多态性的好处: 1增加了程序的 ...
- TCP/IP学习
1.TCP/IP网络包括两部分 ①传输协议 ②网络协议