【面向秋招】
关注我一起进步!
- 浅层理解作用域
- 深层理解作用域
3.理解预编译
前言:兄弟们,上一篇文章,我们理解了什么是面向对象?以及面向对象的new的实现原理?大家都知道,js执行过程是创建,运行和销毁的,既然已经知道了创建过程中new的实现原理,那么,我们接下来呢就要关注作用域链了!
浅层的随便看看就好,水平往往不体现在这里!
作用域包括全局作用域和函数作用域:
浅层理解的全局作用域:
1.在页面打开时创建,关闭时销毁
2.每个浏览器都会有自己的一个window窗口,可以直接使用
3.作用域是全局的,在script标签内的任何地方都可以访问到
4.全局作用域中的属性和函数都会被window对象的属性和方法保存
浅层理解函数作用域:
1.调用函数时创建。执行完毕后销毁
2.每次调用的函数是相互独立的
3.函数作用域的内部可以访问到函数外部的声明的变量,但是外部访问不了内部的变量
4.函数作用域内访问变量,函数的时候,会首先在自己作用域内寻找,如果没有则一直向上找到全局作用域为止
前置知识:
js预编译的四大步骤:
1.创建对象
1.找到形参,函数内声明变量,让其属性值都为undefined
2.形参和实参一体化(将实参赋值给形参)
3.在函数内部找到函数声明,(切记不要找函数表达式,咱们不理函数表达式)最后将函数体赋予函数
想必大家都应该是明白上述的浅层知识的,这边就不解释了!
深层理解函数作用域:
在js执行的预编译过程中,声明了变量和函数创建了内部局部对象AO(Actived Object) 全局象GO(Globle Object)
深刻解就来做下笔试题吧!
function test(a, b){
console.log(a);
console.log(b);
var b = 1;
console.log(b);
a = 2;
console.log(a);
function a () {}
var a;
b = 3;
var b = function () {}
console.log(a);
console.log(b);
}
test(1);
生成AO对象
AO{
}
将声明变量添加到AO对象内
AO{
a:undefined;
b:undefined;
}
将实参的值传递给形参
AO{
a:1;
b:undefined;
}
声明函数添加进AO对象内
AO{
a:function a () {};//值覆盖
b:undefined;//b是赋值,不是函数声明
}
执行函数,输出结果为
function a () {};
undefined;
1;
2;
2;
function () {};
var x = 1, y = z = 0;
function add(n) {
return n = n+1;
}
y = add(x);
function add(k) {
return k = k + 3;
}
z = add(x);
console.log(x,y,z)
//问执行完毕后 x, y, z 的值分别是多少?
//错误:
//x 1
//y 2
//z 4
//正确:
//x 1
//y 4
//z 4
//当函数声明重名时后面的会覆盖前面的,以为add(x)赋值给他们,都指向了同一个地址,所以y和z相同
//牢记:不管是什么,只要调用同一个名字的方法,因为赋值地址没有变化,所以,被赋值了相同方法的变量,都应该和最后一个执行的结果一致!!!
小提示:
1.先找函数声明,ok有了,那就输出这个
2,没函数声明,我找你的变量声明,在我前面那就输出你,前面没任何东西并且内部又没有同名的函数声明直接undefined
3.最后按照顺序依次赋值
假设预编译中console.log(变量某某)的前面没有任何东西,内部有同名有函数声明,变量某某输出就是函数声明,内部无同名函数声明变量某某输出就是undefined,然后再按照顺序赋值执行即可!!!
其实简而言之:变量声明和函数声明,电脑编译已经完成,第二遍就是按照顺序赋值就可以了。
持续更新中。。。。
有错误欢迎指正