目录
3、两个数组 var A = [1, 5, 6]; var B = [2, 6, 7],实现一个方
4、 你了解构造函数吗 ? class 是什么 ? 两者有什么区别 ?
5、for (var i = 0; i < 5; i++) { setTimeout(function() {
console.log(i); }, 1000); } 要求:输出0,1,2,3,4
7、 JS 的数据类型有哪些 ? 如何判断数据类型 ?他们的优缺点是什么?
- document.getElementById('id名')
- document.getElementsByTagName('标签名')
- document.getElementsByName('name属性值')
- document.querySelector('css选择器')
- document.querySelectorAll('css选择器')
// 当有文档声明的时候document.documentElement.scrollTopdocument.documentElement.srollLeft// 没有文档声明的时候document.body.scrollTopdocument.body.scrollLeft
解决办法使用兼容写法:
- // 获取
- var t = document.documentElement.scrollTop || document.body.scrollTop
- var l = document.documentElement.srollLeft || document.body.scrollLeft
- // 设置
- document.documentElement.scrollTop = document.body.scrollTop = 数值
- document.documentElement.srollLeft = document.body.scrollLeft = 数值
// W3C 标准浏览器window.getComputedStyle( 元素 )// 低版本 IE 中元素 .currentStyle
使用函数封装的方式兼容:
function getStyle(ele,attr){if (window.getComputedStyle){return getComputedStyle(ele)[attr]}else{return ele.currentStyle[attr]}}
// W3C 浏览器ele.addEventListener( 事件类型 , 函数 )// 低版本 Ieele.attachEvent( 'on 事件类型 ' , 函数 )
使用函数封装的方式解决:
- function bindEvent(ele,type,handler){
- if(ele.addEventListener){
- ele.addEventListener(type,handler)
- }else if(ele.attachEvent){
- ele.attachEvent('on'+type,handler)
- }else{
- ele['on'+type] = handler
- }
- }
// W3C 浏览器ele.removeEventListener( 事件类型 , 函数 )// 低版本 Ieele.detachEvent( 'on 事件类型 ' , 函数 )
使用函数封装的方式解决:
- function unBind(ele,type,handler){
- if(ele.removeEventListener){
- ele.removeEventListener(type,handler)
- }else if(ele.detachEvent){
- ele.detachEvent('on'+type,handler)
- }else{
- ele['on'+type] = null
- }
- }
// W3C 浏览器元素 .on 事件类型 = function (e){}元素 .addEventListener( 事件类型 ,fn)function fn(e){}// 在低版本 IE 中元素 .on 事件类型 = function (){ window.event }元素 .addEventListener( 事件类型 ,fn)function fn(){window.event}
使用短路运算符解决:
- 元素.on事件类型 = function(e){
- var e = e || window.event
- }
- 元素.addEventListener(事件类型,fn)
- function fn(e){
- var e = e || window.event
- }
// W3C 浏览器元素 .on 事件类型 = function (e){e.preventDefault()}// 在低版本 IE 中元素 .on 事件类型 = function (){ window.event.returnValue = false }
通过封装函数解决:
- 元素.on事件类型 = function(e){
- var e = e || window.event
- e.preventDefault?e.preventDefault():e.returnValue=false
- }
// W3C 浏览器元素 .on 事件类型 = function (e){e.stopPropagation()}// 在低版本 IE 中元素 .on 事件类型 = function (){ window.event.cancelBubble = true }
通过函数封装解决:
- 元素.on事件类型 = function(e){
- var e = e || window.event
- e.stopPropagation?e.stopPropagation():e.cancelBubble=true
- }
// W3C 浏览器元素 .on 事件类型 = function (e){e.target}// 在低版本 IE 中元素 .on 事件类型 = function (){ window.event.srcElement }
通过短路运算符解决:
- 元素.on事件类型 = function(e){
- var e = e || window.event
- var target = e.target || e.srcElement;
- }
// W3C 浏览器元素 .on 事件类型 = function (e){e.keyCode}// 在低版本火狐中元素 .on 事件类型 = function (e){e.which}
通过短路运算符解决:
- 元素.on事件类型 = function(e){
- var e = e || window.event
- var keycode = e.keyCode || e.which;
- }
事件对象 .stopPropagation()
在ie低版本浏览器中,使用事件对象的属性阻止:
现在的 w3c 浏览器也支持 ie 低版本浏览器中的写法,所以以前在阻止事件冒泡的时候,需要考虑兼容写法,现在就不需要了,直接用ie 低版本浏览器中的写法即可
- function getDiff(arr, brr){
- // 仅存在于arr中的内容
- var onlyArr = arr.filter(item => !brr.some(v => item === v))
- // 仅存在于brr中的内容
- var onlyBrr = brr.filter(v => !arr.some(item => v === item))
- // 需要哪个就返回哪个,或者一起返回
- return {
- "仅存在于arr中的内容": onlyArr,
- "仅存在于brr中的内容": onlyBrr
- }
- }
在 es5 中构造函数其实就是在定义一个类,可以实例化对象, es6 中 class 其实是构造函数的语法糖。但还是有点区别的:
首先这个面试题考察的是对于 js 中异步代码以及作用域的理解:js 中常见的异步代码包括定时器和 ajax 。 js 执行代码的流程是碰到同步代码就执行,碰到异步就交给浏览器的webAPI处理,当 webAPI 中的异步该执行时, webAPI 会将需要执行的回调函数放在任务队列中,等候执行,所以, js中所有的异步代码总会在所有同步代码执行结束后,再执行任务队列中的代码。在这个问题中,循环是同步代码,定时器是异步代码,所以整个循环都执行结束以后才会执行定时器代码。for 循环中使用 var 定义的变量是全局变量,定时器回调函数中输出变量的时候,根据作用域规则,先在当前作用域中变量i 的定义表达式,如果没有找到,就去上一级作用域中找,此时,在局部作用域中没有找到,去上级作用域中,也就是全局找到了,全局中的i ,因为循环已经执行结束了,所以 i 的值是 5 。最终,会输出 5 个 5 。其次考察的是对于类似问题的解决方式,间接性判断你是否有过类似情况的开发:这个问题的解决思路就是让回调函数中输出 i 的时候,不要去全局中找 i ,因为全局的 i 在循环执行结束后已经变成 5了,根据这个思路,有2 种解决办法:
1.在异步代码外面嵌套一层函数作用域:
- for(var i = 0;i < 5; i++){
- (function(i) {
- setTimeout(function() {
- console.log(i)
- }, 1000)
- })(i)
- }
- for(let i = 0;i < 5; i++){
- setTimeout(function() {
- console.log(i)
- }, 1000)
- }
常见的有5种,分别是GET、HEAD, POST、PUT、 DELETEGET :它是最常见的方法,用于获取资源,常用于向服务器查询某些信息。打开网页一般都是用GET方法,因为要从 Web 服务器获取信息HEAD :类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头。POST :向指定资源提交数据进行处理请求(例如提交表单或者上传文件), 数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或对已有资源的修改。PUT :从客户端向服务器传送的数据取代指定文档的内容。DELETE :请求服务器删除指定的页面。最常见的HTTP请求方法是GET 和 POST。GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。GET和POST的区别:GET 提交的数据会放在 ? 之后,以问号(?)分割 URL 和传输数据,参数之间以&相连GET 提交的数据大小有限制(因为浏览器对 URL 的长度有限制), 而 POST 方法提交的数据大小没有限制。GET 方式提交数据会带来安全问题,比如一个登录页面通过 GET 方式提交数据时,用户名和密码将出现在URL 上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码
检测的不管是数组还是正则都返回的是 "object", 所以 typeof 不能判断一个值是否为数组
instanceof/constructor。检测某一个实例是否属于某一个类使用instanceof/constructor可以检测数组和正则
用 instanceof 检测的时候 , 只要当前的这个类在实例的原型链上 ( 可以通过 原型链__proto__ 找到它 ), 检测出来的结果都是true 。基本数据类型 的值是不能用 instanceof 来检测的在 类的原型继承 中 ,instanceof 检测出来的结果其实是 不准确的
Object.prototype.toString.call(value) ->找到Object原型上的toString方法,让方法执行,并且让方法中的this变为value(value->就是我们要检测数据类型的值)。检测的类型比较多,也比较精准。
concat() 连接两个或更多的数组,并返回结果。join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。pop() 删除并返回数组的最后一个元素。shift() 删除并返回数组的第一个元素push() 向数组的末尾添加一个或更多元素,并返回新的长度。unshift() 向数组的开头添加一个或更多元素,并返回新的长度。reverse() 颠倒数组中元素的顺序。slice() 从某个已有的数组返回选定的元素sort() 对数组的元素进行排序splice() 删除元素,并向数组添加新元素。toSource() 返回该对象的源代码。toString() 把数组转换为字符串,并返回结果。toLocaleString() 把数组转换为本地数组,并返回结果。valueOf() 返回数组对象的原始值
基本语法是 document.cookie = '键名=键值;expires=时间对象;path=路径' ;时效 如果不设定 默认是 seeion 会话时效路径 如果不设定 默认是 当前文件所在文件夹设定时效 要 设定一个时间对象 时间对象的时间戳 就是 时效期要注意计算 当前时区 和 世界标砖时间的时间差路径一般设定为根目录 也就是 '/'
- // 普通的add函数
- function add(x, y) {
- return x + y
- }
-
- // Currying后
- function curryingAdd(x) {
- return function (y) {
- return x + y
- }
- }
-
- add(1, 2) // 3
- curryingAdd(1)(2) // 3
优点:
1 , 参数复用例如 一个函数 有两个参数 但是第一个参数会被反复使用 每次都需要输入 一个重复的参数使用柯里化函数之后 只需要 输入一个参数就可以了2 , 提前确认提前定义好一个参数 也就 决定了整个函数程序的执行方向 避免每次都执行判断比较等
缺点:
只能提前定义一个参数 如果想要提前定义多个参数 这样的语法是不支持
柯里化函数执行效能上的问题:
存取 arguments 对象通常要比存取命名参数要慢一点一些老版本的浏览器在 arguments.length 的实现上是相当慢的使用 函数 .apply() 和 函数 .call() 通常比直接调用 fn() 稍微慢点创建大量嵌套作用域和闭包函数会带来花销,无论是在内存还是速度上