美文网首页面试Web 前端开发 程序员
尝试解析js面试题(二)

尝试解析js面试题(二)

作者: 小pxu | 来源:发表于2016-05-24 23:25 被阅读766次

    说明:一共有13题(原本14题,最后一道什么鬼,嫌弃不要了),覆盖面比较广,都属于比较烧脑的类型,各种神坑;不过对于夯实js理论基础帮助非常大;看看都能做对几题吧(🙈😏)

    //第1题
    (function () {  
        return typeof arguments;  
    })();  
    A. "object"
    B. "array"
    C. "arguments"
    D. "undefined"
    
    //第2题
    var f = function g() {
        return 23;
    };
    typeof g();
    A. "number"
    B. "undefined"
    C. "function"
    D. Eorror
    
    //第3题
    (function (x) {
        delete x;
        return x;
    })(1);
    A. 1
    B. null
    C. undefined
    D. Error
    
    //第4题
    var y = 1,
    x = y = typeof x;
    x;
    A. 1
    B. "number"
    C. undefined
    D. "undefined"
    
    //第5题
    (function f(f) {
        return typeof f();
    })(function () {
        return 1;
    });
    A. "number"
    B. "undefined"
    C. "function"
    D. Error
    
    //第6题
    var foo = {
    bar: function () {
        return this.baz;
    },
        baz: 1
    };
    (function () {
        return typeof arguments[0]();
    })(foo.bar);
    A. "undefined"
    B. "object"
    C. "number"
    D. "function"
    
    //第7题
    var foo = {
    bar: function () {
        return this.baz;
    },
        baz: 1
    };
    typeof (f = foo.bar)();
    A. "undefined"
    B. "object"
    C. "number"
    D. "function"
    
    //第8题
    var f = (function f() {
    return "1";
    }, function g() {
        return 2;
    })();
    typeof f;
    A. "string"
    B. "number"
    C. "function"
    D. "undefined"
    
    //第9题
    var x = 1;
    if (function f() {}) {
        x += typeof f;
    }
    x;
    A. 1
    B. "1function"
    C. "1undefined"
    D. NaN
    
    //第10题
    var x = [typeof x, typeof y][1];
    typeof typeof x;
    A. "number"
    B. "string"
    C. "undefined"
    D. "object"
    
    //第11题
    (function (foo) {
        return typeof foo.bar;
    })({
        foo: {
            bar: 1
        }
    });
    A、“undefined” 
    B、“object” 
    C、“number” 
    D、Error
    
    //第12题
    (function f() {
        function f() {
            return 1;
        }
        return f();
        function f() {
            return 2;
        }
    })();
    A、1 
    B、2 
    C、Error (e.g. “Too much recursion”) 
    D、undefined
    
    //第13题
    function f() {
        return f;
    }
    new f() instanceof f;
    A、true 
    B、false
    
    //第14题
    with (function(x, undefined){}) length;
    A、1 
    B、2 
    C、undefined 
    D、Error
    

    解析

    ps1:这套题在知乎上也有相关的解析可以参考如何理解这14道JavaScript 题--知乎

    //第1题  答案A
    (function () {  
        return typeof arguments;  
    })();  
    A. "object"
    B. "array"
    C. "arguments"
    D. "undefined"
    

    arguments是函数免费赠送的一个关键字,功能类似数组,但实际上是一个对象,因此这题答案是A

    //举个arguments的例子
    function foo(x) {
        alert(x); // 10
        for (var i=0; i<arguments.length; i++) {
            alert(arguments[i]); // 10, 20, 30
        }
    }
    foo(10, 20, 30);
    

    //第2题  答案D
    var f = function g() {
        return 23;
    };
    typeof g();
    A. "number"
    B. "undefined"
    C. "function"
    D. Eorror
    

    1)函数定义有两种方式,一种是普通函数直接声明function a () {return b;};(这种在解析时会被优先处理)

    2)另外一种就是匿名函数 var a = function () {returnb;};,这种也被称为表达式类型,因为右边部分已经成为一个表达式的一部分,无法再被正常访问

    3)题目中的情况按照第二种方法理解,作为表达式的g函数已经无法被访问

    4)注意,题目是typeof g(),不是typeof g;这两者的区别在于函数调用"()"的运算优先级高于typeof,所以先解析g()的情况下,js直接报错,而不是给出"undefiend";因此答案是D

    //调试比对结果
    //typeof a是function这个没有问题
    //typeof fn1是得到undefined
    //typeof fn1()是错误报警形式出现
    var a = function fn1 (){}
    typeof a  //"function"
    typeof fn1()  //Uncaught ReferenceError: fn1 is not defined(…)
    typeof fn1  //"undefined"
    

    //第3题  答案A
    (function (x) {
        delete x;
        return x;
    })(1);
    A. 1
    B. null
    C. undefined
    D. Error
    

    1)delete是用来删除对象的属性的,它不能够删除函数中传递的参数

    2)所以这里delete x这句其实并没有什么软用,函数正常执行传参及返回参数;因此答案是A

    //给个delete使用方法的举例
    var xiaoming = {
        name: '小明'
    };
    xiaoming.age; // undefined
    xiaoming.age = 18; // 新增一个age属性
    xiaoming.age; // 18
    delete xiaoming.age; // 删除age属性
    xiaoming.age; // undefined
    delete xiaoming['name']; // 删除name属性
    xiaoming.name; // undefined
    delete xiaoming.school; // 删除一个不存在的school属性也不会报错
    

    //第4题  答案D
    var y = 1,
    x = y = typeof x;
    x;
    A. 1
    B. "number"
    C. undefined
    D. "undefined"
    

    1)赋值运算符由右向左运算

    2)首先typeof x因为x未声明,因此结果是"undifined"(注意:typeof的结果都是以字符串形式给出的)

    3)接着"undifined"被接连赋值给y与x,所以答案是D


    //第5题  答案A
    (function f(f) {
        return typeof f();
    })(function () {
        return 1;
    });
    A. "number"
    B. "undefined"
    C. "function"
    D. Error
    

    1)这道题可以拆分一下,首先是函数本体

    //此处是一个函数,传入了一个叫f的参数,这个参数还是另外一个函数
    //随后在本体函数内部,将这个参数所代表的函数执行了一下,并返回其typeof结果
    (function f(f) {
        return typeof f();  //这里的f是指参数函数
    })();
    

    2)其次是参数

    function () {
        return 1;
    }
    

    3)所以现在就很清晰了,按照运算符优先级,首先参数函数执行f()结果为1;typeof 1结果为"number";所以结果是A


    //第6题  答案A
    var foo = {
        bar: function () {
            return this.baz;
        },
        baz: 1
    };
    (function () {
        return typeof arguments[0]();
    })(foo.bar);
    A. "undefined"
    B. "object"
    C. "number"
    D. "function"
    

    1)先说下我的理解,这题考的是this的指向问题

    2)this指向的四种情况,其中只有作为方法调用或者apply/call强行指向的情况下才可能指向原函数

    3)在作为普通函数调用的时候是指向window的,所以这里的argument[0]()的调用形式我认为是这种调用

    4)也就是说this.baz就是window.baz,当然是"undefined",所以答案是A

    this对我来说还是比较绕的一个东西,就再贴上别人的解析看看吧

    这个分析总的结果就是foo.bar中的this指向的是arguments(此处懵逼脸😳)

    为什么是"undefined"?.
    我们必须要知道this运算符是怎么工作的.

    JS语言精粹总结的很精炼:
    1 纯粹的函数调用
    2 作为对象方法的调用
    3 作为构造函数调用
    4 apply调用

    我们看看题目是属于那种环境?
    arguments[0]()中执行了一个方法,arguments[0]就是foo.bar方法
    注意:这在foo.bar中的this是没有绑定到foo

    虽然 foo.bar 传递给了函数,但是真正执行的时候,函数 bar 的上下文环境是 arguments ,并不是 foo

    arguemnts[0] 可以理解为 arguments.0(不过写代码就不要这样了,语法会错误的),所以这样看来,上下文环境是 arguemnts 就没问题了,所以在执行baz的时候自然this就是window了,window 上没有baz属性,返回的就是undefined, typeof调用的话就转换成"undefined"了


    //第7题  答案A
    var foo = {
    bar: function () {
        return this.baz;
    },
        baz: 1
    };
    typeof (f = foo.bar)();
    A. "undefined"
    B. "object"
    C. "number"
    D. "function"
    

    1)这题还是在考察this的指向问题

    2)foo.bar的确是方法的调用方式,但是在赋值给f的时候这个this的指向还是被改变了

    3)把调用函数拆分一下就清楚了

    var f = foo.bar
    typeof f();
    

    4)这样在调用形式上又是普通函数调用,this指向window;同上题,答案是A


    //第8题  答案B
    var f = (function f() {
        return "1";
    }, function g() {
        return 2;
    })();
    typeof f;
    A. "string"
    B. "number"
    C. "function"
    D. "undefined"
    

    1)此处是一个立即执行函数,但是在前面的包含函数的圆括号(命名空间)中出现了2个函数,并用逗号分隔

    2)这种形式,最终圆括号返回的是最后的一个值

    //来看一个例子
    var a = (1,2,3,4)
    console.log(a) //4
    
    //题目中的情况,最终将后面的函数返回
    var f = (function f() {return "1";}, function g() {return 2;})
    console.log(f) //function g() {return 2;}
    

    3)所以,同样的此处会返回第二个函数出来执行,得到的最终返回值是2并赋值给f;所以答案是B


    //第9题  答案C
    var x = 1;
    if (function f() {}) {
        x += typeof f;
    }
    x;
    A. 1
    B. "1function"
    C. "1undefined"
    D. NaN
    

    1)首先在if判定中,函数f的布尔值是true;所以判定条件成立,可以执行if中的语句

    2)函数f在正常声明的情况下,typeof f应该是"function"

    3)但是题目中f函数只是if的判定条件,没有经过声明;所以typeof f返回"undefined",所以答案是C

    //单独声明的情况下,f是函数类型
    function f(){}
    typeof f //"function"
    
    //但题目中f作为一个if中的判定条件存在,未得到声明
    if(function f(){}){
        
    }
    typeof f //"undefined"
    

    //第10题  答案B
    var x = [typeof x, typeof y][1];
    typeof typeof x;
    A. "number"
    B. "string"
    C. "undefined"
    D. "object"
    

    1)数组中获取坐标1的是typeof y,因为y未声明,所以返回"undefined"并赋值给x

    2)所以typeof x就是typeof "undefined"返回"string",typeof "string"依然返回"string";所以答案是B


    //第11题  答案A
    (function (foo) {
        return typeof foo.bar;
    })({
        foo: {
            bar: 1
        }
    });
    A、"undefined"
    B、"object"
    C、"number"
    D、Error
    

    1)又是一个立即执行的匿名函数,首先拆分一下

    var a = { foo:{ bar:1 } }
    (function (foo) { return typeof foo.bar; })(a);
    

    2)再简化

    var a = { foo:{ bar:1 } }
    var foo = a;
    typeof foo.bar
    

    3)再简化,用a将foo替代掉

    var a = { foo:{ bar:1 } }
    typeof a.bar
    

    现在就清楚了,无法直接通过a访问bar属性,只有通过a.foo.bar才成立,所以答案是A

    ps:这个思路是看到的别人的解析,但是总觉得简化函数的第二步存在问题(var foo = a这步)

    //第12题  答案B
    (function f() {
        function f() {
            return 1;
        }
        return f();
        function f() {
            return 2;
        }
    })();
    A、1 
    B、2 
    C、Error (e.g. “Too much recursion”) 
    D、undefined
    

    1)形式类似于第8题,中间多了个return

    2)正常来说,return会导致跳出函数,所以后边的语句不会执行

    3)但是,此处因为两个函数都是普通声明的函数,会被优先解析,所以第二个函数是在return前执行的;所以答案还是B


    //第13题  答案B
    function f() {
        return f;
    }
    new f() instanceof f;
    A、true 
    B、false
    

    1)首先,instanceof是用来检测原型的,如果是原型返回true,否则返回false

    2)此处函数f中return了一个返回值f,导致new出来的东西与原来期望的实例化对象已经不是一个东西了,所以答案是false

    //如果这里返回的是this或者不定义返回值(默认返回一个this)
    function f() {
        return this;
    }
    new f() instanceof f; //true
    
    //题目中return了f后的结果
    function f() {
        return f;
    }
    new f() instanceof f; //false
    

    3)再说的详细一些,引用一篇看到的解释:小小沧海--第六问处对于new的解释

    1、没有返回值则按照其他语言一样返回实例化对象。

    2、若有返回值则检查其返回值是否为引用类型。如果是非引用类型,如基本类型(string,number,boolean,null,undefined)则与无返回值相同,实际返回其实例化对象。

    3、若返回值是引用类型,则实际返回值为这个引用类型。

    //对比调试
    //首先没有返回值,没有问题
    function a(){}
    new a() //a {}
    new a() instanceof a //true
    
    //这是返回非引用类型,也是true
    function a(){return true}
    new a() //a {}
    new a() instanceof a //true
    
    //这是返回引用类型,这个就是false了,因为new出来的东西被返回值覆盖
    function a(){return {a:1}}
    new a() //Object {a: 1}
    new a() instanceof a //false
    
    //类似的,题目中应该也是引用的类型
    function f() {return f;}
    new f() //function f(){return f} 
        //关键就是这里了
        //new出来的东西被返回值强行指向原本的函数本身,而不是其实例化对象,当然原型也无从谈起
    new f() instanceof f; //false
    

    也就是说,调试结果显示;只有new出来的是原函数的实例化对象,这个原型才会指向原函数(这是我的理解😳)

    妈蛋总算写完,累死宝宝了😂

    新手上路,错漏之处,请各位大神指导

    相关文章

      网友评论

      本文标题:尝试解析js面试题(二)

      本文链接:https://www.haomeiwen.com/subject/vsazrttx.html