JavaScript中的作用域与函数和变量声明的提升
var foo = 1;
function bar() {
if (!foo) {
var foo = 10;
}
alert(foo);
}
bar();//解释:js没有块级作用域,if switch while等不会有块级作用域
如果你对foo的值实际上为"10"而感到诧异的话,再看一下下面这个例子:
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
发现浏览器会弹出alert(1)。
//解释:第一点是函数声明的提升会把函数的实现都提升到作用域的最顶级,上面的函数b相当于
function b() {
function a() {}
a = 10;
return;
}
第二点是:这样的话,我们在b函数里面定义了一个a函数,a的作用域是在b函数的内部而非全局,这是对a的赋值相当于把a函数替换,作用域并不发生变化,相当于用var定义了一个a变量;所以在b函数外面输出a的时候只会去访问全局的a;
//var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);//报错a is undefined
另外:如果这里的a函数不是函数声明式定义的而是变量式定义的,变量提升而函数实现并不会提升:如下:
var a = 1;
function b() {
a = 10;
return;
a=function () {} //此处的a是全局的变量
}
b();
alert(a);//10
如果是这样的话
var a = 1;
function b() {
a = 10;
return;
var a=function () {} //此处的a是局部变量
}
b();
alert(a);//1
等价于这个:
var a = 1;
function b() {
var a;
a = 10;
return;
a=function () {} //此处的a是局部变量
}
b();
alert(a);//1
可以发现,声明语句中的赋值部分并没有被提升声明,只有名称被提升了。两种函数声明方式:
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
}
test();
这个例子中,只有包含函数体的函数声明会被提升声明。foo虽然会被提升声明,但是函数体却在执行中被赋值。以上就是提升声明时机的基本概念,看起来一点也不复杂。 Name resolution order(JavaScript中名称解析顺序) 名称解析顺序有4步,一般来说,如果一个名称已经被定义了,它就不会被另一个具有同名称的属性所覆盖。这也就意味着,函数声明会比变量声明优先。并不是名称的赋值操作不会被执行,只是说声明部分被忽略了而已。有些例外:
- 原生变量
arguments特立独行,包含了传递到函数中的参数。如果自定义以arguments为命名的参数,将会阻止原生arguments对象的创建。所以勿使用arguments为名称的参数。 - 胡乱使用
this标识符会引起语法错误。 - 如果多个参数具有相同的命名,那么最后一个参数会优先于先前的,即时这个参数未定义。
Named Function Expressions(函数命名表达式) 你可以通过函数表达式给函数命名,语法上看起来像是函数声明,实则不是。上一段代码:
foo(); // TypeError "foo is not a function"
bar(); // valid
baz(); // TypeError "baz is not a function"
spam(); // ReferenceError "spam is not defined"
var foo = function () {}; // anonymous function expression ('foo' gets hoisted)
function bar() {}; // function declaration ('bar' and the function body get hoisted)
var baz = function spam() {}; // named function expression (only 'baz' gets hoisted)
foo(); // valid
bar(); // valid
baz(); // valid
spam(); // ReferenceError "spam is not defined"
JavaScript中的作用域与函数和变量声明的提升的更多相关文章
- javascript中var let const三种变量声明方式
javascript中var let const三种变量声明方式 1.var ①var表示声明了一个变量,并且可以同时初始化该变量. ②使用var语句声明的变量的作用域是当前执行位置的上下文:一个函 ...
- Javascript中函数及变量定义的提升
<html> <head> <title>函数提升</title> <script language="javascript" ...
- JavaScript中的作用域
很多(JavaScript)开发者都在讨论"作用域",但它是什么?它们在JavaScript中的任何地方!我发现很多年轻的开发者不知道作用域是什么.他们中大多数人可以用jQuery ...
- [转]Javascript中的自执行函数表达式
[转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...
- 深入理解javascript中的立即执行函数(function(){…})()
投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...
- 【翻译】JavaScript中的作用域和声明提前
原文:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html ===翻译开始=== 你知道下面的JavaScript脚本执 ...
- JavaScript中的作用域和闭包
首先强烈安利<你不知道的JavaScript>,JS初学者进阶必读. 对于从C++.Java等静态语言转向JavaScript的初学者(比如我)来说,JS一些与众不同而又十分要紧的特性使得 ...
- JavaScript中的作用域和声明提前
[翻译]JavaScript中的作用域和声明提前 原文:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html ===翻译 ...
- javascript中的立即执行函数(function(){…})()
javascript中的立即执行函数(function(){…})() 深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包 ...
随机推荐
- 线性表-串:KMP模式匹配算法
一.简单模式匹配算法(略,逐字符比较即可) 二.KMP模式匹配算法 next数组:j为字符序号,从1开始. (1)当j=1时,next=0: (2)当存在前缀=后缀情况,next=相同字符数+1: ( ...
- FFmpeg YUV视频序列编码为视频
上一篇已经写了如何配置好开发环境,这次就先小试牛刀,来个视频的编码.搞视频处理的朋友肯定比较熟悉YUV视频序列,很多测试库提供的视频数据都是YUV视频序列,我们这里就用用YUV视频序列来做视频.关于Y ...
- Java中finalize方法用途何在?
package thinking.in.java.demo; /* * finalize的用途何在? * *本例的终止条件是L所有的Book对象在被当做垃圾回收前都应该被签入.但是在main方法中 * ...
- delphi 常用属性+方法+事件+代码+函数
内容居中(属性) alignment->tacenter mome控件 禁用最大化(属性) 窗体-> BorderIcons属性-> biMaximize-> False 让鼠 ...
- 浅析作用域链–JS基础核心之一
JS中的作用域,大家都知道的,分为全局作用域和局部作用域,没有块级作用域,听起来其实很简单的,可是作用域是否能够有深入的了解,对于JS代码逻辑的编写成功率,BUG的解决能力,以及是否能写出更优秀的代码 ...
- win10中android studio中的terminal不能输入
1 打开CMD窗口右击 2 3 重启电脑,你试试就知道了.
- xampp配置host和httpd可以随意访问任何本机的地址
1.修改host 不管你用的是什么系统,windows, mac,电脑上都会有一个 hosts 文件,修改这个文件,可以改变主机名所对应的 ip 地址.比如你安装了 Web 开发环境(MAMP 或 W ...
- Windows 环境下基于 Redis 的 Celery 任务调度模块的实现
搭建环境: Windows-x64 10 Celery 3.1.23 Celery-with-redis 3.0 Redis-win32-win64 2.4.5 实现步骤: 1.安装 Redis ...
- JQuery上传插件Uploadify API详解
一.相关key值介绍uploader:uploadify.swf文件的相对路径,该swf文件是一个带有文字BROWSE的按钮,点击后淡出打开文件对话框,默认值:uploadify.swf. scrip ...
- java反射快速入门(一)
本文会从以下几个方面讲起 ① 反射的简单解释 ② java反射的API接口 及 demo ③ 反射的优缺点.应用场景 一.什么是反射? java反射:在程序运行中动态获取类的信息,及动态调用对象的方法 ...