当前位置: 首页 > 编程日记 > 正文

JS笔记(一):声明提升

我们习惯将 var a = 2; 看作一个声明,而实际上JavaScript引擎并不这么认为。他将 var a a = 2 当作两个单独的声明,第一个是编译阶段的任务,第二个则是执行阶段的任务。

——《你不知道的Js》

 

变量提升

变量提升的概念已经为大家所熟知,简单来讲就是在代码执行前编译器会将变量的声明提升至其所在作用域(不是全局作用域)的顶端。看一个简单的例子。

         

如果不存在变量提升,很显然这行代码会给我们抛出一行错误  ReferenceError : a is not defined . 因为我们还没有定义 a 就使用了它。

由于存在变量声明提升,通过预编译对 a 的声明已经提升至最前,于是这里打印变量 a 的值就不会抛出 ReferenceError ( a is not defined )异常。而是打印出了 a 的值 undefined

为什么 a 为 undefined ? 这过程中还有一些细节需要注意。比如赋值与声明提升的先后关系。

undefined 表明 a 处于未赋值状态。说明了变量的赋值操作并未随着变量声明的提升而被提升,而是仍被留在原地。等同于下图。

函数声明提升

跟变量声明的提升一样,只不过声明的不再是变量而是一个函数了 var a  = >  function a(){...} 。还是来看例子。

由于存在函数声明提升,函数 foo 被正常执行打印出 a 的值为2。但这里同样有一个细节需要注意。

这里看到,函数声明会被提升,但函数表达式并不会。其中的道理跟上面的变量赋值是一样的。对变量 foo 的声明首先被提升,将一个匿名函数赋值给变量 foo 的操作还被丢在原地。像下面这样。

执行到 foo() 时,这里的 foo 只是一个值为 undefined 的小变量,还未被改变为函数呢。对一个 undefined 进行函数调用当然要抛出 TypeError 错误。

说到这里,还有一种具名的函数表达式(非匿名函数表达式),常常被人(我)误解。看例子。

为什么会出现 ReferenceError ? 先从函数的声明方式说起。函数有且只有两种声明方式。

  1.  一般函数声明:function foo(){ }
  2. 函数表达式声明:var foo = function(){ }; 等号后面必须为匿名函数

 对于 var foo = function bar(){ }; 这种具名函数表达式声明函数的方式等同于普通函数表达式。但此时的 bar 仅仅作为 foo() 的一个内部属性,这就是上例中抛出 ReferenceError 的原因。

bar 作为 foo() 的内部属性只可以在 foo() 内部访问,于是上图例中返回了 bar() 函数。 在函数外部调用局部变量 bar 就一定会出现 ReferenceError 错误。

优先级问题

 一般存在两个优先级问题:

  1. 函数的声明提升优先级高于同名变量声明提升。

   >>>  

由此可见,无论在什么时候函数声明总是会被提升到普通变量之前。另外,重复的 var 声明会被忽略(严格模式下,let  const 不可重复声明,抛出 SyntaxError ),但出现在后面重复的函数声明会覆盖前面的。

  2. 函数形参高于同名局部变量。

  之前我还从没注意过这个问题,直到昨天做了一道题qwq。我先来简化一下原题便于理解他们的优先级问题。

      >>>   

函数内部局部变量 foo 声明提升到所在作用域顶部后,此时它的值应该为 undefined 。像这样。

  

  但打印 foo 值却显示为1。说明此时打印 foo 实际上是函数的形参,也同时说明了函数的形参是优先于函数局部同名变量的。

  (形参实际上是函数内部自动创建的新变量,这样就相当于两个重复声明后面的声明被忽略,优先级关系也就不难理解了)

接下来上原题啦,其实很简单。不多做解释。但如果不清楚他们的优先级关系就会做错喔。

最后,重复命名可能会导致一些我们难以掌控的事情发生,所以尽量不要在同一作用域中进行重复定义。

--End--

转载于:https://www.cnblogs.com/qimeng/p/7064032.html

相关文章:

event对象(触发机制)

Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态,常用事件如下: 事件触发时机onchange用户改变域的内容onclick鼠标点击某个对象onfocus、onblur元素获得焦点、失去焦点时触发onkeydown、o…

3种方式理解旋转变换

有V1(x1,y1), 求这个点绕坐标原点旋转θ角度后的坐标V2(x2,y2) 1.三角函数 假设(x1,y1)(Rcosα,Rsinα) (x2,y2) (Rcos(αθ),Rsin(αθ)) (Rcosαcosθ-Rsinαsinθ,RcosαsinθRsinαcosθ) (x1cosθ-y1sinθ,x1sinθy1cosθ) 2.坐标轴旋转 如果有向量Ax&#xff1d…

Yahoo中国变脸?

