• 真懂JavaScript吗


    你真懂JavaScript

    http://www.cnblogs.com/elegance/p/4195593.html

    看了汤姆大叔的“你真懂JavaScript吗?”,里面有5道题目,我都一一作了,然后在chrome的控制台里面运行了一遍,虽然只错了一道,但还是细细读了下答案,在此总结一下,看看是否对大家对这些JavaScript底层的原理都懂了。

    题目一(所有全局变量都是window的属性、变量声明提前、变量赋值不会提前)

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

    因为在JavaScript在变量声明提前的特性,所以事实上上述代码相当于下面所示:

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

    因为所有的全局变量都是window的属性,所以不会进入循环体内也就不会执行a=1 这也就是为什么答案是undefined

    题目二(函数声明提前、函数表达式相当于变量赋值所以不会提前、函数声明会覆盖变量声明,但不会覆盖变量赋值)

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

    这个题目的答案是1。事实上上述代码的相当于下而的代码

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

    原题目第二行代码中,b和a同时指向一个地方也就是函数的入口,但是a和b唯一不同的地方在于函数定义结束也就是};后,a就引用不到了,也就是说a的作用域只在函数体内,而b的作用域却在整个全局范围内。看图说话

    这里面还有一个重要的概念就是:函数声明会覆盖变量声明,但不会覆盖变量赋值。看下面的例子:

    function value(){
        return 1;
    }
    var value;
    alert(typeof value);    //"function"

    尽快变量声明在下面定义,但是变量value依然是function,也就是说这种情况下,函数声明的优先级高于变量声明的优先级,但如果该变量value赋值了,那结果就完全不一样了:

    function value(){
        return 1;
    }
    var value = 1;
    alert(typeof value);    //"number"

    题目三(遇到同名的函数声明,函数变量不会重新定义)

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

    相信你看懂了题目二的注释之后,这题肯定会了,把答案贴一下。

    题目四(callee和caller及函数参数的一些关系)

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

    其实arguments跟数组类似,可以通过方括号语法访问它的每一个元素,另外arguments和命名参数可以一起使用,它们是共享的,但是这个共享其实不是真正的共享一个内存地址,而是2个不同的内存地址,使用JavaScript引擎来保证2个值是随时一样的,所以修改了arguments的值同时也会体现在命名参数上,当然这也有一个前提,那就是这个索引值要小于你传入的参数个数,也就是说如果你只传入2个参数,而还继续使用arguments[2]赋值的话,就会不一致,看如下代码:

    function b(x, y, a) {
        arguments[2] = 10;
        alert(a);
    }
    b(1, 2);//这时候因为没传递第三个参数a,所以赋值10以后,alert(a)的结果依然是undefined,而不是10,但如下代码弹出的结果依然是10,因为和a没有关系。
    function b(x, y, a) {
        arguments[2] = 10;
        alert(arguments[2]);
    }
    b(1, 2);//结果依然是10

    不过在严格模式下是不允许修改arguments的值

    题目五(this的相关概念)

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

     this说直白一点就是当前调用的对象,也就是说如果方法是某个对象的属性的话,那在该方法内的this就指向这个对象,this指向的是运行时的当前对象。如果某方法是全局函数的话,那该方法内的this就指向window

    call方法主要是用来改变作用域链的,call方法作为一个function执行代表该方法可以让另外一个对象作为调用者来调用,call方法的第一个参数是对象调用者,随后的其它参数是要传给调用method的参数(如果声明了的话),根据ECMAScript262规范规定:如果第一个参数传入的对象调用者是null或者undefined的话,call方法将把全局对象(也就是window)作为this的值。所以,不管你什么时候传入null,其this都是全局对象window。

    所以这题目的答案是[object Window]

     
    分类: JavaScript
  • 相关阅读:
    机器学习系列-tensorflow-01-急切执行API
    Python3基础-代码阅读系列—优惠码生成
    英语口语练习系列-C01-好棒
    Python3基础系列——枚举类型大揭秘
    Python3字符串-最容易理解的方式
    英语词性系列-B02-动词
    专业方向系列-02-基于深度学习的诊断方法
    英语词性系列-B01-名词
    英语进阶系列-A06-本周总结
    Python数据可视化系列-02-pyecharts可视化非常cool
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4196686.html
Copyright © 2020-2023  润新知