- 函数的调用栈规定了js的代码执行顺序,栈底永远都是全局上下文,栈顶则是当前正在执行的上下文。
- 全局上下文在浏览器关闭窗口后出栈。
- 遇到return会直接终止当前上下文代码执行,将当前上下文弹出栈。
- 函数在执行时才会创建执行上下文。
函数被调用时(执行上下文)时的生命周期分为两个阶段:
创建阶段:生成变量对象,确认作用域链,确定this指向
执行阶段:变量赋值,函数引用,执行其他代码。
执行完毕后出栈,等待被回收
上下文在创建阶段确认变量对象,就是获取变量名,并赋值undefined,在执行阶段才会完成赋值工作,就是变量声明提前。
函数声明的执行优先级(也就是创建阶段)会比变量声明的优先级高。所以在执行阶段同名的函数会被同名的变量重新赋值。因为函数优先声明,声明后被变量重新赋值了。
开发过程中可以通过单例模式与闭包,完成代码层面或者业务层面的模块分离。通过定义函数,return函数内变量的get和set方法来控制私有变量。
当前函数的this是在函数被调用执行时候才确定的。(在哪里调用,this就指向谁)
在一个函数的执行上下文中,this由该函数的调用者提供,由调用函数的方式来决定其指向。
题目1
var a = 20
var obj ={
a: 40
}
function fn() {
console.log ('fn this: ',this);
function foo() {
console.log(this.a);
}
foo()
}
fn.call(obj)
fn()
输出为 fn this: obj对象 this.a = 20 fn this: window this.a = 20 疑惑的是第一个输出this都已经是obj了,为啥 this.a还是20,不是obj的a
因为foo是独立调用的,谁.foo() this就是.前面那个对象。前面没.的话this就是window
题目2
function foo () {
console.log(this.a)
}
function active(fn) {
fn();
}
var a =20;
var obj = {
a: 10,
getA: foo,
active: active
}
active(obj.getA);
obj.active(obj.getA);
输出为两个20 套用一下
active(obj.getA); //等于下面的代码
active(function foo () {
console.log(this.a)
}) //等于下面的代码
function active(function foo () {console.log(this.a)}) {
function foo () {console.log(this.a)}
foo()
}
//调用的时候是在active里面调用的,active里面的foo前面没点,所以this是window 所以this.a是20
obj.active(obj.getA); //等于下面的代码
obj.active(function foo () {
console.log(this.a)
}) //等于下面代码
active(fn) {
fn(); //这里的fn等于function foo () {console.log(this.a)}
}
//原理同上 fn在调用时候没有点,所以this就是window,所以this.a是20
题目3
var n ='window';
var object = {
n: 'object',
getN: function() {
return function() {
return this.n;
}
}
}
console.log(object.getN()())
输出是window,因为最后return的时候方法调用时候前面没点,所以就是window
改一下
var n ='window';
var object = {
n: 'object',
getN: function() {
console.log(this.n) //object
return function() {
return this.n;
}
}
}
console.log(object.getN()()) //window
再改一下
var n ='window';
var object = {
n: 'object',
getN: function() {
console.log(this.n) // object
var that = this //闭包,所以 里面return的this还是object
return function() {
return that.n; // object
}
}
}
console.log(object.getN()())
闭包
闭包的意义在于js在执行完垃圾回收机制时,保留一些有用的变量或方法