这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战
预编译
简单理解记忆
- 函数声明整体提升 系统会把函数提升到逻辑的最前面
- 变量 声明提升
这两句话不能解决的问题
console.log(a);
function a(a) {
var a = 234;
var a = function () {
}
a();
}
var a = 123;
未经声明的变量归window所有
- imply global暗示全局变量:即任何变量,如果
变量未经声明就赋值,此变量就为全局对象所有。
eg:a= 123;eg: var a=b= 123; - 一切声明的全局变量,全是window的属性。window就是全局的域
eg:var a = 123; ===> window.a = 123;
预编译过程 发生在函数执行的前一刻
- 创建AO对象:执行期上下文
- 找形参和变量声明,将变量和形参名作为AO 属性名,值为undefined
- 将实参值和形参统一
- 在函数体里面找函数声明,值赋予函数体
例子1:
function fn(a) {
console.log(a);//function a() {}
var a = 123;
console.log(a) ;//123
function a () {}
console.log(a);//123
var b = function () {}
console.log(b);//function () {}
function d() {}
Fn(1);
预编译过程:AO{
a:function a () {}
b:undefined,
d:function d() {}
}
例子2
function test(a, b) {
console.log(a) ;//1
C=0;
var C;
a=3;
b=2;
console.log(b) ;//2
function b () {}
I
function d ( )
{}
console.log(b) ;//2
test(1);
例子3
function test(a, b) {
console.log(a) ;//function a () {}
console.log(b);//undefined
var b = 234;
console.log(b);//234
a = 123;
console.log(a);//123
function a () {}
var a;
b = 234;
var b = function ( ){}
console.log(a);//123
console.log(b) ;|//function () {}
}
test(1);
AO {
a:function
b:1
}
有全局的执行期上下文的时候
console.log(test);//function text () { }
function test(test) {
console.log(test) ;//function text () { }
var test = 234;
console.log(test);//234
function test( ){
}
}
test(1) ;
var test = 123;
过程 :
在全局的执行期上下文:
GO {
text :function text () { }
}
函数执行的执行上下文
AO {
}
复杂的面试题例子:
function test() {
console.log(b);//undefined
if (a) {
var b = 100;
}
console.log(b)//undefined
c = 234;
console.log(c);//234
}
var a;
test();
// AO{
// b: undefined
// }
a = 10;
console.log (b);//Uncaught ReferenceError: b is not defined
console.log(c);//234
立即执行函数
上面的普通函数会产生变量提升,如果要顶一个一个函数定义的变量不会污染全局变量该怎么做呢,这个时候我们就可以用理解狮执行函数了
定义:此类函数没有声明,在一次执行过后即释放。适合做初始化工作。
作用:造出一个函数作用域,防止污染全局变量,它既不会提升,也不会污染全局对象,尽量的把功能封装在函数中
首先得知道,
- 只有表达式才能被执行符号执行
- 被执行符号执行的表达式他的名字会被自动忽略
当函数成为一个表达式时,它既不会提升,也不会污染全局对象。将函数变为一个函数表达式的方式之一,将函数用小括号括起来。
然而,这样一来,函数无法通过名称调用。如果书写一个函数表达式,然后将立即调用,该函数称之为立即执行函数 IIFE(Imdiately Invoked Function Expression)。
由于大部分情况下,函数表达式的函数名没有实际意义,因此,可以省略函数名。没有名字的函数,称之为匿名函数
//w3c建议写法:
(function () {
var a = 1,
b = 2,
c = 3;
console.log(a, b, c);
}());
//2.
(function (){
var a = 1,
b = 2,
c = 3;
console.log(a, b, c);
})();
上面说到了只有表达式才能被执行符号执行负责就会报错,但是有这个特殊情况
function test(a, b, c,d) {
console.log(a + b + C + d) ;
}(1,2,3,4);
这里他不会报错,但也不会执行…他会分开执行
function test(a, b, c,d) {
console.log(a + b + C + d) ;
}
(1,2,3,4);