在执行全局代码前将window确定为全局执行上下文。
(1)对全局数据进行预处理:(并没有赋值)
(2)开始执行全局代码
在调用函数,准备执行函数体之前,创建对应的函数执行上下文对象(虚拟的,存在于栈中)。
(1)对局部数据进行预处理:
(2)开始执行函数体代码
this指的是,调用函数的那个对象。this永远指向函数运行时所在的对象。
解析器在调用函数每次都会向函数内部传递进一个隐含的参数,这个隐含的参数就是this。
根据函数的调用方式的不同,this会指向不同的对象:【重要】
需要特别提醒的是:this的指向在函数定义时无法确认,只有函数执行时才能确定。
this的几种场景:
例如:
functionFoo(name){//this={};this.name=name;//returnthis;}varfoo=newFoo();varobj={name:'A',printName:function(){console.log(this.name);}}obj.printName();functionfn(){console.log(this);//this===window}fn();作用域作用域指一个变量的作用范围。它是静态的(相对于上下文对象),在编写代码时就确定了。
作用:隔离变量,不同作用域下同名变量不会有冲突。
作用域的分类:
if(true){varname='smyhvae';}console.log(name);上方代码中,并不会报错,因为:虽然name是在块里面定义的,但是name是全局变量。
直接编写在script标签中的JS代码,都在全局作用域。
在全局作用域中:
全局作用域中的变量都是全局变量,在页面的任意的部分都可以访问到。
举例1:
console.log(a);vara=123;打印结果:undefined
举例2:
console.log(a);a=123;//此时a相当于window.a程序会报错:
所以说,下面的例子,会报错:
调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁。
每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的。
在函数作用域中可以访问到全局作用域的变量,在全局作用域中无法访问到函数作用域的变量。
在函数中要访问全局变量可以使用window对象。(比如说,全局作用域和函数作用域都定义了变量a,如果想访问全局变量,可以使用window.a)
提醒1:
vara=1;functionfoo(){console.log(a);a=2;//此处的a相当于window.a}foo();console.log(a);//打印结果是2上方代码中,foo()的打印结果是1。如果去掉第一行代码,打印结果是UncaughtReferenceError:aisnotdefined
functionfun6(e){console.log(e);}fun6();//打印结果为undefinedfun6(123);//打印结果为123作用域与执行上下文的区别区别1:
区别2:
联系:
当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用(就近原则)。如果没有则向上一级作用域中寻找,直到找到全局作用域;如果全局作用域中依然没有找到,则会报错ReferenceError。
外部函数定义的变量可以被内部函数所使用,反之则不行。