• 你自认为理解了JavaScript?


    关于Dmitry Baranovskiy 的博客中一篇文章(http://dmitry.baranovskiy.com/post/91403200),其中有五段小代码,用来测试是否理解 JavaScript 的核心,闭包和作用域,  该文章也在csdn论坛上受到过关注和讨论, 集思广益,下面结合自己的理解,做了如下小结。

    1

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

    程序会首先解析所有声明的函数,其次是var声明的变量,因为javascript没有块的概念,所以if(){...}中,var声明了 a = 1, a是依然属于全局变量。

    执行等价于:

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

    (1)开始时,声明了变量a,但并没有赋值,所以a = undefined ,  而undefined 存在于window中,所以(’a’ in window)返回true,  取反为false, 这样就不会执行大括号里面的 “a=1” 的语句。

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

    2

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

    可以用一个var,来声明多个变量,中间用多个逗号分开,执行等价于:

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

    (1) 函数表达式类似于局部变量,不会被全局作用域访问到,所以这里的函数 function a 是局部变量,外部无法访问,因此全局a还是1;

    (2) console.log(a); //1

    3

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

    javascript永远是先解析声明函数,再解析变量, 执行顺序如下:
    (1) 解析函数a;
    (2) 声明变量var a; 因为a此时并没有被赋值,所以它为 undefined, 还是指向原来的值,即函数 function a;
    (3) console.log(a); // function a

    4

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

    函数内部,可以引用一个类数组的对象arguments,它并不是真正的数组,代表了函数实际接受参数的集合,可以通过下标对相应参数进行访问,
    如果修改了此对象的属性,如arguments[index],则被传进来的第index (如果有的话,下标从0开始) 变量的值也会被修改。
    执行顺序:

    (1) 声明一个函数b;
    (2) 执行函数b(1,2,3);因为这里arguments[2]与变量a引用的是同一个值,所以当arguments[2]改变时,a也随之改变。
    (3) console.log(a) // 10;

    5

    function a () {
      console.log(this); 
    }
    a.call (null);

    call 调用一个对象的一个方法,以另一个对象替换当前对象。 

    格式如 call(thisObj, arg1,arg2...argN);

    在函数体外部调用call()方法,如果传入null,则默认转成window,如果不传也是一样,即函数中的this指向window。
    console.log(this) // window;

    function a () {
        console.log (this === window);
    }
    console.log(this === window); // true
    a.call (); // true
    a.call (null); // true
    a.call (this); // true
    a.call (window); // true
    a(); // true


    function fo(){
        console.log(a); 
    }
    function foo(){
        var a = 2;
        fo();
    }
    foo();

    先执行 foo 函数, fo 虽然在foo调用,但是 fo函数是声明在全局作用域下的,所以fo中引用的a,是指向全局的window,而全局作用域下的a 并未声明,虽然在 foo 下,声明了var a=2,但它作为局部变量,无法被函数外的作用域所调用。
    console.log(a) // a is not defined;

    如果将以上代码写成:

    function foo(){
        var a = 2;
        function fo(){
            console.log(a);
        }
        fo();
    }
    foo();

    因为这时候,函数fo是声明在foo函数体内的,属于foo的内部函数,作用域链的访问顺序是由内向外的,a在fo里搜索不到,就会到上一级函数foo中 寻找,这里找到var a = 2 后返回结果。

    console.log(a) // 2;

  • 相关阅读:
    DBCA创建数据库ORA-01034 ORACLE not available
    Linux shell 内部变量
    ext4文件系统制作
    curses-键盘编码-openssl加解密【转】
    Linux 中的键盘映射【转】
    C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出【转】
    Linux下使用popen()执行shell命令【转】
    linux下获取按键响应事件【转】
    linux select函数:Linux下select函数的使用详解【转】
    OTA升级中关于update.zip包的一些总结【转】
  • 原文地址:https://www.cnblogs.com/fengfan/p/3993542.html
Copyright © 2020-2023  润新知