zoukankan      html  css  js  c++  java
  • 你自认为理解了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;

  • 相关阅读:
    EXTJS 4.2 资料 控件之checkboxgroup的用法(静态数据)
    EXTJS 4.2 资料 控件之Window窗体相关属性的用法
    EXTJS 4.2 资料 控件之textfield文本框加事件的用法
    Entity Framework 学习笔记(一)之数据模型 数据库
    EXTJS 4.2 资料 控件之checkboxgroup的用法(动态数据)
    EXTJS 4.2 资料 控件之Grid 列鼠标悬停提示
    Entity Framework 学习笔记(二)之数据模型 Model 使用过程
    EXTJS 4.2 资料 控件之radiogroup 的用法
    EXTJS API
    vue移动端弹框组件,vue-layer-mobile
  • 原文地址:https://www.cnblogs.com/fengfan/p/3993542.html
Copyright © 2011-2022 走看看