今天看到一则消息“门户雅虎走了”,到Yahoo中国网站一看,果然首页变成简洁的以搜索为主的页面。原来的Yahoo首页成为现在的“资讯首页”。似乎Yahoo中国要在搜索上大干一场……

ubuntu14.04上搭建android开发环境

这几天心血来潮,想在ubuntu上写写android软件。所以就上网找些资料在ubuntu上搭建android环境。结果要么时不完整的,要么就是过时的。所以我把我搭建android环境的过程写下了,以便以后忘了能够參考參考,也给来看这篇博文的读者一些…

nuxt.js实战之移动端rem

nuxt.js的项目由于是服务端渲染,通过js动态调整不同尺寸设备的根字体这种rem方案存在一种缺陷。由于设置字体的代码不能做服务端渲染,导致服务端返回的代码一开始没有相应的跟字体,直到与前端代码进行合并根字体改变,这就造成我们…

Window对象中setInterval()和setTimeout()的区别

- setInterval("",time)&#xff1a;每隔指定的时间执行一次调用的函数或计算表达式&#xff0c;如果不停止会无限次去执行&#xff1b; - setTimeout("",time)&#xff1a;在指定时间的最后执行一次调用的函数或计算表达式&#xff0c;仅执行一次。 <…

妹妹生了个女儿,纪念一下

下午艺花打电话告诉我&#xff0c;春兰生了个女儿。 赶紧发了短信过去询问情况&#xff0c;没想到妹夫就打了电话过来&#xff0c;换了她上线&#xff0c;声音里透着初为人母的喜悦&#xff0c;很为她高兴。她说生产不是很顺利&#xff0c;后来剖腹才产下了小外甥女&#xff0c…

如何获取HTML元素对应JavaScript对象?

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><!--如何获取HTML元素对应JavaScript对象--><!--我们首先要明白标签和元素的区别&#xff1a;标签&#xff1a;div标签&a…

HTML样式以及使用

HTML的样式包含&#xff1a; 1&#xff0c;标签{style &#xff0c;link} 2。属性{rel"styleSheet"外部样式表&#xff0c;type"text/css",margin-left:边距} 外部样式的插入方法&#xff1a;当中myStyle.css是你自定义的css文件&#xff0c;里面能够写上你…

VMWARE虚拟机安装系统提示CPU已被客户机操作系统禁用和secureCUT乱码

错误&#xff1a;VMWARE虚拟机安装系统提示CPU已被客户机操作系统禁用 改正&#xff1a;找到虚拟机的位置找到下图灰色的部分&#xff1a;打开 .vmx后缀的操作系统配置文件&#xff0c;加入以下代码&#xff1a; cpuid.1.eax :: 2.补充一个secureCUT乱码的 1.找到会话管理----…

代码 设计 生活 (2)--- 菜鸟

刚开始涉足这个领域&#xff0c;可以说自己是个十足的菜鸟&#xff0c;不对&#xff0c;菜鸟是行内行对新人的称呼&#xff0c;应该说我当时孤陋寡闻的连菜鸟这个词都没听说过。既然进了这行&#xff0c;也就先从基层的菜鸟做起吧。说实话初中和高中是有开计算机课程的&#xf…

如何用JavaScript操作form表单组件?

一、用JavaScript操作按钮&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>JavaScript操作form表单组件</title></head><body><span></span><br /><!--用JavaScript操…

电梯演讲(团队)

各位同学大家好&#xff0c;我的产品时间管理系统是为了解决大学生们制定计划难和执行计划难的痛苦&#xff0c;他们需要一个能够帮助他们制定时间计划并且可以起到一定督促作用的软件&#xff0c;但是现有的方案并没有很好的解决这些需求&#xff0c;我们可以帮助用户 一键定做…

1291 火车线路(区间修改,区间最值)

