作用域/执行上下文
- JavaScript分为解释阶段和执行阶段
- 作用域是解释阶段,就是函数写的时候作用域就确定了
- 执行上下文是执行代码的时候才确定,特别是this的指向
作用域
- 全局作用域
- 函数作用域
- 块级作用域(ES6中 let const定义的变量有块级作用域,而var没有块级作用域)
{
var username = 'lisi'
let age2 = 11
}
let age = 12
console.log(age); //12
console.log(age2); //error
console.log(username); //lisi
作用域链就是现在当前作用域中找,找不到就去上一级作用域中找
执行上下文
执行上下文是JavaScript运行时环境中的一个概念,它是用于管理每个函数执行时相关变量、函数和作用域的一种机制。在JavaScript中,每当调用一个函数时,就会创建一个执行上下文,该执行上下文包含了该函数所有的变量、参数、内部声明的函数以及对父级作用域的引用等信息。执行上下文还会建立函数执行的作用域,并且在函数执行结束后进行清理。
说到底,执行上下文就是当前代码所执行的环境,你在全局中执行,就创建一个全局上下文,在函数中被执行就创建函数上下文
执行上下文分三种
- 全局上下文:只有一个,浏览器中的全局对象就是 window对象,this 指向这个全局对象
- 函数内部上下文:函数被调用就创建
- Eval 函数执行上下文:但是用的不多,不讲
var x = 10;
function fn() {
console.log(x);
}
function show(f) {
var x = 20;
f();
}
show(fn); //10 当前的执行上下文是全局
--------------------------------------------------------------
let x = 10
let obj = {
x:30,
fnn:function(){
fn()
}
}
obj.fnn() //10 当前的执行上下文是全局
----------------------------------------------------------------
function test(){
let x=40
function inner(){
console.log(x);
}
inner()
}
test() //40 test是在全局中,但是 inner()是在test中执行的
----------------------------------------------------------------
let x = 1;
function fn() {
let x = 2;
fn1();
function fn1() {
console.log(x);
}
fn2();
function fn2() {
let x = 3;
fn1();
}
}
fn(); //2 , 2
let b = 4;
let obj = {
b: 2,
fn1: function () {
console.log(b);
}
}
obj.fn1(); //4
//需要注意的是,尽管obj对象中存在一个属性b,但该属性只能通过obj.b来访问,
//而不能通过b来访问。因此,即使obj.fn1()函数中使用了console.log(b),
//它实际上是在访问全局作用域中的变量b,而不是对象obj中的属性b。
//如果想要访问obj对象中的属性b,可以使用console.log(obj.b)来打印该属性的值。
---------------------------------------------------------
let b = 4;
let obj = {
b: 2,
fn1: function () {
let b = 5;
console.log(b);
}
}
obj.fn1(); //5
----------------------------------------------------------
let b = 4;
let obj = {
b: 2,
fn1: function () {
console.log(this.b);
}
}
obj.fn1(); //2
//需要注意的是,这里使用了对象字面量语法来创建obj对象,其中包含一个名为b的属性。
//因此,obj对象中的属性b和全局作用域中的变量b是不同的变量。在上面的代码中,
//当obj.fn1()函数中使用this.b时,它引用的是obj对象中的属性b,
//而不是全局作用域中的变量b。
var obj = {
canon:'5d4',
fn1:function(){},
fn2: function () {
// let canon = '5d2'
console.log(canon)
}
}
obj.fn2() //语法错误
// fn2()是在全局中执行的,因为没有找到canon变量,先看自己内部有没,没有看全局,没有,则错误