和15岁女儿做很舒服网站,郑州seo优化外包热狗网,上海房产网二手房出售,临沂网站开发技术员文章来源于公众号#xff1a;猴哥说前端 作者#xff1a;monkeysoft 本文给大家分享一些 JavaScript 面试经验#xff0c;在这金九银十的招聘季#xff0c;希望大家都能找到满意的工作。 JavaScript的数据类型都有什么#xff1f;
基本数据类型#xff1a;String,Boolea… 文章来源于公众号猴哥说前端 作者monkeysoft 本文给大家分享一些 JavaScript 面试经验在这金九银十的招聘季希望大家都能找到满意的工作。 JavaScript的数据类型都有什么
基本数据类型String,Boolean,Number,Undefined,Null
引用数据类型Object(Array,Date,RegExp,Function) javascript中和的区别是什么
会自动进行类型转换不会 例举3种强制类型转换和2种隐式类型转换?
强制parseInt,parseFloat,Number()
隐式 1”1”//true
nullundefined//true 原生 JS 中 call()、apply()、bind() 方法有什么区别
三个方法都可以改变函数运行时的 this 指向。
三个方法第一个参数都是函数调用执行时this 指向的对象。 call() 方法第二个参数是个可变参数是函数调用执行时本身所需要的参数。 apply() 方法第二个参数是数组或arguments。call()与apply()都是立即调用函数执行在运行时修改this指向。 bind()是返回一个新的函数新函数的函数主体与原函数的函数主体一致当新函数被调用时函数体中 this 指向的是 bind() 方法第一个参数传递的对象而bind() 方法不会影响原函数本身的 this 指向。 什么是闭包特点是
闭包官方对闭包的解释是一个拥有许多变量和绑定了这些变量的环境的表达式通常是一个函数因而这些变量也是该表达式的一部分。
闭包的特点
1作为一个函数变量的一个引用当函数返回时其处于激活状态。
2 一个闭包就是当一个函数返回时一个没有释放资源的栈区。
简单的说JavaScript 允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时就会形成闭包。 事件委托是什么
符合W3C标准的事件绑定 addEventLisntener /attachEvent
让利用事件冒泡的原理让自己的所触发的事件让他的父元素代替执行 如何阻止事件冒泡和默认事件
e. stopPropagation();//标准浏览器
event.canceBubbletrue;//ie9之前
阻止默认事件
为了不让a点击之后跳转我们就要给他的点击事件进行阻止
return false
e.preventDefault(); document load 和document ready的区别
Document.onload 是在结构和样式加载完才执行js
window.onload不仅仅要在结构和样式加载完还要执行完所有的样式、图片这些资源文件全部加载完才会触发window.onload事件
Document.ready原生种没有这个方法jquery中有 $().ready(function) 为了保证页面输出安全我们经常需要对一些特殊的字符进行转义请写一个函数escapeHtml将, , “进行转义 return str.replace(/[”]/g, function(match) {switch (match) {case “”:return “”;case “”:return “”;case “\””:return “”;}});
} 简述创建函数的几种方式
第一种函数声明function sum1(num1,num2){ return num1num2; }
第二种函数表达式var sum2 function(num1,num2){ return num1num2; }
第三种函数对象方式var sum3 new Function(num1,num2,return num1num2); 把 Script 标签 放在页面的最底部的body封闭之前 和封闭之后有什么区别浏览器会如何解析它们
如果说放在body的封闭之前将会阻塞其他资源的加载
如果放在body封闭之后不会影响body内元素的加载 iframe的优缺点
优点 解决加载缓慢的第三方内容如图标和广告等的加载问题Security sandbox并行加载脚本
缺点 iframe会阻塞主页面的Onload事件即时内容为空加载也需要时间没有语意 Javascript如何实现继承
原型链继承借用构造函数继承组合继承寄生式继承寄生组合继承 请你谈谈Cookie的弊端
缺点
1.Cookie 数量和长度的限制。部分浏览器每个 domain 最多只能有50条 cookie基本所有浏览器中每个 cookie 长度不能超过4KB否则会被截掉。
2.安全性问题。如果 cookie 被人拦截了那人就可以取得所有的 session 信息。即使加密也与事无补因为拦截者并不需要知道 cookie 的意义他只要原样转发 cookie 就可以达到目的了。
3.有些状态不可能保存在客户端。例如为了防止重复提交表单我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端那么它起不到任何作用。
4.占用网络上传带宽。每次请求服务器资源时都会携带 cookie 信息向服务器传递。 DOM操作——怎样添加、移除、移动、复制、创建和查找节点? 创建新节点 createDocumentFragment() // 创建一个DOM片段createElement() // 创建一个具体的元素createTextNode() // 创建一个文本节点 添加、移除、替换、插入 appendChild()removeChild()replaceChild()insertBefore() // 在已有的子节点前插入一个新的子节点 查找 getElementsByTagName() // 通过标签名称getElementsByName() // 通过元素的Name属性的值(IE容错能力较强会得到一个数组其中包括id等于name值的)getElementById() // 通过元素Id唯一性 js延迟加载的方式有哪些 defer和async动态创建DOM方式创建script插入到DOM中加载完毕后callBack按需异步载入js documen.write和 innerHTML 的区别
document.write 只能重绘整个页面
innerHTML 可以重绘页面的一部分 哪些操作会造成内存泄漏
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。垃圾回收器定期扫描对象并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0没有其他对象引用过该对象或对该对象的惟一引用是循环的那么该对象的内存即可回收。 setTimeout 的第一个参数使用字符串而非函数的话会引发内存泄漏。闭包控制台日志循环在两个对象彼此引用且彼此保留时就会产生一个循环 判断一个字符串中出现次数最多的字符统计这个次数? var str asdfssaaasasasasaa;
var json {};
for (var i 0; i str.length; i) {if(!json[str.charAt(i)]){json[str.charAt(i)] 1;}else{json[str.charAt(i)];}
};
var iMax 0;
var iIndex ;
for(var i in json){if(json[i]iMax){iMax json[i];iIndex i;}
}
alert(出现次数最多的是:iIndex出现iMax次); 数组扁平化
数组扁平化是指将一个多维数组变为一个一维数组 const arr [1, [2, [3, [4, 5]]], 6];
// [1, 2, 3, 4, 5, 6] 方法一使用flat() const res1 arr.flat(Infinity); 方法二利用正则 const res2 JSON.stringify(arr).replace(/\[|\]/g, ).split(,); 但数据类型都会变为字符串 方法三正则改良版本 const res3 JSON.parse([ JSON.stringify(arr).replace(/\[|\]/g, ) ]); 方法四使用reduce const flatten arr {return arr.reduce((pre, cur) {return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);}, [])
}
const res4 flatten(arr); 方法五函数递归 const res5 [];
const fn arr {for (let i 0; i arr.length; i) {if (Array.isArray(arr[i])) {fn(arr[i]);} else {res5.push(arr[i]);}}
}
fn(arr); 数组去重 const arr [1, 1, 1, 17, true, true, false, false, true, a, {}, {}];
// [1, 1, 17, true, false, true, a, {}, {}] 方法一利用Set const res1 Array.from(new Set(arr)); 方法二两层for循环splice const unique1 arr {let len arr.length;for (let i 0; i len; i) {for (let j i 1; j len; j) {if (arr[i] arr[j]) {arr.splice(j, 1);// 每删除一个树j--保证j的值经过自加后不变。同时len--减少循环次数提升性能len--;j--;}}}return arr;
} 方法三利用indexOf const unique2 arr {const res [];for (let i 0; i arr.length; i) {if (res.indexOf(arr[i]) -1) res.push(arr[i]);}return res;
} 方法四利用include const unique3 arr {const res [];for (let i 0; i arr.length; i) {if (!res.includes(arr[i])) res.push(arr[i]);}return res;
} 方法五利用filter const unique4 arr {return arr.filter((item, index) {return arr.indexOf(item) index;});
} 方法六利用Map const unique5 arr {const map new Map();const res [];for (let i 0; i arr.length; i) {if (!map.has(arr[i])) {map.set(arr[i], true)res.push(arr[i]);}}return res;
} 类数组转化为数组
类数组是具有length属性但不具有数组原型上的方法。常见的类数组有arguments、DOM操作方法返回的结果。 方法一Array.from Array.from(document.querySelectorAll(div)) 方法二Array.prototype.slice.call() Array.prototype.slice.call(document.querySelectorAll(div)) 方法三扩展运算符 [...document.querySelectorAll(div)] 方法四利用concat Array.prototype.concat.apply([], document.querySelectorAll(div)); debounce防抖
触发高频时间后n秒内函数只会执行一次,如果n秒内高频时间再次触发,则重新计算时间。 const debounce (fn, time) {let timeout null;return function() {clearTimeout(timeout)timeout setTimeout(() {fn.apply(this, arguments);}, time);}
};
防抖常应用于用户进行搜索输入节约请求资源window触发resize事件时进行防抖只触发一次。 throttle节流
高频时间触发,但n秒内只会执行一次,所以节流会稀释函数的执行频率。 const throttle (fn, time) {let flag true;return function() {if (!flag) return;flag false;setTimeout(() {fn.apply(this, arguments);flag true;}, time);}
}
节流常应用于鼠标不断点击触发、监听滚动事件。 函数珂里化 指的是将一个接受多个参数的函数 变为 接受一个参数返回一个函数的固定形式这样便于再次调用例如f(1)(2) 经典面试题实现add(1)(2)(3)(4)10; 、 add(1)(1,2,3)(2)9; function add() {const _args [...arguments];function fn() {_args.push(...arguments);return fn;}fn.toString function() {return _args.reduce((sum, cur) sum cur);}return fn;
} 深拷贝
递归的完整版本考虑到了Symbol属性 const cloneDeep1 (target, hash new WeakMap()) {// 对于传入参数处理if (typeof target ! object || target null) {return target;}// 哈希表中存在直接返回if (hash.has(target)) return hash.get(target);const cloneTarget Array.isArray(target) ? [] : {};hash.set(target, cloneTarget);// 针对Symbol属性const symKeys Object.getOwnPropertySymbols(target);if (symKeys.length) {symKeys.forEach(symKey {if (typeof target[symKey] object target[symKey] ! null) {cloneTarget[symKey] cloneDeep1(target[symKey]);} else {cloneTarget[symKey] target[symKey];}})}for (const i in target) {if (Object.prototype.hasOwnProperty.call(target, i)) {cloneTarget[i] typeof target[i] object target[i] ! null? cloneDeep1(target[i], hash): target[i];}}return cloneTarget;
}