JavaScript面试题(1)
第一题:赋值,调用
var a, b;
(function () {
alert(a);
alert(b);
var a = b = 3;
alert(a);
alert(b);
})();
alert(a);
alert(b);
依次弹出:undefined,undefined,3,3,undefined,3
解析: var a=b=3 相当于 var a = 3;b = 3;b是全局的
第二题: 异步任务
console.log(1); let a = setTimeout(() => { console.log(2) }, 0); console.log(3); Promise.resolve(4).then(b => { console.log(b); clearTimeout(a); }); console.log(5);
答案: 1 3 5 4
解析:
在执行异步任务:其中异步任务分为宏任务和微任务,微任务优先级高于宏任务。promise.then执行的微任务,输出4,然后clearTimeout(a)清除了定时器,于是不再打印2。
第三题:
var str = "stiabsstringapbs"; var obj = {}; for (var i = 0; i < str.length; i++) { var key = str[i]; if (!obj[key]) { obj[key] = 1; } else { obj[key]++; } } var max = -1; var max_key = ""; var key; for (key in obj) { if (max < obj[key]) { max = obj[key]; max_key = key; } } alert("max:" + max + " max_key:" + max_key);
答案: max:4 max_key:s
解析:
第四题:(--运算符)
function out(x) { var temp = 2; function inside(y) { document.write(x + y + (temp--)); } inside(5); } out(3);
答案: 10
解析: 如果该运算符作为后置操作符,则返回它递减之前的值。如果该运算符作为前置操作符,则返回它递减之后的值。
第五题:(构造函数)
var F = function () {}; Object.prototype.a = function () {}; Function.prototype.b = function () {}; var f = new F();
答案: f 能取到a,但取不到b
解析:
1. f.__proto__ === f[的构造函数].prototype === F.prototype
2. F.prototype.__proto__ === (F.prototype)[的构造函数].prototype === Object.prototype (所以a能够 通过f.a访问)
3. f.constructor === F
4. F.__proto__ === F[的构造函数].prototype === Function.prototype (所以b可以通过, f.constructor.b访问到)
注意:
(F.prototype)[的构造函数] === Object
F[的构造函数] === Function
网上有一道美团外卖的面试题是这样的:
Function.prototype.a = 'a';
Object.prototype.b = 'b';
function Person(){};
var p = new Person();
console.log('p.a: '+ p.a); // p.a: undefined
console.log('p.b: '+ p.b); // p.b: b 问为什么?
有不少同学第一眼看上去就觉得很疑惑,p不是应该继承了Function原型里面的属性吗,为什么p.a返回值是undefined呢?
其实,只要仔细想一想就很容易明白了,Person函数才是Function对象的一个实例,所以通过Person.a可以访问到Function
原型里面的属性,但是new Person()返回来的是一个对象,它是Object的一个实例,是没有继承Function的,所以无法访问
Function原型里面的属性。但是,由于在js里面所有对象都是Object的实例,所以,Person函数可以访问到Object原型里面的
属性,Person.b => 'b'
第六题:
function test() { var n = 4399 function add() { n++ console.log(n) } return { n: n, add: add } } var reslut = test() var reslut2 = test() reslut.add() reslut.add() console.log(reslut.n) reslut2.add()
答案: 4000 4001 4399 4000
解析: 在第三个,这里{n:n}是对变量n里的值进行缓存,而不是本身n这个指针变量,这样生成add的时候n指向的值是多少{n:n}里的值就是多少