zoukankan      html  css  js  c++  java
  • js中的执行上下文,菜鸟入门基础。

    console.log(a); //Uncaught ReferenceError: a is not defined

    因为没有定义a所以报错了。

    var a = 52;
    console.log(a); //52

    有定义a,并且给a赋值了52所以打印a就是52。

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

    虽然有定义a但是打印却在变量a的前面,那为什么不是报错而是打印出来的是undefined?因为在js执行代码之前,js会先获取到所有的变量并且把这些变量放置到js代码的顶部。(简称变量声明提前)

    实际上,上面的代码是这样执行的:

    var a;
    console.log(a);

    所以代码出来的就是undefined,那你是不是会疑问?我们给赋值给a的52到哪去了。虽然我前面说了js会事先获取所有的变量并且将这些变量放置到顶部,但是变量的赋值并不会事先执行,也就是说,你在哪声明的变量,这个变量的赋值就在哪执行。

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

    虽然声明了但没有赋值所有undefined

    console.log(a); 
    function a(){
      this.user = "追梦子";
    }

    为什么,可以事先就打印出函数a呢?因为函数的赋值在函数声明的时候就已经赋值了,结合上面我说的变量提前,那是不是就可以理解这句话了?

    当然这只是一种情况,还有一种情况,稍后说。

    function a(){
      this.user = "追梦子";
    }
    console.log(a);

    正常

    a(); //Uncaught TypeError: a is not a function
    var a = function(){
      console.log(52);
    }

    为什么现在又不行了?因为现在的函数已经赋值给了变量a,现在它的执行过程和变量一样了,我们通常把这种函数赋值给变量的形式叫做函数表达式。

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

    正常

    if(false){
        var a = 1;
    }
    console.log(a); //undefined

    之所以没有报错而是输出了undefined是因为变量存在预解析的情况,又因为js没有块级作用域,所以最后代码就成了这样

    var a;
    if(false){
        a = 1;
    }
    console.log(a);

    总结:

      函数分为:函数声明和函数表达式。

      函数声明--

    function a(){
        alert("追梦子博客");
    }

      函数表达式--

    var a = function(){
        alert("追梦子");
    }

      看似两段相同的语句,它们的执行顺序却截然不同,函数声明时的赋值行为是在函数创建的时候进行的,而函数表达式的赋值行为是在执行这句变量时进行的(因为它已经赋值给了变量所以我这里把它称为变量)。

      不管是变量还是函数都会存在变量声明提前。

    来看看几题有意思的js例题,加以理解。

      

    var a = 1;
    function b(){
        console.log(a); //undefined
        var a = 5;
    }
    b();

    为什么打印的是undefined?

      我们先来看看它的解析过程:

    var a = 1;
    function b(){
        var a
        console.log(a); //undefined
        a = 5;
    }
    b();

      变量提前了,那为什么不打印全局变量1呢?如果你有这个问题我猜你应该是JavaScript的新朋友,那我建议你看我的上一篇文章:

    什么是作用域链,什么是原型链,它们的区别,在js中它们具体指什么?

      在看完作用域链以后我相信你能够看懂这个例子。

    我们一起来看看另外一题比较有难度的js面试题:

      

    var a = 1;      
    function b() {      
        a = 120;      
        return;      
        function a() {}
    }      
    b();      
    alert(a); //1;

      如果你看了上面一题我相信你应该有种不知所措的感觉,这里现在为什么又是1了呢?

    我把执行过程的代码写出来我相信你就懂了。

      

    var a = 1;      
    function b() {
        var a;      
        a = 120;      
        return;      
        function a() {}
    }      
    b();      
    alert(a); 

      如果你正在js的进阶阶段肯定更闷了,你肯定会想我们不是写return了吗?return后面的代码不是不执行吗?为什么这里却影响了这段代码?

      虽然return后面的代码不会被执行,但是在js预解析的时候(变量提升的时候)还是会把return后面的变量提前,所以我们这段代码因为变量提前所以函数里面的变量a就成了局部变量,因为函数外部是访问不了函数内部的变量所以就输出了1。

      另外提两点,函数的arguments和函数名都是直接赋值的,也就是在这个函数解析的时候就会进行赋值。

      如果你还是不理解建议多看几遍,另外如果你是js的新朋友一定要看什么是作用域链,什么是原型链,它们的区别,在js中它们具体指什么?这篇文章。

  • 相关阅读:
    ASP的URL重写技术 IIS的ISAPI
    关于如何去勾引百度谷歌的蜘蛛爬虫
    如何让百度和google的蜘蛛爬虫迅速爬过来
    本机不安装Oracle客户端,使用PL/SQL Developer和 Instant Client 工具包连接oracle 11g远程数据库
    Java小知识点总结
    Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量)
    OracleDBconsoleorcl无法启动解决方案
    Java中PreparedStatement的错误使用
    Oracle 中行列转换问题总结
    Java中 Interger 的自动装箱
  • 原文地址:https://www.cnblogs.com/pssp/p/5205764.html
Copyright © 2011-2022 走看看