1291 火车线路 时间限制: 1 s空间限制: 128000 KB题目等级 : 大师 Master题目描述 Description 某列火车行使在C个城市之间(出发的城市编号为1&#xff0c;结束达到的城市的编号为C)&#xff0c;假设该列火车有S个座位&#xff0c;现在有R笔预订票的业务。现在想对这R笔业务进行…

在DataTable中创建计算列

我们知道DataTable是内存中的一个表&#xff0c;可以用DataColumn和DataRow来构造一个DataTable,并且用DataColumn的Expression属性来创建计算列。 (1)创建计算列,该列的值是其它列的计算值.如&#xff1a; DataSet1.Tables("myTable").Columns("Pri…

go 网络请求篇

---恢复内容开始--- 今天特意找了下go的网络请求篇&#xff0c;get请求是ok的&#xff0c;post请求一直不下来&#xff0c;搜索了下&#xff0c;代码都差不多&#xff0c;无法拿到post数据&#xff0c;先整理一篇&#xff0c;亲测可用。 针对post &#xff0c;先来说下post 四种…

jQuery添加DOM节点常用的5种方法

一、内部插入&#xff08;前插入、后插入&#xff09;&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>jQuery添加DOM节点常用的五种方法</title><script type"text/javascript" src"…

未能从程序集 XX加载类型XXX的错误解决方法(借以提醒NHibernate使用者)

这是写.hbm.xml文件最容易犯的错误之一首先,Class的Name属性必须是"完全限定类名,程序集名"这里,例如<class name"ibiz.core.domain.product,ibiz.core">很多人在这里写成"product"或者"product,ibiz.core",这样,没有写上namesp…

正则最常用到的东西

一种组合方式: (.*?)匹配除换行符以外任意字符,匹配模式加上re.S,则开启无敌模式,匹配一切.需要的内容放在括号里面. 两个方法: re.searchgroup()可以找到第几个括号的东西,在确定只有一个内容时,使用re.search会提高效率, 因为re.search找到第一个就不会去找了,而findall会遍…

2005年你看过的,认为比较好的书,请大家一起来评评

我今年看过的书:设计模式 第三遍了..呵呵..有时候莫名其妙的拿到书就很兴奋..充满魔力的书...敏捷软件开发&#xff1a;原则、模式与实践 第二遍了..和第一本一样..同样充满着魔力..Java编程思想 (第二版) 看第二遍了,主要是补充一下以前看不懂的,或者忽略过的技术..比如垃…

从今天开始收集一些经典的算法。

一。用过excel的都知道excel的列编号是这样的&#xff1a; a b c .... z aa ab ac .... az ba bb bc .... yz za zb zc .... zz aaa aab aac .... 分别代表以下编号&#xff1a; 1 2 3 .... 26 27 28 29 .... 52 53 54 55 .... 676 677 678 679 .... 702 703 704 705 .... 请写…

ros ddns

ROS5X-6X脚本&#xff08;10-15分钟执行一次&#xff09;#DDNS本站帐号:global ddnsuser "用户名" #DDNS本站密码:global ddnspass "密码"#ROS系统版本&#xff08;5X,6X&#xff09;:global rver "5X"#DDNS域名(本站添加的子域名):global zho…

apicloud 基础

时间成本 人力成本 很多人想开发app 又碍于时间和金钱成本 。 本色对app 要求不高的话。 混合app 开发是一种很好的方式。 apicloud 就是一种很好的方式。 apicloud 配合aui 和vue 既节省时间 又加大了开发效率。不失为创业公司的选择。 对前端来讲 你需要的学习有几个方…

jQuery中的页面载入($()、ready(fn)、onload)

用jQuery进行页面载入时有集中方式&#xff0c;我们通过例子来说明一下&#xff1a; 第一种&#xff08;通过window.onload()&#xff09;&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><…

性能,安全,集成才是web之道

年底了,又是一年过去了.今年感觉收获颇多..做web开发将近4年时光,期间没有做过任何完整的winApp,一直从事者网络开发.从最初的留言本--新闻--企业网站--论坛--聊天室--大型门户网站--大流量下载网站--网站系统优化,一路走来,不仅仅是技术上的进步,更重要的是思想上的成熟..今天…

站立会议第四天

今天是我们冲刺周期第四天&#xff0c;今天的站立会议主要有以下内容&#xff1a; 1.完成录入菜的数量函数的编写&#xff08;gersort&#xff09; 部分代码如下&#xff1a; void Cmenu::getsort(int SORT) // 录入所点菜的数量 { sortSORT; } cout<<"…

iOS 后台挂起的一些坑

特别说明&#xff1a;后台状态&#xff1a;当前app如果不是作为屏幕中的第一层&#xff0c;呈现显示给用户&#xff0c;那么此时app就是后台状态。锁屏&#xff08;包括&#xff1a;当前应用下锁屏、其他应用下锁屏、桌面锁屏&#xff09; 用户在使用其他应用app2&#xff0c;…

jQuery绑定事件的三种常见方式(bind、one、【change、click、keydown、hover】)

一、bind(type,[data],fn)&#xff1a;为每个匹配元素的特定事件绑定对应的事件处理函数。 也可以同时给一个元素绑定多个事件&#xff0c;我们来看一下例子&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>…

Visual Web Development 2005开发ASP.NET使用小技巧

&#xff08;1&#xff09;改变端口 VWD2005自带有一个内置的web服务器&#xff0c;当我们使用它进行开发ASP.NET时&#xff0c;可以发现它默认使用的端口是动态改变的&#xff0c;要想使用固定端口&#xff0c;步骤如下1&#xff09;在“解决方案资源管理器”里选择你的应用…

java 日志框架的选择Log4j-SLF4j-Logback

Log4j->SLF4j->Logback是同一个人开发的 import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;R…