作用域与提升

(一)词法作用域,动态作用域的区别

因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。
而与词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的。

function foo() {
	console.log( a ); 
}
function bar() {
	var a = 3;
	//2 该处是函数调用,词法作用域会进入函数foo中,foo的上级作用域为全局作用域,因此为2;
	//javascript采用词法作用域,故此处输出为2,若是采用动态作用域,此处则应该为3.
	foo();
	(function foo2() {
		console.log( a ); //3 该处是函数表达式,词法作用域会进入函数foo2中,foo2的上级作用域为bar(),因此为3;
	})();
}
var a = 2;
bar();

词法作用域查找只会查找一级标识符,比如 a、b 和 c。如果代码中引用了 foo.bar.baz, 词法作用域查找只会试图查找 foo标识符,找到这个变量后,对象属性访问规则会分别接 管对 bar 和 baz 属性的访问,因此存在重名变量是相当不安全的。

注意:

//由于浏览器演进的历史遗留问题,在创建带有 id 属性
//的 DOM 元素时也会创建同名的全局变量。例如:页面上有
<div id="foo"></div>

if (typeof foo == "undefined") {//foo已经被Dom声明为全局变量了
	foo = 42; // 永远也不会运行
}
console.log( foo ); // HTML元素
//你可能认为只有 JavaScript 代码才能创建全局变量,并且习惯使用 typeof 或 .. in window来检测全局变量。
//但是如上例所示,HTML 页面中的内容也会产生全局变量,并且稍不注意就很容易让全局变量检查错误百出。

(二)函数作用域,块级作用域

javascript中function中才有函数作用域,if与for语句是没有块级作用域的。
块作用域只有在let,try…catch, const, with(不推荐使用)中。(’{}'进行块级显式操作,例如let a=1; => {let a=1;})

  • if与for代码串是没有私有作用域的
"use strict";
//if语句
var foo = true, baz = 10;
if (foo) {
	var bar = 3;
}
if (baz > bar) {//10 > 3
	console.log( baz );//10
}
//for循环同样会污染全局变量
for (var i=0; i<10; i++) {
	console.log( i );//1 2 ... 9
}
console.log( i );//10
  • 函数表达式与函数声明
    区分函数声明和表达式最简单的方法是看 function 关键字出现在声明中的位置(不仅仅是一行代码,而是整个声明中的位置)。
    如果 function 是声明中的第一个词,那么就是一个函数声明,否则就是一个函数表达式。
var a = 2;
(function IIFE() {//立即执行函数表达式
	var a = 3;
	console.log( a ); // 3
})();//IIFE的另一种写法(function IIFE(){}()); 依据个人习惯即可
console.log( a ); // 2
  • 块级作用域
{
	let a = 2;
	console.log( a );
}
console.log( a ); // ReferenceError

//try..catch语句在目前javascript环境中效率十分低下,日后有望提升执行效率
try{
	throw 2;
}catch(a){
	console.log( a ); // 2
}
console.log( a ); // ReferenceError

(三)提升

  • 函数优先
    函数声明和变量声明都会被提升。但是一个值得注意的细节是函数会首先被提升,然后才是变量。
  • 函数声明会被提升,但是函数表达式却不会被提升
foo(); // 1
var foo;
function foo() {
	console.log( 1 );
}
foo = function() {
	console.log( 2 );
};
foo();//2
  • 重复声明同名函数,会以后声明的为准
foo(); // 3
function foo() {
	console.log( 1 );
}
var foo = function() {
	console.log( 2 );
};
function foo() {
	console.log( 3 );
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Funnee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值