一,执行上下文环境
在JavaScript中,一段代码在执行前,都会生成一个执行上下文环境,来初始化代码中定义的变量,函数,还有this。
其中又生成执行上下文又分为了三种情况,
1.全局代码的初始化
2.函数体代码的初始化
3.eval代码初始化
二、针对全局环境下的代码,生成执行上下文时会做哪些工作呢?
1.变量的初始化,初始化为undefined
2.函数表达式内的变量声明,初始化为undefined
3.给this赋值,全局环境下就赋值为window
4.函数声明赋值,所以函数声明会被前置。
另外针对函数体,在传参后未执行前,也会初始化一个执行上下文环境,其中的
1.argument对象会被赋值
2.参数会被赋值
3.自由变量的取值作用域会被赋值。
举个例子
function Fn(x){
console.log(x)
}
Fn(10);
传入参数后,未执行前,该函数Fn生成了一个执行上下文环境,
包括了
argument赋值为[10];
参数x赋值为10;
此外,函数每次被调用时都会生成一个新的执行上下文
三、针对this
在全局环境下,this指的就是window。因为在代码初始化阶段this就被赋值了。
但是,如果this在函数体内,this的指向只有函数被调用的时候才能确定。
在函数体中的this可以分为几种情况
1.构造函数中的this
举个例子
function foo(){
this.name = 'wang';
this.age = 18;
}
var obj = new foo()
obj.name // wang
像上面的函数声明,如果直接调用就是普通的函数。如果用new关键字去赋值给一个变量,就是一个构造函数。
针对构造函数中的this,指向的是它new出来的这个对象。
如果是普通调用,该例中,this就指向window
2.函数作为一个对象的方法
举个例子
var obj = {
name:'wang',
fn:function(){
console.log(this);
console.log(this.name)
}
}
obj.fn() //obj wang
在这种情况下,对象方法中的this指向的是该对象本身。
那如果赋值给一个变量呢。比如
var fo = obj.fn;
fo();
这种情况的话,因为fo函数就是定义在全局环境下,跟obj没有关系,所以this指向window
3.用call,apply,bind调用函数
使用这三种方法调用函数的话,函数中的this就会指向call,apply,bind方法中传入的第一个参数,是一个对象。那如果传入的是null或undefined,就会指向window
4.全局 & 调用普通函数
在全局环境下,调用函数的话this是指向window的。
但是有一种情况要注意
var obj = {
name:'sss',
fn:function(){
function f(){
console.log(this);
console.log(this.name)
}
f();
}
}
obj.fn()
函数f虽然是在对象方法内部定义的,但是this确实指向了window