最基本的JavaScript面试题(16个)

1.使用 typeof bar === "object" 来确定 bar 是否是对象的潜在陷阱是什么?如何避免这个陷阱?

陷阱:

typeof null === "object" //true

避免:

console.log((bar !== null) && (typeof bar === "object"));  // false

2.下面的代码将输出什么到控制台,为什么?

(function(){

var a=b=3;

})();

console.log("a defined? "+(typeof a!=='undefined'));

console.log("b defined? "+(typeof b!=='undefined'));

输出:

a defined?false

b defined?true

原因:

var a = b = 3; 实际是以下声明的简写:

b=3;

var a=b;

在闭包外访问内部变量,正常应该输出undefined。b不是undefined,是因为没有var声明,则b=3,默认定义的是全局变量。

3.封装JavaScript源文件的全部内容到一个函数块有什么意义及理由?

创建一个私有的命名空间,避免不同JavaScript模块和库之间潜在的名称冲突。

4.在JavaScript源文件的开头包含 use strict 有什么意义和好处?

意义:

有利于那些被忽略或默默失败了的代码错误,产生或抛出异常。

严格模式的主要优点:

(1)使调试更加容易。

(2)防止意外的全局变量。

(3)消除 this 强制。如果没有严格模式,引用null或未定义的值到 this 值会自动强制到全局变量。在严格模式下,引用 null或未定义的 this 值会抛出错误。

(4)不允许重复的属性名称或参数值。有利于bug的定位。

(5)使eval() 更安全。

(6)在 delete使用无效时抛出错误。

5.考虑以下两个函数。它们会返回相同的东西吗? 为什么相同或为什么不相同?

function foo1(){  

    return {     

            bar: "hello"  

    };

}

 function foo2(){ 

     return  

    {      

        bar: "hello" 

     };

}

返回不同的东西。

foo1(); //Object{bar:"hello"}

foo2(); //undefined 

原因:

foo2的return语句后面空白,默认会被添加一个分号。导致运行后返回undefined。

6.NaN 是什么?它的类型是什么?你如何可靠地测试一个值是否等于 NaN ?

NaN:not a number

类型:number。typeof NaN,返回number

可靠地测试:

由于NaN !== NaN,可使用value !== value测试。

内置函数(全局函数)isNaN(),或ES6新增的Number.isNaN() 函数。注:后者更可靠。

7.讨论写函数 isInteger(x) 的可能方法,用于确定x是否是整数。

es6提供Number.isInteger() 函数。

es5时代,自行实现:

function isInteger(x) {

    return (x^0) === x; //或 return Math.round(x) === x;

}

function isInteger(x) {

    return (typeof x === 'number') && (x % 1 === 0);

}

8.写一个简单的函数(少于80个字符),要求返回一个布尔值指明字符串是否为回文结构。

function isPalindrome(str) {    

    str = str.replace(/W/g, '').toLowerCase();   

    return (str == str.split('').reverse().join(''));

}

9.请看下面的代码片段:

for (var i = 0; i < 5; i++) {  

    var btn = document.createElement('button');  

    btn.appendChild(document.createTextNode('Button ' + i));      

    btn.addEventListener('click', function(){ console.log(i); });  

    document.body.appendChild(btn);

}

(a)当用户点击“Button 4”的时候会输出什么到控制台,为什么?

(b)提供一个或多个备用的可按预期工作的实现方案。

答案:

(a)输出:5。原因:当 onclick 方法被调用(对于任何按钮)的时候, for 循环已经结束,变量 i 已经获得了5的值。变量i是全局变量,在click事件被触发的时候,执行响应函数function,打印i,则都会打印出5。

(b)

for (var i = 0; i < 5; i++) {  

    var btn = document.createElement('button');  

    btn.appendChild(document.createTextNode('Button ' + i));  

    btn.addEventListener('click', (function(i) {   

         return function() { console.log(i); }; 

     })(i)); 

     document.body.appendChild(btn);

}

for (var i = 0; i < 5; i++) {  

    var btn = document.createElement('button');  

    btn.appendChild(document.createTextNode('Button' + i)); 

     (function (i) {    

        btn.addEventListener('click', function() { console.log(i); });  

    })(i); 

     document.body.appendChild(btn);

}

10.下面的代码将输出什么到控制台,为什么?

var arr1 = "john".split('');

var arr2 = arr1.reverse();

var arr3 = "jones".split('');

arr2.push(arr3);

console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(-1));

console.log("array 2: length=" + arr2.length + " last=" + arr2.slice(-1));

输出:

