资讯专栏INFORMATION COLUMN

函数&作用域提升

stormgens / 2421人阅读

摘要:立即执行函数表达式输出绑定在函数表达式自身的函数中而不是所在作用域,使值为的变量只能在内被访问。且变量名不会污染外部作用域。作用域执行一个非法操作来制造异常说明仅存在分句内部。且,函数声明可覆盖。

立即执行函数表达式(IIFE)

var a = 2;
(function foo() {
  var a = 3;
  console.log(a);//3
})();//IIFE
console.log(a);//2

输出:3 2
foo绑定在函数表达式自身的函数中而不是所在作用域,使值为3的变量a只能在{..}内被访问。 且foo变量名不会污染外部作用域。

var a=2;
(function IIFE(global) {//参数名为global
  var a=3;
  console.log(a);//3
  console.log(global.a);//2
})(window);//将window对象的引用传递进去
console.log(a);//2

输出:3 2 2
立即执行函数表达式的传参版本。

//倒置代码运行顺序
var a=2;
(function iife(def) {
  def(window);
})(function def(global) {
  var a=3;
  console.log(a);//3
  console.log(global.a);//2
});
console.log(a);

输出:3 2 2
同上。

作用域

try {
  undefined();//执行一个非法操作来制造异常
} catch(err) {
  console.log(err);//TypeError: undefined is not a function
}
console.log(err);//Uncaught ReferenceError: err is not defined

说明:err仅存在catch分句内部。

var foo=true;
if(foo) {
  let bar=foo*2;
  var b = foo*3;
  console.log(b);
  console.log(bar);
}
console.log(b);
console.log(bar);

输出:
3
2
3
Uncaught ReferenceError: bar is not defined
let关键字将变量绑定到所在作用域,所以在全局作用域找不到变量bar。

for(var i=0; i<10; ++i) {
  console.log(i);
}
console.log(i);

输出:1 2 3 4 5 6 7 8 9 10

for(let i=0; i<10; ++i) {
  console.log(i);
}
console.log(i);

输出:1 2 3 4 5 6 7 8 9 Uncaught ReferenceError: i is not defined

var foo=true;
if(foo) {
  var a=2;
  const b=3;
  console.log(a);
  console.log(b);
  a=3;
  b=4;
}
console.log(a);
console.log(b);

输出:2 3 Uncaught TypeError: Assignment to constant variable.
在为b赋值时直接报错,因为const的值是固定的,试图修改会引起错误。

如果将b=4;注释掉,则
输出:2 3 3 Uncaught ReferenceError: b is not defined
constlet一样,将变量绑定到所在作用域。

作用域提升

总结:变量和函数声明被提升到最上面,函数表达式不会被提升。

a=2;
var a;
console.log(a);
console.log(b);
var b=2;
/*以上代码相当于
var a;
var b;
a=2;
console.log(a);
console.log(b);
b=2;*/

输出:2 undefined
var a;定义声明编译 阶段进行
a=2;赋值声明在原地等待 执行 阶段
变量a的定义声明var a;被提升到最上面,即 a=2 之前,所以没有报错undefined.

foo();//1
var foo;
function foo() {
  console.log(1);
}
foo=function() {
  console.log(2);
}
/*以上代码相当于
function foo() {
 console.log(1);
}
foo();
foo=function() {
 console.log(2);
}

输出:1
函数foo的声明var foo;被提升到最上面。
注:函数首先被提升,然后是变量。且,函数声明可覆盖。

代码引用自《你不知道的JavaScript》系列,部分有更改。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101759.html

相关文章

  • JS中let与const命令如何使用

      本篇文章主要讲述JS中let与const命令使用,通过代码展示给各位。  let命令  基本使用  在ES6中,let命令是新增的声明变量,与var的差异在于let无法重复声明,且let有效只是在其命令的代码块内,let禁止变量出现变量提升现象,let的特点就是通过暂时性死区的方式来避免程序上的错误  代码块:使用{}包括起来的内容  声明变量:分配一个存储空间  不可重复声明:let声明过后...

    3403771864 评论0 收藏0
  • ES6笔记之 let &amp;&amp; const

    摘要:声明的变量只在其所在的代码块内有效。只要在声明之前使用这些变量,就会报错。在语法上称为暂时性死区有时候,会不经间遇到比较隐蔽的死区,不太容易被发现。不允许重复声明不允许在相同的作用域内声明同一个变量。一旦声明,其值就不能再改变。 let && const let let声明的变量只在其所在的代码块内有效。 { let a = 10; } console.log(a) //R...

    aristark 评论0 收藏0
  • 详解Javascript的作用作用链以及闭包

      一、我们先说说javascript的作用域  ①全局变量-函数体外部进行声明  ②局部变量-函数体内部进行声明  1)函数级作用域  javascript语言中局部变量不同于C#、Java等高级语言,在这些高级语言内部,采用的块级作用域中会声明新的变量,这些变量不会影响到外部作用域。  而javascript则采用的是函数级作用域,也就是说js创建作用域的单位是函数。  例如:  在C#当中我...

    3403771864 评论0 收藏0
  • es6必会之let &amp;&amp; const

    摘要:副作用,无副作用可执行和关键词。和不能像一样同一个下声明多次和不会像一样变量声明提升原因是,存在因此不能,赋值前使用变量。 showImg(https://segmentfault.com/img/bVbhPlD?w=1271&h=715); 关键词: let ,const, blocking scope ,temporal dead zone,redeclaration,reassi...

    ygyooo 评论0 收藏0
  • const &amp; let

    摘要:前世在还未出现前,的世界一直是的统治在中用于变量声明的关键字。的出现给带来了块级作用域,解决了变量提升,禁止了重复声明变量,让少了很多疑惑的地方。时代已经过去了,各种特性用起来。 前世 在 const & let 还未出现前,JS 的世界一直是 var的统治 var:在JS中用于变量声明的关键字。 特点: 变量提升 只有函数作用域或者全局作用域,没有块级作用域 重复声明变量 循环体重...

    or0fun 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<