不多说先上图,下面有每道题的详细解答:
这个是西安某个公司的面试题,时间半个小时,题不太难,小心作答还是可以的,博主有些地方也没弄清楚(只是觉得平时不用,就有所放松),先来我们看看具体每道题是怎样解答的。
1. javascript哪些值可以被转换成false
'' 0 null undefined NaN false
2.如何判断变量的正确类型?
// 使用typeof或者intanceof也可以正常判断类型,至于使用哪种方式判断可以自行考量
Object.prototype.toString.call(letType)
3.判断如下运行结果?
for (var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000)
}
解答: 10个10,setTimeout是延时队列,会在程序最后执行相对于微队列和延时队列优先级最低,所以是10个10
4. var set = new Set([0, 2, 2, 0, 0, 5, 9, {}, {}, NaN, NaN]) 请回答set.size的结果
console.log(set.size); // 7
解答: Set是被定义去重的功能,而上面的执行结果就是 [0,2,5,9,{},{},NaN] 在Set内部NaN是相等的
5. 判断a = []是数组的方法
和第2个问题判断方法相同,还可以使用Array.isArray(), 还可以结合typeof进行判断,都可以效果自己权衡
中等
1. 输出以下结果
function Foo() {
getName = function() {
console.log(1);
}
return this;
}
Foo.getName = function() {
console.log(2);
}
Foo.prototype.getName = function() {
console.log(3);
}
var getName = function() {
console.log(4);
}
function getName() {
console.log(5);
}
Foo.getName()
getName()
Foo().getName()
getName()
解答:2 4 1 1 这个题考察原型实例之间的关系
Foo.getName() 的调用很明显是 Foo.getName = function() {console.log(2);} 构造函数方法优先原型上的方法
getName() **当变量声明时没有赋值或初始化,函数声明的优先级高于变量,否则变量优先级高于函数。**
这个也就是说变量有初始化值的时候变量优先级高于函数,结果就是4
Foo().getName() 这个在node环境中是执行不出来的,会有问题,需要在浏览器环境执行。
先调用Foo()在通过链式调用Foo里面的getName方法,所以就是 1 ,并返回并返回当前作用域(或者说当前作用于指向Foo)
getName() getName的重新赋值是指向的闭包里的getName(即外层window上的getName)
这个本身没有什么难度,额,我把这个题写错了,哈哈哈,时间长没复习啥都忘了,大家面试之前好好看看这块内容
1.1 判断下面代码
function SetCount(count) {
this.count = count
}
SetCount.prototype.printCount = function() {
console.log(this.count);
}
let a = new SetCount(100)
a.count = 200
a.__proto__.count = 300
a.__proto__.printCount() // 300
a.printCount() // 200
解答: 这个a 是 SetCount的实例,这个时候a.count是100,a.count = 200 修改了a这个实例上的count为200
再往下需要知道a.proto === SetCount.prototype这个关系,a.proto.count就是SetCount.prototype.count = 300, a.proto.printCount() 的意思就是 SetCount.prototype.printCount() 那这个原型上已经被赋值300,所以 a.proto.printCount() 就是300.。a.printCount()调用的是实例上的count,实例上的已经被赋值200,所以就是200
知识点分析: 这个里边需要用到原型和实例之间关系,new一个构造函数之后会生成一个实例,可以给实例挂载属性和方法,可以给这个构造函数添加原型属性和原型方法,如果访问实例上的属性或方法不存在就回去构造方法的原型上去找,找不到则继续沿着原型链关系查找找到就返回,找不到就返回null
2. 请实现一个方法,求出最大值和最小值,例如 [2,3] -> 3 [2,4,3] -> 4
自行解答,这种题无聊之程度令人喷饭
const boring = [2,4,3]
Math.max.apply(null,boring) // 4
boring.sort().reverse()[0]
3. 请事先一个或多个方法,能将字符串中重复部分去重,例如 'hello' -> 'helo'
哎。。。
const set = new Set(str)
let strs = ''
for (let i of set) {strs += i}
诸多方法,自行探索
4. 回答一下执行结果
var name = 'Tom'
(function() {
if (typeof name == 'undefined') {
var name = 'jack'
console.log('goodbye', name);
} else {
console.log('Hello', name);
}
})()
解答: goodbye jack 预解析name是undefined执行if中的代码。
var a = 10;
(function() {
console.log(a); // undefined
a = 5
console.log(window.a); // 10
var a = 20
console.log(a); // 20
})()
解答: 自执行函数直接执行,里面没有a但是会创建一个,没有值就是undefined。window.a就是获取全局的a变量 10 最后一个a就近查找就是20
// javasccript
var a = { n: 1 }
var b = a
a.x = a = { n: 2 }
console.log(a.x); // undefined
console.log(b.x); // { n:2 }
这个题比较好,应为我当时做错了,哈哈哈,这个以后得注意
5. javascript
function changeObjPrototype(o) {
o.siteUrl = 'www.baidu.com'
o = new Object()
o.siteUrl = 'www.google.com'
}
let webSite = new Object()
changeObjPrototype(webSite)
console.log(webSite.siteUrl); // www.baidu.com
解答:传进去的是一个外部的实例,内部会有一个新的实例挂载新的siteUrl方法
6. 完成下列等式
class A{}
class B extends A{}
const a = new A()
const b = new B()
a.__proto__ ===
b.__proto__ ===
B.__proto__ ===
B.prototype.__proto__ ===
b.__proto__.__proto__ ===
// 解答
// console.log(a.__proto__ === A.prototype);
console.log(b.__proto__ === B.prototype);
console.log(B.__proto__ === A);
console.log(B.prototype.__proto__ === A.prototype);
console.log(b.__proto__.__proto__ === A.prototype);
把下面这个图看一下,找几道题基本就没啥问题了
添加图片注释,不超过 140 字(可选)
7. 请写出一下代码运行结果(浏览器环境)
function Person(){}
var person1 = new Person()
var person2 = new Person()
Person.prototype.getName = function(){
return this.name
}
Person.prototype.name = "tom"
person1.name = "jerry"
var name = person2.getName()
console.log(name) // tom
解答:构造函数和实例之间的关系,new一次就是一个实例
var name = "tom"
function getMethod(){
var result = function(){
return name
}
var name = "jerry"
return result
}
var getName = getMethod()
var name1 = getName()
console.log(name1) // jerry
解答:getMethod返回result函数赋值给getName,通过getName就可以调用内部的namee已经是jerry
8. 事件循环面试题
setTimeout(function() {
console.log(1)
}, 0)
new Promise(function execulor(resolve) {
console.log(2)
for (let i = 0; i < 10000; i += 1) {
i == 9999 && resolve()
}
console.log(3);
}).then(function() {
console.log(4);
})
console.log(5);
// 23541
解答:现在最新的文档已经没有宏任务和微任务的相关描述,最新的说法微队列,延时队列,交互队列,下载队列的说法
渲染主线程(优先级最高)2 3 5
微队列(高)4
延时队列 (低) 1
结果就是 2 3 5 4 1
再来一个事件循环面试题
async function async1() {
console.log("async1 start");
await async2()
console.log("async1 end");
}
async function async2() {
console.log("async2");
}
console.log("script start");
setTimeout(function() {
console.log('setTimeout')
}, 0)
async1()
new Promise(function(resolve) {
console.log("promise1");
resolve()
}).then(function() {
console.log("promise2");
})
console.log("script end");
/**
*
* script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
*/
和上面分析思路一致
渲染主线程(优先级最高)script start | async1 start | async2 | promise1 | script end
微队列(高) async1 end | promise2
延时队列 (低) setTimeout
结果就是
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
加分题
1. 实现一个变量a使用满足条件判断 a == 1 && a == 2 && a == 3
var a = {
num: 0,
valueOf:function(){
return this.num++
}
}
解答:了解valueof,这个也是最近比较火的面试题,大家一起抄起来
2. 一共有10级台阶一次只能走一级或两级总共有多少种走法?
function step(n) {
if (n == 1) {
return 1
}
if (n == 2) {
return 2
}
return step(n - 1) + step(n - 2)
}
console.log(step(10)); // 89
总结:有的面试题不错,有的有点糟糕,不过人家公司招人按人家的游戏规则玩吧,认真总结就完事了,卷死他们、卷死他们、卷死他们