"array 1: length=5 last=j,o,n,e,s"

"array 2: length=5 last=j,o,n,e,s"

原因:

reverse()操作会改变原数组,并返回改变后的数组。即:var a = [1,2,3]; a.reverse(); console.log(a);//[3,2,1]

同时,数组是引用类型,arr2指向arr1的地址,二者的值完全相同

11.下面的代码将输出什么到控制台,为什么?

console.log(1 +  "2" + "2"); //"122"

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

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

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

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

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

12.下面的递归代码在数组列表偏大的情况下会导致堆栈溢出。在保留递归模式的基础上,你怎么解决这个问题?

var list = readHugeList(); 

var nextListItem = function() {   

     var item = list.pop();    

     if (item) {        

    // process the list item...       

     nextListItem();   

     }

};

解决:

var list = readHugeList();

    var nextListItem = function() {    

    var item = list.pop();    

    if (item) {       

         // process the list item...        

        setTimeout( nextListItem, 0);    

    }

};

堆栈溢出之所以会被消除,是因为事件循环操纵了递归,而不是调用堆栈。当 nextListItem 运行时,如果 item不为空,timeout函数(nextListItem)就会被推到事件队列,该函数退出,因此就清空调用堆栈。当事件队列运行其timeout事件,且进行到下一个 item 时,定时器被设置为再次调用 nextListItem。因此,该方法从头到尾都没有直接的递归调用,所以无论迭代次数的多少,调用堆栈保持清空的状态。

13.JavaScript中的“闭包”是什么?请举一个例子。

闭包是一个可以访问外部(封闭)函数作用域链中的变量的内部函数。

闭包可以访问三种范围中的变量:

这三个范围具体为:(1)自己范围内的变量,(2)封闭函数范围内的变量(3)全局变量。

例子:

var globalVar = "xyz"; 

(function outerFunc(outerArg) {  

    var outerVar = 'a';   

    (function innerFunc(innerArg) {    

        var innerVar = 'b';    

        console.log(      

            "outerArg = " + outerArg + "n" +     

             "innerArg = " + innerArg + "n" +     

             "outerVar = " + outerVar + "n" +      

            "innerVar = " + innerVar + "n" +     

            "globalVar = " + globalVar);   

    })(456);

})(123);

输出:

outerArg = 123

innerArg = 456

outerVar = a

innerVar = b

globalVar = xyz

14.以下代码行将输出什么到控制台?

console.log("0 || 1 = "+(0 || 1));

console.log("1 || 2 = "+(1 || 2));

console.log("0 && 1 = "+(0 && 1));

console.log("1 && 2 = "+(1 && 2));

输出:

0 || 1 = 1

1 || 2 = 1

0 && 1 = 0

1 && 2 = 2

15.以下代码将输出什么?并解释你的答案。

var a={},   

b={key:'b'},   

c={key:'c'}; 

a[b]=123;

a[c]=456; 

console.log(a[b]);

输出:456

原因:

当设置对象属性时,JavaScript会暗中字符串化参数值。在这种情况下,由于 b 和 c都是对象,因此它们都将被转换为"[object Object]"。结果就是, a[b]和a[c]均相当于a["[object Object]"] ,并可以互换使用。因此,设置或引用 a[c]和设置或引用 a[b]完全相同。

16.创建一个函数,给定页面上的一个DOM元素,就会去访问元素本身及其所有子元素(不只是它的直接子元素)。对于每个被访问的元素,函数应该传递元素到提供的回调函数。

此函数的参数为:

DOM元素

回调函数(将DOM元素作为其参数)

访问树(DOM)的所有元素是经典的深度优先搜索算法应用。下面是一个示范的解决方案:

function Traverse(p_element,p_callback) {   

    p_callback(p_element);  

    var list = p_element.children;  

    for (var i = 0; i < list.length; i++) {       

        Traverse(list[i],p_callback);  // recursive call  

     }

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容

  • “听说北路交叉口的东边开了一家馄饨店,你要不要去试一下?”叶子歪着头一本正经的问我。 “不去...
    繁华宛如一掬细沙阅读 352评论 0 2
  • 曹越鹏阅读 141评论 0 1
  • 《摔跤吧,爸爸》这部电影是前段时间很火的一部,很可惜没能去电影院看。 后来,手机可以观影后,我分别刷了三次,每看一...
    碎碎念的又又阅读 260评论 0 1
  • 多年后的某天午后,闲来无事我便去整理书房,在书桌的抽屉里我看到几封信和一个日子本,打开看了里面的内容。这是十年前一...
    余尺素阅读 322评论 0 0