前端工程师面试知识库:JavaScript相关
JavaScript相关
1 ["1", "2", "3"].map(parseInt)
首先, map接受两个参数, 一个回调函数 callback, 一个回调函数的this值
其中回调函数接受三个参数 currentValue, index, arrary;
而题目中, map只传入了回调函数--parseInt.
其次, parseInt 只接受两个两个参数 string, radix(基数).
本题理解来说也就是key与 index
所以本题即问
parseInt('1', 0);
parseInt('2', 1);
parseInt('3', 2);
parseInt(string, radix)
string 必需。要被解析的字符串。
radix 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。
如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。
复制代码
2 [[3,2,1].reduce(Math.pow), [].reduce(Math.pow)]
arr.reduce(callback[, initialValue])
reduce接受两个参数, 一个回调, 一个初始值.
回调函数接受四个参数 previousValue, currentValue, currentIndex, array
需要注意的是 If the array is empty and no initialValue was provided, TypeError would be thrown.
所以第二个表达式会报异常. 第一个表达式等价于 Math.pow(3, 2) => 9; Math.pow(9, 1) =>9
复制代码
3
var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
我们看到在迭代这个数组的时候, 首先检查了这个索引值是不是数组的一个属性, 那么我们测试一下.
0 in ary; => true
3 in ary; => false
10 in ary; => true
也就是说 从 3 - 9 都是没有初始化的bug !, 这些索引并不存在与数组中. 在 array 的函数调用的时候是会跳过这些坑的.
复制代码
4 [typeof null, null instanceof Object]
typeof 返回一个表示类型的字符串.
instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上.
type result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol "symbol"
Host object Implementation-dependent
Function "function"
Object "object"
复制代码
5 js数据类型
1.number;
2.string;
3.boolean;
4.undefined;
5.null;
6.symbol(ES6新增,文章后面有对着新类型的解释)Symbol 生成一个全局唯一的值。
7.Object.(包括Object,Array,Function)
6 promise 用法
定义
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
使用
promise.then(function(value) {
// success
}, function(error) {
// failure
});
//等价于:
promise.then(function(){
//success
}).catch(function(){
//failure
})
复制代码
7 es6 promise ajax
定义
const myHttpClient = url => {
return new Promise((resolve, reject) => {
let client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function handler() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
}
});
};
使用
myHttpClient('https://www.baidu.com').then(res => {
console.log(res);
}).catch(error => {
console.log(error);
});
复制代码
8闭包
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 现在是一个闭包
bar(10);
结果是16
es6通常用let const块级作用域代替,
闭包缺点,ie中会引起内存泄漏,严格来说是ie的缺点不是闭包的问题
复制代码
9 什么是立即执行函数?使用立即执行函数的目的是什么?
常见两种方式
1.(function(){...})()
(function(x){
console.log(x);
})(12345)
2.(function(){...}())
(function(x){
console.log(x);
}(12345))
作用 不破坏污染全局的命名空间,若需要使用,将其用变量传入如
(function(window){...}(window))
复制代码
10 async/await 语法
作用:异步代码的新方式
promise示例
const makeRequest = () => {
return getJSON()
.then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data)
.then(moreData => {
console.log(moreData)
return moreData
})
} else {
console.log(data)
return data
}
})
}
async/await示例
const makeRequest = async () => {
const data = await getJSON()
if (data.needsAnotherRequest) {
const moreData = await makeAnotherRequest(data);
console.log(moreData)
return moreData
} else {
console.log(data)
return data
}
}
函数前面多了一个aync关键字。await关键字只能用在aync定义的函数内。async函数会隐式地返回一个promise,该promise的reosolve值就是函数return的值。(示例中reosolve值就是字符串"done")
复制代码
11 深浅拷贝
let a = {
aa: 1,
bb: 2,
cc: 3,
dd: {
ee: 5,
},
ff: {
gg: 6,
}
};
let d = JSON.parse(JSON.stringify(a));//深复制包含子对象
let c = {...a};//拷贝一层但不包含子对象
let b = a;//浅拷贝
b.bb = 22;
c.cc = 33;
c.dd.ee = 55;
d.ff.gg = 66;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
复制代码
12数组去重
思路1:定义一个新数组,并存放原数组的第一个元素,然后将元素组一一和新数组的元素对比,若不同则存放在新数组中
思路2:先将原数组排序,在与相邻的进行比较,如果不同则存入新数组。
思路3:利用对象属性存在的特性,如果没有该属性则存入新数组。
思路4(最常用):使用es6 set
let arr= [1, 2, 3, 3, 5, 7, 2, 6, 8];
console.log([...new Set(arr)]);
复制代码
13正则实现trim()功能
function myTrim(str) {
let reg = /^\s+|\s+$/g;
return str.replace(reg, "");
}
console.log(myTrim(' asdf '));
复制代码
14 JS原型
1.每个对象都有 __proto__ 属性,但只有函数对象才有 prototype 属性
2.个人粗略理解与python的类方法静态方法实例方法差不多
复制代码
#####15 es6 class
面向对象,java中类
复制代码
16 JS 如何实现继承
1.使用原型继承(既继承了父类的模板,又继承了父类的原型对象。优点是继承了父类的模板,又继承了父类的原型对象,缺点就是父类实例传参,不是子类实例化传参,不符合常规语言的写法)
2.使用call的方式(继承了父类的模板,不继承了父类的原型对象。优点是方便了子类实例传参,缺点就是不继承了父类的原型对象)
复制代码
17 手写jquery插件
(function ($) {
$.fn.myPlugins = function (options) {
//参数赋值
options = $.extend(defaults, options);//对象合并
this.each(function () {
//执行代码逻辑
});
};
})(jQuery);
$(selector).myPlugins({参数});
复制代码
18 数组合并去重排序
let arr1 = [1, 25, 2, 26, 1234, 6, 213];
let arr2 = [2, 6, 2134, 6, 31, 623];
let c = [...new Set([...arr1, ...arr2])].sort((a, b) => {
return a - b;
});
复制代码
19 call apply
作用:在函数调用时改变函数的执行上下文也就是this的值 区别:call采用不定长的参数列表,而apply使用一个参数数组。 性能优化图
20 for 中setTimeOut
要为循环题创建不同的循环副本
21 sort函数
V8 引擎 sort 函数只给出了两种排序 InsertionSort 和 QuickSort,数量小于10的数组使用 插入,比10大的数组则使用 快排。
22 navigator
23 jquery绑定方式
- click后者覆盖
- bind后者覆盖
- on(jquery>=1.7)
- live
- delegate
24 事件流向
- 冒泡:子节点一层层冒泡到根节点
- 捕获顺序与冒泡相反
- addEventListener最后个参数true代表捕获反之代表冒泡
- 阻止冒泡不停止父节点捕获
25原生操作class
//判断有无
function hasClass(ele, cls) {
return ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
}
//添加
function addClass(ele, cls) {
if (!this.hasClass(ele, cls)) ele.className += " " + cls;
}
//删除
function removeClass(ele, cls) {
if (hasClass(ele, cls)) {
let reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
ele.className = ele.className.replace(reg, " ");
}
}
html5中加入classList
一系列操作
兼容至IE10
作者:信心
链接:https://juejin.im/post/5b94d8965188255c5a0cdc02
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
THE END