首页 > 技术文章 > js变量提升函数提升

bibiafa 2018-07-27 14:39 原文

概念:

  1.js的变量和函数在编译阶段会被提升到当前作用域最前面编译

  2.函数是一等公民,优先编译函数

  3.js是按照script块编译的

console.log(a);//undefined
console.log(b);//error
var a = 10;

根据变量的提升原则,var a会被优先提升到最前面编译,但赋值是在运行的时候完成的。实际上的代码是

var a;
console.log(a);
console.log(b);
a = 10;

由于b没有声明就直接输出了,当前作用域中是没有变量b的记录的,所以报错

 

console.log(a);//function a(){}
var a = 10;
function a(){

}
console.log(a);//10

变量的声明虽然在函数声明之前,但是函数优先被编译,实际代码是

function a(){

}
console.log(a);
a = 10;
console.log(a);

这里的实际代码中是a = 10而不是var a = 10;因为函数声明不仅优先被编译了,还覆盖掉剩余的同名变量的声明。

 

<script>
    //这句话报错,必须注释掉
    // console.log(b);
    var a = "a";
</script>

<script>
    var b = "b";
    console.log(a);//"a"
</script>

js以script块为单位进行编译运行。

第一个块中没有变量b的声明,所以报错。

第二个块中成功输出变量a。也就是说,虽然以script块为单位,但是块之间并不是独立的,它们的编译执行结果都会被当前作用域保存,上面的两块script块都是在全局作用域环境下编译运行的。

 

几个测试js核心概念的小案例:

1.

if (!("a" in window)) {
    var a = 1;
}
console.log (a);

  结果:undefined

2.

var a = 1,
    b = function a (x) {
        x && a (--x);
    };
console.log(a);

结果:1

var b = function a(){...}是具名函数表达式赋值,函数名a只能在函数体使用,一般用于递归调用

3.

function a (x) {
    return x * 2;
}
var a;
console.log(a);

结果:function a

4.

function b (x, y, a) {
    arguments[2] = 10;
    console.log(a);
}
b(1, 2, 3);

结果:10

arguments对像保存实参值,x,y,a是形参名。实参值的改变会影响形参值

5.

function a () {
    alert (this);
}
a.call (null);

结果:window

显式绑定this,绑定对象是null时,则采用默认绑定。

 

推荐阅读