JS作用域与变量提升

作用域指的是变量的可见区域

1.全局作用域

  • 全局作用域在网页运行时创建,在网页关闭时销毁
  • 直接写到script标签中的代码都在全局作用域中
  • 全局作用域中的变量是全局变量,可在任意地方访问
let a = 9 //全局作用域之全局变量,任何地方都能访问
console.log(a);//9
{
	console.log(a);//9
	function xxx(){
		console.log(a);//9
		function yyy(){
			{
				console.log(a);//9
			}
		};
		yyy();
	};
	xxx();
}

2.局部作用域

1)块级作用域

  • 块级作用域是一种局部作用域
  • 块级作用域在代码块执行时创建,在代码块执行完毕就销毁
  • 在块级作用域中声明的变量只能在块内部访问,外部访问不了

2)函数作用域

  • 函数作用域也是一种局部作用域
  • 函数作用域在函数调用时创建,调用结束后销毁
  • 函数每一次调用都会产生一个全新的函数作用域,它们都是独立的,互不影响
  • 在函数作用域中声明的变量只能在块函数内部访问,外部访问不了
let a = 9
console.log(a);//9
{
	let a = 10
	let c = 100
	console.log(a);//10
	function xxx(){
		console.log(a);//10
		console.log(b);//b is not defined
		function yyy(){
			{
				let b = 11
				console.log(b);//11
			}
		};
		yyy();
	};
	xxx();
}
console.log(c);//c is not defined

3.作用域链

当我们使用一个变量时,JS解释器会优先在当前作用域中寻找变量,如果找到了则直接使用,如果没找到,则去上一层作用域中寻找,找到了则使用如果没找到,则继续去上一层寻找,以此类推如果一直到全局作用域都没找到,则报错 xxx is not defined

let a = 9
let b = 1
function x(){
	let b = 10
	function y(){
		let c = 100
		function z(){
			{
				{
					console.log(a,b,c,d);//9  10  100 "d is not defined"
				}	
			}	
		}
		z()
	}
	y()
}
x()

总结:外面的变量里面可以访问,里面的变量外面访问不了。

4.var

1)Window对象

  • 在浏览器中,浏览器为我们提供了一个window对象,可以直接访问
  • window对象代表的是浏览器窗口,通过该对象可以对浏览器窗口进行各种操作
  • 除此之外window对象还负责存储JS中的内置对象( String( ),Number( )...)和浏览器的宿主对象( alert( ),console.log( )...)
  • window对象的属性可以通过window对象访问,也可以直接访问
  • 函数可以认为是window对象的方法
  • 向window对象中添加的属性会自动成为全局变量

2)var

  • 声明变量,作用和let相同,但是var不具有块作用域
  • 全局中使用var声明的变量,都会作为window对象的属性保存
  • 用function声明的函数,都会作为window的方法保存
  • 使用let声明的变量不会存储在window对象中,而存在一个秘密的小地方(无法访问)
  • var虽然没有块作用域,但有函数作用域
// 直接访问或通过window访问
console.log(Number("123")); //123
console.log(window.Number("123")); //123
window.console.log(Number("123")); //123
window.console.log(window.Number("123")); //123
// 函数可以看做是window的方法
function x(){
	console.log(1);
}
x() //1
window.x() //1
// 向window对象中添加的属性会自动成为全局变量
window.prop = "你好"
console.log(prop); //"你好"
{
	function xx(){
		console.log(prop);//"你好"
	}
	{
		xx()
	}
}
//全局中使用var声明的变量,作为window对象的属性保存,let则不是
var a = 100
console.log(window.a);//100
console.log(a);//100
let b = 200
console.log(window.b);//undefined
console.log(b);//200
// var没有块作用域,但有函数作用域
function xxx(){
	var aaa = 1000
}
console.log(aaa);//aaa is not defined
{
	var bbb = 1000
}
console.log(bbb);//1000

 5.提升

javascript代码执行是从上到下挨个执行,当有var,函数声明创建的函数时,会先把它们全部找出来,先执行它们,再依次逐行执行,这个就是提升。

1)变量的提升

  • 使用var声明的变量,它会在所有代码执行前被声明,所以我们可以在变量声明前就访问变量,此时的值为undefined(var a = 1,当程序开始执行,var a会被拿到最前面执行)

2)函数的提升

  • 使用函数声明创建的函数function fn(){  },会在其他代码执行前先执行,所以我们可以在函数声明前调用函数

3)let声明的变量实际也会提升,但是在赋值之前解释器禁止对该变量的访问

var a = 1
function fn(){
	a = 2 //没有声明变全局
	console.log(a);//2
}
fn()
console.log(a); //2 全局为2它为2

var a = 1
function fn2(){
	console.log(a);//undefined
	var a = 2;
	console.log(a);//2
}
fn2()
console.log(a);//1

function fn3(a){ //形参相当于变量声明
	console.log(a);//undefined
	a = 2;
	console.log(a);//2
}
fn3()
console.log(a);//1

function fn4(a){
	console.log(a);//1
	a = 2;
	console.log(a);//2
}
fn4(a)
console.log(a);//1

// 函数提升
console.log(b);// ƒ b(){alert(111)}
var b = 10;
b() //直接弹出111
function b(){
	alert(111)
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值