码迷,mamicode.com
首页 > 其他好文 > 详细

变量提升,函数提升概念及相关题

时间:2018-12-17 21:07:58      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:预编译   测试   外部   定义   名称   表达式   匿名函数   def   define   

之前总是对变量提升,函数提升一知半解,随着时间的推移,理解的越来越深刻,接下来就写一写,有不对的地方请大家指出来。

1) 变量提升

1. 通过var定义(声明)的变量, 在定义语句之前就可以访问到
2. 值: undefined

console.log(a)//undefined
var a = 1111;
console.log(a)//1111

等同于

var a = undefined
console.log(a) //undefined
a = 1111;
console.log(a) //1111

即:变量提升。你在一个作用域任何一个地方声明变量,都会被提升到作用域开始

2) 函数提升

1. 通过function声明的函数, 在之前就可以直接调用
2. 值: 函数定义(对象)

例子:

(1)var和函数

<script>
     console.log(a)//function a(){}         
     var a=1;
     console.log(a)//1
     function a(){
   } console.log(a)
//1 </script>

等同于以下代码:             

其过程:变量a先声明,给a赋值为undefined,后来预编译函数function a(){}再声明;输出a为function a(){} ; 之后给a赋值为1;输出a为1 

<script>
     var a;
     a = function a(){}
     console.log(a)//function a(){}
     a=1;
     console.log(a)//1
     console.log(a)//1
</script>

(2)var和函数参数

<script>
    var a=8;
    function fn(a,b){ 
        console.log(a)//undefined    当前函数作用域能够找到a,其值是undefined。 所以不会向外查找
        var a=10;
        console.log(a)//10
    }
    fn();
</script>

 

<script>
    function fn(a,b){
        console.log(a)//hello
        var a=10;
        console.log(a)//10
    }
    fn(‘hello‘);
</script>

调用fn的时候传入参数a,b。 a和b会预编译赋值undefined,调用fn,传入"hello", a就被赋值为hello。

函数里面变量a的默认值就是参数a的值了,输出a即参数a值。给a赋值为10,输出a为10。

<script>
    var a=1;
    function fn(a,b){
        console.log(a)//undefined  当前作用域能够找到a的
        a=2;
        console.log(a)//2
    }
    fn();
</script>

 

foo();
    function foo(){
        console.log("aaa");
    }

 

function foo(){
        console.log("aaa");
    }

    foo();

 

foo();
    var foo = function(){
        console.log("aaa");
    }

 

报错运行结果是: foo is not a function

原因是:js解析遇到 foo()时会默认当做函数来解析 

 

var foo;
console.log(foo);  //undefined
foo(); //foo is not a function
 foo = function(){
        console.log("aaa");
    }

 

如果函数声明和变量声明使用同一变量名称,函数声明的优先级高于变量

 

函数,函数参数,var

<script>
    var a=10;
    function fn(a,b){
        console.log(a)//function a(){}   这里输出function a(){}, 不是参数a的值
        var a=10;
        console.log(a)//10
        function a(){}
        console.log(a)//10
    }
    fn(15);
</script>

fn里面有参数a,也有变量a,也有函数a,这种迷惑性更高。其实当你知道三者先后顺序之后就不迷惑了

经过测试,我发现:参数a会覆盖预编译变量a的默认值,如果有函数,函数会覆盖参数a的值,就是先后顺序而已。

函数形参声明--->函数声明---->变量声明  

<script>
    a();//1
    var a = c = function() {
        console.log(2)
    };
    a();//2

    function a() {
        console.log(1)
    }
    a();//2
    (function(b) {
        b();//2    其实就是外部的a
        c();//2     c为什么是2? 也许有人以为这里会报错,其实不会。 原因就在于var b=c=xxx。  c相当于没有加var 不会预编译,这里c直接查找到外部作用域的c
        var b = c = function a() {
            console.log(3)
        }
        b()//3
    })(a);//走到这里 a已经被赋值表达式重新赋值
    c();//3 由于没加var 的原因 c已经被立即执行函数内部的赋值表达式改变了值 这里是3
</script>

 

console.log(typeof foo); 
console.log(typeof bar); 
console.log(typeof add); //函数的声明 
function foo(){ alert(‘foo‘); } //命名函数表达式 
var bar = function(){ alert(‘bar‘); }; // 函数表达式-匿名函数 
var add = function(a,b){ return a+b; }

输出结果为 function  undefined  undefined

 

console.log(b);
console.log(b());
var b=1;
function b(){
    return 2;
}

输出结果为 

function b(){
    return 2;
}

 2

 

console.log(a)  // f a() { console.log(a) }
console.log(b) //undefined
function a() {
        console.log(a) 
}
var b = function(){
        console.log(b)
}

 

变量提升,函数提升概念及相关题

标签:预编译   测试   外部   定义   名称   表达式   匿名函数   def   define   

原文地址:https://www.cnblogs.com/renzm0318/p/8966018.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!