2018已步入尾声,苦苦奋斗了一年的各位程序猿(媛)们估计早已蠢蠢欲动,憧憬着新的一轮涨薪,话不多说,直接上代码,一切没有答案和解说的面试题都是耍牛氓,各位看官如果有收获,请务必记得点赞给余支持
一面就不多说了,简单的问了一下基本情况
1.目前用的什么框架?
2.正在做什么项目?
3.有没有做过xxx?(这里很可能就是你即将去贵公司要参与的项目,这时候就知道自己改对症下药了)
4.有了解过xxx? (比如es6,nodejs,webpack)
基础面试
每一次console.log输出多少,将 var 改成 let,每一次的console.log输出又是多少
var a = 10; // 全局变量挂载在 window 对象上
(function () {
// 匿名函数的回调形成独立的作用域,函数内部无法获取外部的 a
// 变量声明提升 var a;
console.log(a); // 输出 undefined
a = 5; // 没有用 var 进行声明,会在该作用域内部形成全局变量,而且会变量声明提升
console.log(a); // 5
console.log(window.a); // 输出 10
var a = 20; // 重新赋值
console.log(a) // 输出20
})()
嗯嗯,看完感觉一搬搬,没有是么特殊的难点,唯一的坑就是第一个 console.log(a) 也许你会以为返回 10,只要你牢记作用域,任凭在花哨的出题也无法扰乱我们坚守的道心,那就是 作用域、作用域、作用域
如果将 外部 var 改成let
let a = 10; // let 声明的变量不会挂载到全局window对象上
(function () {
// 匿名函数的回会形成独立的作用域,函数内部无法获取外部的 a
// 变量声明提升 var a;
console.log(a); // 输出 undefined
a = 5; // 没有用 var 进行声明,会在该作用域内部形成全局变量,而且会变量声明提升
console.log(a); // 5
console.log(window.a); // 输出 undefined
var a = 20; // 重新赋值
console.log(a) // 输出20
})()
既然都已经无法访问了,随你怎么改,俺就是不为所动,你爱谁谁啊,这就是纯粹的忽悠,不要面试官一问你瑟瑟发抖,坚守本心最重要
如果将 回调函数内部的 var 改成 let
var a = 10; // let 声明的变量不会挂载到全局window对象上
(function () {
console.log(a); // 用let进行声明,就存在了内部的块级作用域, a is not undefined
a = 5; // 看起来有了内部的全局变量,但是操作依然在 let 之前,所以然并卵 a is not defined
console.log(a);
console.log(window.a); // 10
let a = 20; // 重新赋值
console.log(a) // 输出20
})()
关于 let 块级作用域的学习,请参见 阮大大的es6教程
是不是很简单,其实也没有考啥,就是一个作用域的问题,我说过,万变不离其中,不要被各种各样的用法所迷惑
原生js封装一个事件代理
eg: proxy(document.querySelector(‘ul’), ‘li’, ‘click’, function () { console.log(this.innerHTML) })
// 面向对象的编程小小的秀一下
const proxyUtil = {
// 获取目标对象
getTarget: function (event) {
return event.target || event.srcElement;
},
proxy: function (element, targetEle, handleType, handle) {
let _that = this
element["on" + handleType] = function (e) {
let target = _that.getTarget(e); // 获取目标节点
if (target.nodeName.toLocaleLowerCase() === targetEle) {
handle.call(target, null)
}
}
}
}
proxyUtil.proxy(document.querySelector('ul'), 'li', 'click', function () {
console.log(this.innerHTML)
})
考察的知识点很简单,就是对原生js的理解,大厂嘛,就是喜欢自己造轮子,你懂得,Ta 们并不喜欢不可控的轮子,当然自己早的轮子肯定就是最安全的毋庸置疑
以下的输出结果
(function () {
var i=0;
var arr = [];
for (i; i< 3;i++) {
arr.push(function () {
console.log(i)
})
}
arr[0](); // 3
arr[1](); // 3
arr[2](); // 3
})()
以上老生常谈的问题就不做解释为什么了哈?如果时至如今,在前端江湖,这个还不懂,请恕我不能为力
将var 改成 let
(function () {
let i=0;
let arr = [];
for (i; i< 3;i++) {
arr.push(function () {
console.log(i)
})
}
arr[0](); // 3
arr[1](); // 3
arr[2](); // 3
})()
这就是一个心理战术啊,可怜的程序员,曾经以为只要会敲代码完成任务就够,后来发现和自己水平相当甚至稍有逊色的同事比自己的薪资拿的不止多一点的时候,才有所觉悟光会敲代码是不够的,还要和人精(HR)玩儿心理战,曾以为技术面试试最讲道理的,没想到如今也是步步惊心。重要的话就讲三遍: 作用域、作用域、作用域
如何将 var 改成 let 可以达到 0、1、 2 的结果
(function () {
let i=0;
let arr = [];
for (let i=0; i< 3;i++) {
arr.push(function () {
console.log(i)
})
}
arr[0](); // 0
arr[1](); // 1
arr[2](); // 2
})()
根据跟人经验,到此一般属于点到为止,还没碰到过哪位面试官要你在讲讲为什么可以形成块级作用域
可否不用 es6 实现刚才的效果
(function () {
var i=0; // 或者 let i = 0
let arr = [];
for (i; i< 3;i++) {
(function (i) {
arr.push(function () {
console.log(i)
})
})(i)
}
arr[0](); // 0
arr[1](); // 1
arr[2](); // 2
})()
这时候,才是真的入戏了,当你写完这段代码,就是和闭包相关的问题,eg: 谈谈你对闭包的理解,闭包的优缺点…
当你说道内存释放的时候,就会带出垃圾回收机制(自行问度娘啊),接下来就是优化相关(HTML、JS、webpack、魔模块化、H5缓存、http缓存……) , 更多干货,点我丫
房间里有100盏电灯,编号为1,2,3……100,每盏灯上有一个按钮,初始时灯全都是关的。编好号的100位同学由房间外依次走进去,将自己编号的倍数的灯的按钮全部按一次,例如第一位同学把编号是1的倍数的灯的按钮按一下(此时100盏灯全亮),第二位同学把编号是2的倍数的灯的按钮按一下(此时只有50盏灯亮着,50盏被这个人按灭了)……第100位同学把编号是100的倍数的灯(即编号为100的灯)的按钮按一下,请问依次走完后,还有多少盏灯亮着。
关于 100 盏灯的点击, 规律找 每个数的公约数(可以被开平方的数)
var findOpenLight = {
arr: [],
createArr: function () {
for (let i = 1, l = 100; i <= l; i++) {
this.arr.push(i)
}
return this.sqrt(this.arr)
},
sqrt: function(arr) {
let newArr = arr.filter((item, index, arr) => {
return Math.sqrt(item).toString().indexOf('.') === -1
})
return newArr
}
}
console.log(findOpenLight.createArr())
这是一个简单的逻辑推理题,面试官想看看你的逻辑思维能力,毕竟程序的世界里,只有想不到没有做不到,一个需求出来了,你都没有任何的思路和逻辑,这么可能写的出来
结束语:
这是一个上市工资的面试题,招聘的岗位是高级前端,这是笔试题中的一部分,后续我会继续更上有关更坑的面试题,今天就总结到这里,但愿各位看官来年薪资有大幅度的提升,学习是一件枯燥的事,但是没有比学习更可以让人充实的事,如果从这里可以让你有所收获,我也感到荣幸。
- 更多的干货请点击这里
- react-native项目实战学习
- 希望该文章对您有帮助,也希望得到您的鼓励和支持