1
2
3
4
5
6
7
8
9
function t(a) {
console.log(a);
var a = 1 //var本质也是按照下面的预编译过程来进行编译,但重复var声明不会报错
console.log(a);
// function a() {}
}
t(2)
// 2,1
// Function a 1(解开注释)

函数预编译,顺序为

  1. let a
  2. 将形参赋值给 a
  3. 将函数声明赋值给 a

1
2
3
4
5
6
7
8
var a = 3;
function c(){
console.log(a);
}
(function(){
var a = 4;
c();
})();

js 中变量的作用域链与定义时的环境有关,与执行时无关。执行环境只会改变 this、传递的参数、全局变量等

1
2
3
4
5
6
7
8
9
10
11
function fun(n, o) {
console.log(o)
return {
fun: function(m){
return fun(m, n);
}
};
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//undefined 0 0 0
var b = fun(0).fun(1).fun(2).fun(3);//undefined 0 1 2
var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined 0 1 1

涉及闭包和作用域
fun 返回一个对象
a 不断调用 a 上的 fun 方法,该方法为 fun 函数,有点递归的意思,但由于每次都只传入第一次运行时闭包的 n(0),所以每次输出 0
b 每次返回一个新对象来链式调用,新对象的 n 默认为上一个对象调用方法时传入的参数 m
c 调用两次函数,返回两次对象,后两次为调用方法,所以对象上形参 n 一直是 1

1
2
3
4
5
6
7
8
9
10
11
f = function() {return true;};   
g = function() {return false;};
(function() {
if (g() && [] == ![]) {
f = function f() {return false;};
// function g() {return true;}
}
function g() {return true;}
})();
console.log(f());
// false

考察预编译
一次执行函数中的 g () 会预编译,所以此时 if 为真,执行语句,此时 f 被重新赋值,所以输出 false
注意如果 g 函数写在 if 中,g 还是会预编译,在一次执行函数的作用域执行 var g,但值为 undefined,不会运行预编译第二步将函数声明提升,此时在 if 判断时执行 g () 时会报错 g is not a function

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

EvilMoOd 微信支付

微信支付

EvilMoOd 支付宝

支付宝