js预编译
js执行前会进行预编译。 会产生一个 GO ,也就是我们说的全局作用域 , 当一个方法被调用时会形成一个局部作用域 AO。
全局代码在执行的时候,先是 变量提升 , 在全局作用域内添加 属性,然后是 函数(以函数声明创建的函数)提升,再是代码执行。
1.全局预编译GO(Global Object)
- 创建GO对象,即window
- 给全局变量赋值 undefined
- 将全局的函数申明的函数名作为key,value为函数整体赋值到GO对象中
2.函数预编译AO (Activation Object)
- 创建AO对象
- 将函数内的形参和变量声明存储到AO对象中,值为undefined
- 将实参和形参统一
- 将函数内的函数申明的名称作为AO对象的key,函数的整体内容为value 存储到AO对象
来个例子:
function f(a){
console.log(a);
var a=123;
console.log(a);
function a(){}
var b=function(){}
function d(){}
}
f(1)
//ƒ a(){}
//123
代码分析:
- 创建AO对象
AO={}
- 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
AO={
a:undefined,
b:undefined
}
- 将实参值和形参统一
AO={
a:1,
b:undefined
}
- 在函数体里面找函数声明,值赋予函数体:由于在函数中有 function a() {} ,这一函数因此此时AO中 a = function a() {}
AO={
a:function a(){},
b:undefined,
d:function d(){}
}
然后代码依次执行,第一个console时取AO中的a为function a(){},然后a=123,改变AO中的a为123
AO={
a:123,
b:undefined,
d:function d(){}
}
接着打印a为123
3.预编译小结
- 函数声明整体提升-(具体点说,无论函数调用和声明的位置是前是后,系统总会把函数声明移到调用前面)
- 变量声明提升-(具体点说,无论变量调用和声明的位置是前是后,系统总会把声明移到调用前,注意仅仅只是声明,所以值是undefined)
- 任何变量,如果未经声明就赋值,则此变量就位全局变量所有。(全局域就是Window)
- 一切声明的全局变量,全是window的属性; var a = 12;等同于Window.a = 12;
- 函数预编译发生在函数执行前一刻。
变量提升
根据上文所提到的,变量提升:在预编译的时候会将函数内变量声明存储到AO对象中,值为undefined
console.log(name) // 'undefined'
var name = 'John Doe'
console.log(name) // John Doe
let & const提升
console.log(a) // ReferenceError: a is not defined
let a = 3
function, var, let, const, class 都会被“提升”。但是let和const声明的变量不会被初始化值为undefined, 只有在执行阶段JavaScript引擎在遇到他们的词法绑定(赋值)时,他们才会被初始化。这意味着在JavaScript引擎在声明变量之前,无法访问该变量。
let a
console.log(a) // undefined
a = 5
class提升
同let和const一样,class在JavaScript中也是会被“提升”的,在被真正赋值之前都不会被初始化值。
let peter = new Person('John', 25) // ReferenceError: Person is not defined
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
let John = new Person('Tom', 18);
console.log(John) // Person { name: 'Tom', age: 18 }
练习题
helloWorld(); // TypeError: helloWorld is not a function
var helloWorld = function(){
console.log('Hello World!');
}
//Uncaught TypeError: helloWorld is not a function
helloWorld();
function helloWorld(){
console.log('Hello World!');
}
//Hello World!
foo();
var foo;
function foo(){
console.log('tom');
}
foo = function(){
console.log('jack');
}
//tom
面试真题
var name = 'Tom';
(function() {
if (typeof name == 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
//Goodbye Jack
变形一
var name = 'Tom';
(function(name) {
if (typeof name == 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})(name);
//Hello Tom
变形二
var name = 'Tom';
(function() {
if (typeof name == 'undefined') {
let name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
//Hello Tom
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!