一、算法题部分
1. 如何获取浏览器URL中查询字符串中的参数
function getParamsWithUrl(url) {
var args = url.split('?');
if (args[0] === url) {
return "";
}
var arr = args[1].split('&');
var obj = {};
for ( var i = 0;
i < arr.length; i++)
{
var arg = arr[i].split('=');
obj[arg[0]] = arg[1];
}
return obj;
}
var href = getParamsWithUrl
('http://www.itlike.com?id=1022&name=撩课&age=1');
console.log(href['name']); // 撩课
2. 写一个深度克隆方法(es5)?
/**
* 深拷贝
* @param {object}fromObj 拷贝的对象
* @param {object}toObj 目标对象
*/
function deepCopyObj2NewObj(fromObj, toObj) {
for(var key in fromObj){
// 1. 取出键值对
var fromValue = fromObj[key];
// 2. 检查当前的属性值是什么类型
// 如果是值类型,那么就直接拷贝赋值
if(!isObj(fromValue)){
toObj[key] = fromValue;
}else {
// 如果是引用类型,
// 那么就再调用一次这个方法,
// 去内部拷贝这个对象的所有属性
var tempObj =
new fromValue.constructor;
console.log(fromValue.constructor);
deepCopyObj2NewObj(fromValue, tempObj);
toObj[key] = tempObj;
}
}
}
/**
* 辅助函数, 判断是否是对象
* @param {object}obj
* @returns {boolean}
*/
function isObj(obj) {
return obj instanceof Object;
}
3. 对数组[1,2,3,8,2,8]进行去重,es5或者es6方法?
es5四种方式:
方式一:
Array.prototype.unique1 = function() {
// 1. 定义数组
var temp = [];
// 2. 遍历当前数组
for(var i = 0;
i < this.length; i++) {
// 3.如果当前数组的第i
// 已经保存进了临时数组,
// 那么跳过,否则把当前项
// push到临时数组里面
if (-1 === temp.indexOf(this[i]))
{
temp.push(this[i]);
}
}
return temp;
};
方式二:
Array.prototype.unique2 = function() {
//1. hash为hash表,r为临时数组
var hash = {}, temp=[];
// 2.遍历当前数组
for(var i = 0; i < this.length; i++)
{
// 3. 如果hash表中没有当前项
if (!hash[this[i]])
{
// 4.存入hash表
hash[this[i]] = true;
// 5.把当前数组的当前项
// push到临时数组里面
temp.push(this[i]);
}
}
return temp;
};
方式三:
Array.prototype.unique3 = function() {
var n = [this[0]];
for(var i = 1;
i < this.length; i++){
if (this.indexOf(this[i]) === i) {
n.push(this[i]);
}
}
return n;
};
方式四:
Array.prototype.unique4 = function() {
this.sort();
var re=[this[0]];
for(var i = 1;
i < this.length; i++) {
if( this[i] !== re[re.length-1]){
re.push(this[i]);
}
}
return re;
};
es6实现方式:
Array.prototype.unique =
Array.prototype.unique ||
() =>{
return [...new Set(this)];
};
4. 如何判断一个对象是否为数组?
function isArray(arg) {
if (typeof arg === 'object') {
return
Object.prototype.toString.call(arg)
=== '[object Array]';
}
return false;
}
5. 冒泡排序?
思路:
每次比较相邻的两个数,
如果后一个比前一个小,换位置;
var arr = [2, 0, 1, 9, 8, 7, 3];
function bubbleSort(arr) {
for (var i = 0;
i < arr.length - 1; i++) {
for(var j = 0;
j < arr.l i - 1; j++) {
if(arr[j + 1] < arr[j]) {
var temp;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
console.log(bubbleSort(arr));
6. 快速排序?
思路: 采用二分法,取出中间数,
数组每次和中间数比较,
小的放到左边,大的放到右边;
var arr = [2, 0, 1, 9, 8, 7, 3];
function quickSort(arr) {
if(arr.length == 0) {
// 返回空数组
return [];
}
var cIndex = Math.floor(arr.length / 2);
var c = arr.splice(cIndex, 1);
var l = [];
var r = [];
for (var i = 0;
i < arr.length;
i++) {
if(arr[i] < c) {
l.push(arr[i]);
} else {
r.push(arr[i]);
}
}
return quickSort(l).concat(c, quickSort(r));
}
console.log(quickSort(arr));
7. 正则表达式验证邮箱格式?
var reg = /^(\w)+(\.\w+)*@(\w)+((\.\w{2,3}){1,3})$/;
var email = "[email protected]";
console.log(reg.test(email)); // true
8. 正则表达式清除字符串前后的空格?
function trim(str) {
if (str && typeof str === "string")
{
// 去除前后空白符
return
str.replace(/(^\s*)|(\s*)$/g,"");
}
}
------------------------------------------------------------------华丽分割线--------------------------------------------------------------------
二、JS系列部分
1. var的变量提升的底层原理是什么?
JS引擎的工作方式是:
1) 先解析代码,获取所有被声明的变量;
2) 然后在运行。也就是说分为预处理和执行两个阶段。
补充:
变量提升:所有变量的声明语句都会被提升到代码头部。
但是变量提升只对var命令声明的变量有效,如果一个变量不是
用var命令声明的,就不会发生变量提升。
js里的function也可看做变量,也存在变量提升情况。
2. JS如何计算浏览器的渲染时间?
浏览器的渲染过程主要包括以下几步:
1) 解析HTML生成DOM树。
2) 解析CSS生成CSSOM规则树。
3) 将DOM树与CSSOM规则树合并在一起生成渲染树。
4) 遍历渲染树开始布局,计算每个节点的位置大小信息。
5) 将渲染树每个节点绘制到屏幕。
优化考虑:
CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。
JS置后:通常把JS代码放到页面底部,且JavaScript 应尽量少影响 DOM 的构建。
3. JS的回收机制?
垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,
并释放掉它们所指向的内存; 主要为了以防内存泄漏,
(内存泄漏: 当已经不需要某块内存时这块内存还存在着),
JS有两种变量: 全局变量和在函数中产生的局部变量。
局部变量的生命周