最后
今天的文章可谓是积蓄了我这几年来的应聘和面试经历总结出来的经验,干货满满呀!如果你能够一直坚持看到这儿,那么首先我还是十分佩服你的毅力的。不过光是看完而不去付出行动,或者直接进入你的收藏夹里吃灰,那么我写这篇文章就没多大意义了。所以看完之后,还是多多行动起来吧!
可以非常负责地说,如果你能够坚持把我上面列举的内容都一个不拉地看完并且全部消化为自己的知识的话,那么你就至少已经达到了中级开发工程师以上的水平,进入大厂技术这块是基本没有什么问题的了。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
解决方案
因为js中的一切都是对象,任何都不例外,对所有值类型应用 Object.prototype.toString.call() 方法结果如下:
console.log(Object.prototype.toString.call(123)) //[object Number]
console.log(Object.prototype.toString.call(‘123’)) //[object String]
console.log(Object.prototype.toString.call(undefined)) //[object Undefined]
console.log(Object.prototype.toString.call(true)) //[object Boolean]
console.log(Object.prototype.toString.call({})) //[object Object]
console.log(Object.prototype.toString.call([])) //[object Array]
console.log(Object.prototype.toString.call(function(){})) //[object Function]
判断是否为函数
function isFunction(it) {
return Object.prototype.toString.call(it) === ‘[object Function]’;
}
判断是否为数组:
function isArray(o) {
return Object.prototype.toString.call(o) === ‘[object Array]’;
}
七、null > 0, null < 0, null >= 0, null <= 0, null == 0 分别输出什么?
1.在关系运算符中,null,undefined会被Number()强制转换成数字类型;
Number(null) //0
Number(undefined) //NaN
因此:
null >= 0; //true
null <= 0; //true
null > 0; //false
null < 0; //false
2.在相等运算符中,null,undefined则不会转化为数字类型,而是经过特殊处理
null == 0 //false
null == undefined //true
null == null //true
undefined == undefined //true
八、js 的类型转换
1.隐式转换
2.转为String:String()、toString()
3.转为数值:Number()、parseInt()、parseFloat()
4.转换成布尔值:Boolean()
九、prototype 是啥,什么是原型,什么是实例原型,说说你的理解
每个构造函数都有一个prototype属性,指向一个对象,这个prototype就是一个原型对象,他所拥有的所有属性和方法,都会被构造函数所拥有
每个对象(包括实例)都有一个__proto__属性,指向构造函数的prototype原型对象,它提供了一种查找机制(原型链查找机制)
十、js 为什么不支持多继承
javascript是可以利用call方法和prototype属性来实现多继承的。继承方法与单继承相似,只是将需要继承的多个父类依次实现,另外对于属性或共有方法重命的时候,以最后继承的属性和方法为主。因为会覆盖前面的继承。
十一、深拷贝和浅拷贝的区别
【JS】深拷贝与浅拷贝的区别,实现深拷贝的几种方法
手写深拷贝函数:
function deepCopy(obj) {
var cloneObj;
if (obj && typeof obj !== 'object') cloneObj = obj;
else if (obj && typeof obj === 'object') {
cloneObj = Array.isArray(obj) ? [] : {};
for (let k in obj) {
if (obj.hasOwnProperty(k)) {
if (obj[k] && typeof obj[k] === 'object') {
cloneObj[k] = deepCopy(obj[k]); //递归
}
else {
cloneObj[k] = obj[k];
}
}
}
}
return cloneObj;
}
var obj = {
name: 'vivian',
age: 18,
course: {
time: 12,
msg: 'nihao'
}
}
var o = deepCopy(obj);
console.log(o);
十二、匿名函数、箭头函数
匿名函数:就是定义时未直接指定名称的函数
因为非匿名函数在定义时就已经创建了函数对象和作用域对象,因此,即使未调用,也占用内存空间
而匿名函数仅在调用时,才临时创建函数对象和作用域链对象,调用完立即释放,所以匿名函数比非匿名函数更节省内存空间
箭头函数:
(1)箭头函数没有自己的this,导致内部的this就是外层代码的this,他的this是定义时候的对象,而不是使用时所在的对象。call、bind、apply都不能改变
(2)因为箭头函数没有this,因此他不能当作构造函数,也就是说不能使用new命令,否则会抛出一个错误
(3)不可以使用arguments对象,该对象在函数体内不存在
(4)不可以使用yield命令,因此箭头函数不能用作generator函数
十三、变量提升
预解析+执行
好处
提高性能:预先为变量分配栈空间
容错性更好:使一些不规范的代码也可以正常执行
问题:函数内一些变量提升会导致输出undefined、循环变量输出最后的值
十四、NaN
typeof NaN;返回“number”
NaN != NaN;返回true
十五、map和object的区别
map有size、set、get、has、delete、clear方法
map结构提供三个遍历器生成函数和一个遍历方法:keys() values() entries() forEach()
十六、map和weakmap区别
weakmap有set、get、has、delete方法,没有size和clear
区别:weakmap只接受对象作为键名,weakmap的键名所引用的对象都是弱引用,也就是不计引用,因此,周期时间内,会被垃圾回收器回收,不易造成内存泄漏
十七、常用的正则表达式
//以字母开头 后面可以是数字、字母、下划线 长度为6-30
var reg = /^[a-zA-Z]\w{5,29}$/g;
//手机号码
var reg = /^1[34578]\d{9}$/g;
//匹配日期 yyyy-mm-dd
var reg = /^[0-9]{4}-(0[1-9]|1[1-2])-(0[1-9]|[12][1-9]|3[01])$/g;
//匹配qq号
var reg = /^[1-9][0-9]{4,10}$/g;
十八、json
JSON.stringify() 传入一个json格式的数据结构,将其转换为一个json字符串
JSON.parse() 将json字符串转换为js数据结构
十九、将类数组转为数组
Array.prototype.slice.call(arguments);
Array.prototype.splice.call(arguments, 0);
Array.prototype.concat.apply([], arguments);
Array.from(arguments);
例如:要想arguments使用数组的forEach方法:
//法一
function foo() {
Array.prototype.forEach.call(arguments, a => console.log(a));
}
//法二
function foo() {
let arr = Array.from(arguments);
arr.forEach(a => console.log(a));
}
//法三
function foo() {
let arr = [...arguments];
arr.forEach(a => console.log(a));
}
二十、常见位运算符
&(与)|(或)^(异或)~(非)<<(左移) >>(右移)
二十一、ajax请求
let xhr = new XMLHttpRequest();
xhr.open('GET', '/url', true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
} else {
alert(xhr.statusText);
}
}
//请求成功回调函数
xhr.onload = e => {
console.log('request success');
}
//请求结束
xhr.onloadend = e => {
console.log('request loadend');
}
//请求出错
xhr.onerror = e => {
console.log('request error');
}
//请求超时
xhr.ontimeout = e => {
console.log('request timeout');
}
//设置超时时间 0表示永不超时
xhr.timeout = 0;
//初始化请求
xhr.open('GET/POST/DELETE/...', 'URL', true || false);
//设置期望返回的数据类型'json' 'text' 'document'...
xhr.responseType = '';
//设置请求头
xhr.setRequestHeader('', '');
//发动请求
xhr.send(null || new FormData || 'a=1&b=2' || 'json字符串');
用promise封装一下:
总结
面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。
还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。
万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
前端面试题汇总
JavaScript
前端资料汇总