zoukankan      html  css  js  c++  java
  • javascript面试题(一)

    1.

    var bar = null;
    console.log(typeof bar === 'object');
    //logs true!
    

      尽管 typeof bar === "object" 是检查 bar 是否对象的可靠方法,令人惊讶的是在JavaScript中 null 也被认为是对象!

    2.

    (function(){
    var a = b =3;
    })();
    console.log(typeof a == 'undefined');     //true
    console.log(typeof b == 'undefined');   //false
    

      这个时候的变量b声明是不加关键字var的,也就是说变量b是全局变量(隐式全局变量)。

    他等同于

    b = 3;
    var a =b ;
    

      如果使用严格模式(use strict)结果会是:

    报错:b is not undefined
    3.
    var myObject = {
        foo: "bar",
        func: function() {        
            var self = this;        
            console.log(this.foo);        
            console.log(self.foo);
            (function() {            
                console.log(this.foo);            
                console.log(self.foo);
            }());
        }
    };
    myObject.func();   // bar bar undefined bar

      

    在外部函数中,  this 和 self 两者都指向了 myObject  ,因此两者都可以正确地引用和访问 foo 。 

    在内部函数中, this不再指向myObject。其结果是,this.foo 没有在内部函数中被定义,相反,指向到本地的变量 self 保持在范围内,并且可以访问。 (在ECMA 5之前,在内部函数中的this 将指向全局的 window 对象;反之,因为作为ECMA 5,内部函数中的功能this 是未定义的。)

    4.use strict有什么好处?

      >1.是调试容易.
      >2.防止意外的全局变量
      >3.消除this指向,如果this指向null或undefined,this将指向全局变量
     >4.不允许重复的属性名或参数值 
     >5.使用delete删除失败时会抛出错误
    5.
    function foo1(){  
        return {
          bar: "hello"
        };
    }
        
    function foo2(){  
        return
          {
              bar: "hello"
          };
    }
    

      返回结果

    console.log(foo1());   // bar:"hellow";
    console,log(foo1());   //undefined
    

      当碰到 foo2()中包含return语句的代码行(代码行上没有其他任何代码),分号会立即自动插入到返回语句之后。请仔细留意上面两个函数中return的不同之处,foo2函数的return是单独一行的。

    6.

    console.log(typeof NaN === "number");  
    // logs "true"
    //如果拿NaN与本身比较
    console.log(NaN === NaN )
    // logs "false"

      一种半可靠的方法来测试一个数字是否等于 NaN,是使用内置函数 isNaN(),但即使使用 isNaN() 依然并非是一个完美的解决方案。

    7.

    console.log(1 +  "2" + "2");
    // logs "112";

      1 + "2" 是执行的第一个操作。由于其中一个运算对象 "2" 是字符串,JavaScript会假设它需要执行字符串连接,因此,会将 1 的类转换为 "1"  ,  1+"2" 结果就是 "12" 。然后, "12"+"2" 就是 "122" 。

    console.log(1 +  +"2" + "2");
    // logs "32"

      

    根据运算的顺序,要执行的第一个运算是 +"2" (第一个 "2" 前面的额外 + 被视为一元运算符)。

    因此,JavaScript将 "2" 的类型转换为数字,然后应用一元 + 号(即将其视为一个正数)。其结果就是得到一个数字 2 ,接下来的运算就是 1 + 2 ,这当然是 3 。

    然后3+"2"Javascript会假设它需要执行字符串链接,因此会将3的类型转化为"3",结果就是"32"

    console.log(1 +  -"1" + "2");
    // logs "02"

      根据运算的顺序,要执行的第一个运算是 -"1" (第一个 "1" 前面的额外 + 被视为一元运算符)

    因此,JavaScript将 "1" 的类型转换为数字,然后应用一元 + 号(即将其视为一个正数)。其结果就是得到一个数字 21,接下来的运算就是 1 - 1,这当然是 0

    然后0+"2"Javascript会假设它需要执行字符串链接,因此会将0的类型转化为"0",结果就是"02"

    console.log(+"1" +  "1" + "2");
    // logs "112"

      虽然第一个运算对象  "1" 因为前缀的一元 + 运算符类型转换为数值,但当连接到第二个运算对象 "1" 的时候,又立即转换回字符串,然后又和最后的运算对象 "2"  连接,产生了字符串  "112" 。

    console.log( "A" - "B" + 2);
    // logs NaN

       "A" - "B" 结果为 NaN 。但是,应用任何运算符到 NaN 与其他任何的数字运算对象,结果仍然是 NaN 。

    console.log("A" - "B" + "2")
    // logs "NaN2"

      由于运算符 - 不能被应用于字符串,并且 "A" 和 "B" 都不能转换成数值,因此, "A" - "B" 的结果是 NaN  ,然后再和字符串 "2"  连接,得到 "NaN2"  。

    8. | | 或 && 运算符

    表达式a && 表达式b :  计算表达式a(也可以是函数)的运算结果,

                                             如果为 True, 执行表达式b(或函数),并返回b的结果;

                                             如果为 False,返回a的结果;

    表达式a || 表达式b :   计算表达式a(也可以是函数)的运算结果,

                                          如果为 Fasle, 执行表达式b(或函数),并返回b的结果;

                                           如果为 True,返回a的结果;

     9.  以下代码输出什么,为什么?

    var a={},
        b={key:'b'},   
        c={key:'c'};
    
    a[b]=123;
    a[c]=456;
    
    console.log(a[b]);
    // logs 456

      b,c做属性时,都会隐式转化为[object object],当两个都为[object object]时,后者会覆盖前者即无论console.log(a[b])或console.log(a[c])输出结果都为456;

    10.关于this指向,this指向谁

    var person = {
        _name: 'I am John',
        sayHello: function (){        
            return this._name;
        }
    };
            
    var sayHello = person.sayHello;
    
    console.log(sayHello());             //undefined
    console.log(person.sayHello());      //I am John
    

      当执行sayHellow时,this._name指向window窗口,在window下找_name属性已经不存在,所以为undefined;

    11.关于变量提升

    function test() {
       console.log(a);
       console.log(foo());
       
       var a = 1;
       function foo() {
          return 2;
       }
    }
     
    test();      //undefined 2
    

      变量和函数都被提升到了函数体的顶部,Js编译的阶段会找到所有的申明,包括变量申明和函数申明,他们会在代码执行前被编译处理提前执行,就好像位置被提前到前面,

      提身后的代码如下:

    function text() {
      var a ;
      function foo() {
              return 2;
       }
       console.log(a);
       console.log(foo());
      a = 1; } } test();

      代码从上而下执行,所以调用函数后执行的解果为 undefined  和  2.

    12.事件循环

    function printing() {
        
        console.log(1);
    
        setTimeout(function() {
            console.log(2);
        }, 1000);
    
        setTimeout(function() {
            console.log(3);
        }, 0);
    
        console.log(4);
    }
    
    printing();      // 1 4 3 2;
    

      当调用setTimeout时,即使设置的时间为0时,也会被排队.先执行其他非延迟语句执行完成后,才会执行.

    13.理解应用闭包

    function outFunc(){
    
        var name = "前端君";
    
        function inFunc(){
    
            console.log(name);
    
        }
    
        return inFunc;
    
    }
    
    inFunc();     //控制台显示"前端君"
    

      函数inFunc认可访问outFunc私有属性

    14.关于delete删除符

    var x = 1;
    var output = (function(){
        delete x;
        return x;
    })();
    
    console.log(output);  //1
    

      delete 操作符是将 object 对象的属性删去的操作。但是这里的 x 是并不是对象的属性,  delete 操作符并不能作用,所以打印的出的结果仍然是 x 的值。

    15.

    var x = { foo : 1};
    var output = (function(){
        delete x.foo;
        return x.foo;
    })();
    
    console.log(output);   // undefined
    

      delete 操作符是将 object 对象的属性删去的操作.删除后.x变为var x;然后在访问它,申明但未赋值.所以为undefined.

    16.

    var name = 'World!';
    (function () {
        if (typeof name === 'undefined') {
            var name = 'Jack';
            console.log('Goodbye ' + name);
        } else {
            console.log('Hello ' + name);
        }
    })();      //Goodbye  Gack;
    

      变量提升,提升后代码如下

    var name;
    (function () {
        var name;
        if(typeof  name === 'undefined') {
             name = 'Jack';
            console.log(Goodbye'  +  name);
           } else {
             console.log('Hellow ' + name);
           }
       })();  
    name = 'World';      
    

      所以执行if时,name为赋值,执行第一个if语句,结果就是Goodbye  Gack;

    17.

    ["1", "2", "3"].map(parseInt);          //[1,NaN,NaN]
    

      结果分析

    parseInt("1",0);   // 当参数为0时,则以十为基数来解析
    parseInt("2",1);   // NaN,第二个参数的范围为2~36
    parseint("3",2);  // NaN
    

    18.

    [typeof null, null instanceof Object]        // [object , false] 
    

      null并不是从原型链上创建出来的,所以null instanceof object 为false

           typeofnull为object

    19.

    var a = [0];
    if ([0]) {
        console.log(a == true);
    } else {
        console.log("wut");
    }
    // logs false;

    当判断时会将[0]转换为"0",然后转化为布尔类型,0为true,然后执行if语句第一个,a == true;a为数组所以转换为0,true转换为数字类型为1;0 != 1,所以返回false.

    20.

    (function(){
        var x = y = 1;
    })();
    console.log(y);     //  1
    console.log(x);     //  error
    

     由于y未申明,所以y会隐式转化为全局变量,即:

    var  y =  1;
    (function () {
             var x = y = 1;
      })();
    

      函数外面是无法访问函数里面的变量的,所以会出现x is  not defined;会报错

    21.

    var a = [1, 2, 3],
        b = [1, 2, 3],
        c = [1, 2, 4];
    console.log(a == b);        //false
    console.log(a === b);      //false
    console.log(a > c);      //false
    console.log(a < c);       //true
    

      >>a==b,相比较,是object和object的比较,会比较他们的存储地址,很显然他们的存储地址不同,所以返回false;

           >>a===b,运算要求两边的数值和类型完全相同,a,b类型都为object/array,但是他们应用地址不同,所以返回false;

      >>a>c,数值比较,由于数组不能比较,所以会转换为字符串类型,"1,2,3">"1,2,4",显然3<4,所以返回false;

      >>a<c,同上原理,所以返回true

    22.

    var two   = 0.2;
    var one   = 0.1;
    var eight = 0.8;
    var six   = 0.6;
    [two - one == one, eight - six == two]

    //logs [true , false]

      二进制

    23

    '5' + 3
    '5' - 3
    // logs "53"
    // logs 2;

      js中  +  除了运算符外还有连接作用,运算符一般都会先转换为number类型然后在运算,  +  不会,如果 + 两边一边是 数字 一边是字符串,会做拼接字符串的操作

  • 相关阅读:
    向量的旋转
    阅读开源库源码,发现这两个方法,惭愧啊!真没看明白
    小实例窥探dotnet垃圾回收
    记录asp.net在IE10下事件丢失排错经过
    CSS布局技巧之——各种居中
    前端程序员容易忽视的一些基础知识
    Web前端体系的脉络结构
    前端程序员容易忽视的一些基础知识
    CSS布局技巧之——各种居中
    面试分享:一年经验初探阿里巴巴前端社招
  • 原文地址:https://www.cnblogs.com/wsjaizlp/p/10041673.html
Copyright © 2011-2022 走看看