zoukankan      html  css  js  c++  java
  • js几个经典的题目详解

    一、作用域、运算符(逗号运算、赋值运算)

     1 var out = 25,
     2    inner = {
     3         out: 20,
     4         func: function () {
     5             var out = 30;
     6             return this.out;
     7         }
     8     };
     9 console.log((inner.func, inner.func)());
    10 console.log(inner.func());
    11 console.log((inner.func)());
    12 console.log((inner.func = inner.func)());
     1 25,20,20,25
     2 
     3 代码解析:这道题的考点分两个 
     4 1.作用域
     5 2.运算符(赋值预算,逗号运算)
     6 
     7 先看第一个输出:25,因为(inner.func, inner.func)是进行逗号运算符,逗号运算符就是 运算前面的,
     8 返回最后一个,举个栗子
     9 
    10 var i=0,j=1,k=2;
    11 console.log((i++,j++,k))//返回的是k的值 2 ,如果写成k++的话  这里返回的就是 3
    12 console.log(i);//1
    13 console.log(j);//2
    14 console.log(k);//2   
    15 
    16 回到原题(inner.func, inner.func)就是返回inner.func而inner.func只是一个匿名函数 
    17 function () {
    18     var out = 30;
    19     return this.out;
    20 }
    21 而且这个匿名函数是属于window的
    22 则变成了
    23 (function () {
    24     var out = 30;
    25     return this.out;
    26 })()
    27 此刻的this--》window
    28 
    29 所以out 是25
    30 
    31 第二和第三个console.log的作用域都是 foo,也就是他们执行的其实是
    32 foo.func();
    33 foo作用域中是有out变量的,所以结果是20
    34 
    35 第四个console.log
    36 考查的是一个等号运算inner.func = inner.func 其实返回的是运算的结果,
    37 举个栗子
    38 var a=2,b=3;
    39 console.log(a=b)//输出的是3
    40 所以inner.func = inner.func 返回的也是一个匿名函数
    41 function () {
    42     var out = 30;
    43     return this.out;
    44 }
    45 
    46 此刻 道理就和第一个console.log一样了 输出的结果是 25

    二、变量声明提前

    1 if (!("a" in window)) {
    2     var a = 1;
    3 }
    4 alert(a);
     1 代码解析:如果window不包含属性a,就声明一个变量a,然后赋值为1。
     2 
     3 你可能认为alert出来的结果是1,然后实际结果是“undefined”。要了解为什么,
     4 需要知道JavaScript里的3个概念。
     5 
     6 首先,所有的全局变量都是window的属性,语句 var a = 1;等价于window.a = 1;
     7 
     8 你可以用如下方式来检测全局变量是否声明:"变量名称" in window
     9 第二,所有的变量声明都在范围作用域的顶部,看一下相似的例子:   
    10 
    11 alert("b" in window);
    12 var b;
    13 
    14 此时,尽管声明是在alert之后,alert弹出的依然是true,这是因为JavaScript引擎
    15 首先会扫墓所有的变量声明,然后将这些变量声明移动到顶部,最终的代码效果是这样的:
    16 
    17 var a;
    18 alert("a" in window);
    19 这样看起来就很容易解释为什么alert结果是true了。
    20 
    21 第三,你需要理解该题目的意思是,变量声明被提前了,
    22 但变量赋值没有,因为这行代码包括了变量声明和变量赋值。
    23 
    24 你可以将语句拆分为如下代码:
    25 
    26 var a;    //声明
    27 a = 1;    //初始化赋值
    28 当变量声明和赋值在一起用的时候,JavaScript引擎会自动将它分为两部以便将变量声明提前,
    29 不将赋值的步骤提前是因为他有可能影响    代码执行出不可预期的结果。
    30 
    31 所以,知道了这些概念以后,重新回头看一下题目的代码,其实就等价于:
    32 
    33 var a;
    34 if (!("a" in window)) {
    35     a = 1;
    36 }
    37 alert(a);
    38 这样,题目的意思就非常清楚了:首先声明a,然后判断a是否在存在,如果不存在就赋值为1,
    39 很明显a永远在window里存在,这个赋值语    句永远不会执行,所以结果是undefined。
    40 
    41 提前这个词语显得有点迷惑了,你可以理解为:预编译。

    三、函数声明与函数表达式

    1    var a = 1;
    2 
    3    var b = function a(x) {
    4             x && a(--x);
    5         };
    6  
    7    alert(a);
     1 这个题目看起来比实际复杂,alert的结果是1;这里依然有3个重要的概念需要我们知道。
     2 
     3 首先,在题目1里我们知道了变量声明在进入执行上下文就完成了;第二个概念就是函数声明也是提前的,
     4 所有的函数声明都在执行代码之前都已经完成了声明,和变
     5 
     6 量声明一样。澄清一下,函数声明是如下这样的代码:
     7 
     8 function functionName(arg1, arg2){
     9     //函数体
    10 }
    11 如下不是函数,而是函数表达式,相当于变量赋值:
    12 
    13 var functionName = function(arg1, arg2){
    14        //函数体
    15    };
    16 澄清一下,函数表达式没有提前,就相当于平时的变量赋值。
    17 
    18 第三需要知道的是,函数声明会覆盖变量声明,但不会覆盖变量赋值,为了解释这个,我们来看一个例子:
    19 
    20 function value(){
    21     return 1;
    22 }
    23 var value;
    24 alert(typeof value);    //"function"
    25 尽快变量声明在下面定义,但是变量value依然是function,也就是说这种情况下,
    26 函数声明的优先级高于变量声明的优先级,但如果该    变量value赋值了,那结果就完全不一样了:
    27 
    28 function value(){
    29     return 1;
    30 }
    31 var value = 1;
    32 alert(typeof value);    //"number"
    33 该value赋值以后,变量赋值初始化就覆盖了函数声明。
    34 
    35 重新回到题目,这个函数其实是一个有名函数表达式,函数表达式不像函数声明一样可以覆盖变量声明,
    36 但你可以注意到,变量b是包含了该函数表达式,而该函数表达式的名字是a;不同的浏览器对a这个名
    37 词处理有点不一样,在IE里,会将a认为函数声明,所以它被变量初始    化覆盖了,就是说如果调用a(–x)的
    38 话就会出错,而其它浏览器在允许在函数内部调用a(–x),因为这时候a在函数外面依然是数字。
    39 基本上,IE里调用b(2)的时候会出错,但其它浏览器则返回undefined。
    40 
    41 理解上述内容之后,该题目换成一个更准确和更容易理解的代码应该像这样:
    42 
    43 var a = 1,
    44     b = function(x) {
    45     x && b(--x);
    46     };
    47 alert(a);
    48 这样的话,就很清晰地知道为什么alert的总是1了。

    四、函数声明与变量声明

    1 function a(x) {
    2     return x * 2;
    3 }
    4 var a;
    5 alert(a);
    这个题目比较简单:即函数声明和变量声明的关系和影响,遇到同名的函数声明,不会重新定义

    五、arguments

    1 function b(x, y, a) {
    2         arguments[2] = 10;
    3         alert(a);
    4     }
    5     b(1, 2, 3);
    1 关于这个题目,ECMAsCRIPT 262-3的规范有解释的。
    2 
    3 活动对象是在进入函数上下文时刻被创建的,它通过函数的arguments属性初始化。
    4 arguments属性的值是Arguments对象.
    5 关于 Arguments对象的具体定义,看这里:ECMAScript arguments 对象

    六、call

    1 function a() {
    2         alert(this);
    3     }
    4     a.call(null);
     1 这个题目可以说是最简单的,也是最诡异的!关于这个题目,我们先来了解2个概念。
     2 
     3 这个问题主要考察 Javascript 的 this 关键字,具体看这里:
     4 
     5 关于Javascript语言中this关键字的用法
     6 
     7 关于 a.call(null);  根据ECMAScript262规范规定:如果第一个参数传入的对象调用者是null
     8 或者undefined的话,call方法将把全局对象(也就是window)作为this的值。所以,
     9 不管你什么时候传入null,其this都是全局对象window,所以该题目可以理解成如下代码:
    10 function a() {
    11     alert(this);
    12 }
    13 a.call(window);
    14 所以弹出的结果是[object Window]就很容易理解了。
  • 相关阅读:
    Linux 下没有 my.cnf 文件的解决方式,完全是我自己整的,好多教程都是瞎扯的 (zhuan)
    Virtualbox虚拟机安装CentOS6.5图文详细教程(zhuan)
    virtualbox中centos系统配置nat+host only上网(zhuan)
    VirtualBox的网络配置,Host Only+NAT方式 (zhuan)
    Linux上安装Mysql后除了本机其他机器不能访问的问题(zhuan)
    VirtualBox没有64位选项,无法安装64位的解决方法(zhuan)
    CentOS查看内核版本,位数,版本号 (zhuan)
    datagrid实现单行的选择、取消
    datagrid实现行的上移和下移
    Excel 、数据库 一言不合就转换 (zhuan)
  • 原文地址:https://www.cnblogs.com/Nightsky-Dec/p/6511307.html
Copyright © 2011-2022 走看看