• 你自认为理解了JavaScript?


    一. 题目

    英文原文地址:http://dmitry.baranovskiy.com/post/91403200

    其中有五段小代码,用来测试是否理解 JavaScript 的核心(core),闭包(closures)和作用域(scopes)。先尝试回答每段代码中alert语句的结果,然后再作实践检查。

    if (!("a" in window)) {
        var a = 1;
    }
    alert(a);

    第一题解析

    var a = 1,
        b = function a(x) {
            x && a(--x);
        };
    alert(a);

    第二题解析

    function a(x) {
        return x * 2;
    }
    var a;
    alert(a);

    第三题解析

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

    第四题解析

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

    第五题解析

    二. 解析

    解析参考:http://bbs.csdn.net/topics/390300541 

    第一题解析:

    首先会解析所有函数,其次是var声明的变量,但是不会赋值。因为JavaScript没有块(block)的概念。像for(var i in array)这里的i依然是全局变量,这点非常的不同于Java。因此,这几行的代码执行顺序是:

    1. var a; // 声明一个变量,但是不会赋值!
    2. if...语句:因为步骤1已经定义了a变量(没赋值),所以"a" in window为真,取反为假。所以不会执行大括号里面的赋值语句。
    3. alert(a); // 显然,结果为undefined


    第二题解析:
    我们可以用多个逗号将变量分开定义,只用一个var。另外函数表达式类似于局部变量,不会被全局作用域中访问到。执行步骤:

    1. 声明两个局部变量(因为有var限定符)a,b;并给他们赋值a=1,b=function a(){...};这里的function a是局部变量,外部无法访问到。
    2. alert(a); // 结果为1


    第三题解析:

    JavaScript永远是先解析声明式函数,再解析变量。所以,它的执行顺序为:

    1. 解析函数a;
    2. 声明变量var a;因为a此时没有被赋值,所以它还是指向原来的值。即function a;
    3. alert(a); // 那就是function a(x){...}


    第四题解析:

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

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

    注意1:形参优先级高于arguments

    function fn(arguments){
        alert(arguments);
    }
    fn('hello'); // -> "hello"

    注意2:在JavaScript中如果定义了2个或2个以上的相同名字的函数,则只有最后定义的函数才有效。

    function b(x, y, a) {
        arguments[2] = 10;
        alert(x);
    }
    function b(x, y, a, b) {
        arguments[2] = 10;
        alert(y);
    }
    b(1, 2, 3); // -> 2


    第五题解析:

    call方法接受多个参数,其作用是借用别人的方法当作自己的方法。这样能保证执行的时候this能够指向自己。

    call方法的第二个参数到最后一个参数是传给借用过来函数的。第一个参数是借用的对象,如果这个对象为空,那么将会作为全局window对象调用。即函数中的this指向window,结果为[object Window]。

    经验:a()/a.call()/a.call(null)无区别。

  • 相关阅读:
    vmwear 及docker
    vue相关
    vue demo
    线程的死锁
    让出和守护线程
    join加入线程
    线程的优先级
    线程间的通信
    synchronized关键字的使用
    线程的并发
  • 原文地址:https://www.cnblogs.com/nayitian/p/3332730.html
Copyright © 2020-2023  润新知