Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

面试总结 #10

Open
hrpc opened this issue May 7, 2018 · 1 comment
Open

面试总结 #10

hrpc opened this issue May 7, 2018 · 1 comment

Comments

@hrpc
Copy link
Owner

hrpc commented May 7, 2018

1:vue虚拟DOM实现

2:flex布局的flex属性的三个值分别是什么意思

   flex:1;//flex:1 1 0%
   flex-grow: 0 默认值为0表示有剩余空间也不放大
   flex-shrink: 1默认值为1表示空间不足时将缩小
   flex-basis: auto 默认值为auto,表示在分配剩余空间前,项目占据的主轴空间.

3:vue子组件传值

4:this指向问题

5:vue数据绑定原理+

6:const a = {x:1} a.x = 2 //?能修改吗 为什么
能 const指向的引用不能修改,但是其对象的值能修改

7:外边距折叠
上下两个块元素,上面的有margin-bottom,下面的有margin-top时候的margin取值问题
7.1:两个都为正值 则取两个值中的最大值
7.2:两个都为负值 则取两个值中的最小值
7.3:一正一负 则取两数相加的和

8:history api
浏览器用来保存浏览历史的一个对象
以下api用来在浏览器历史之间移动

back()//移动到上一个访问页面,相当于浏览器的回退按钮
forward()//移动到下一个访问页面,相当于浏览器的前进按钮
go()//接受一个整数作为参数,移动到该整数指定的页面,go(1)就相当于forward()

以下api用来操作浏览器浏览历史
pushState 想浏览器历史中添加记录,接受三个参数
state,一个与指定网址相关的状态对象,在popstate事件触发时,该对象作为回调函数的参数传入
title,新页面的标题,目前所有浏览器都忽略这个值,可传null
url,新的网址,必须与当前页面处在同一个域,浏览器地址栏将显示这个网址
调用这个方法并正确的传入参数后,浏览器地址栏将变化为传入的地址,但是并不会跳转到指定页面,甚至不会检查这个页面是否存在,也就是没有404页面,她只是成为浏览器历史记录中最新的一条.点击浏览器回退按钮将会跳转到调用该方法之前的页面,
总之,pushState并不会触发页面刷新,只是导致history对象发生变化,地址栏会体现出来

1:自己写解析url参数的方法

2:css画三角形

.div{
width:0;
height:0
border-bottom:50px solid red;
border-left:50px solid transparent;
border-right:50px solid transprent;
}

3:两列布局,左边定宽高,右边自适应
容器flex
自适应的flex设置为1

4:typeof 能确定的数据类型,如何确定array

5:垂直居中的几种方法
1:transform:translate(-50%)

 .parent{
position:relative
}
.children{
position:absolute;
top:50%;
tranform:translate(-50%)
}

2:flex
3:table
结构
image
样式
image
即要设置两层容器包裹所要垂直居中的元素,最外层display设置为table,第二层display设置为table-cell,并将样式的vertical-align设置为middle,就能实现目标元素垂直居中

6:JavaScript实现数据劫持

const obj = {
name:"zhangsan"
}
Object.object.defineproperty(obj,'name',{
  set:function(newVal){
    name = newVal
    console.log("name更新!")
    //name值更新时的其他操作
    //其他业务代码
  }
})
obj.name = "wangwu"

一般问到这个问题的场景有:
6.1: vue的双向绑定原理,核心方法就是用的Object.defineproperty方法
6.2:当我业务中更新了一个对象的属性,此时想要带起其他操作的时候也要用到这个方法

7:数组去重最简单的方法

const array = [1,2,3,45,1,2,3]
console.log([...new Set(array)])

8:解释一下原型链是什么

9:解释一下null和undefinded的区别
引用阮一峰大神的总结:

null表示"没有对象",即该处不应该有值
典型用法就是
1:作为函数的参数,表示参数值不是对象
2:作为原型链的终点

undefined表示"缺少值",就是此处应该有一个值,但是还没有定义
典型用法是
1:变量被声明了,但是还没有被赋值,此时值为undefined
2:调用函数时,本应该传的参数没有传,此时值为undefined
3:对象没有赋值的属性,此时为undefined
4:函数没有返回值时,默认返回undefined

tips:undefined在参与数值运算是会自动转为NaN,如5 + undefined //NaN
但是null参与数值运算是自动转为0 ; 5 + null //5

10: 有数组 const arr = [1,2,3,4],要求多种方法输出 [1,2,3,4,1,2,3,4]
type1:

function myConcat1(arr){
  	if(arr instanceof Array){
  		return arr.concat(arr)
  	}
  }
  console.log(myConcat1([1,2,3,4]))

type2:

function myConcat1(arr){
if(arr instanceof Array){
return [...arr,...arr]
}
}
console.log(myConcat1([1,2,3,4]))

11:好多公司都问到了知道ES6的Symbol吗?
回答:ES6之前,JS有6种数据类型分别为:null,undefined,String,Number,Boolean,Object;ES6中新加入了一个新的数据类型Symbol,表示独一无二的值,也就是JS第七种数据类型
应用:作为对象的属性名,可以保证对象的属性名不会冲突,不会出现同名的情况,能防止某一个键不被修改和覆盖,

var mySymbol = Symbol()
//方法1
var a = {}
a[mySymbol] = 'hello world!'
//方法2
var a = {
 [mySymbol]:'hello world!'
}
//方法3
var a = {}
Object.defineProperty(a,mySymbol,{
  value:'hello wolrd!'
})

//以上三种方法都得到同一个值
a[mySymbol] //hello world!

tips:Symbol属性名不能通过点运算符获取,在对象内部定义属性是,也要用[]将Symbol包裹才有效

12:const与对象防篡改
用const命令定义一个对象a,表示a指向的内存地址不可修改,但是对象本身是可以修改的

const a = {
  name:"zhangsan"
}
a.name = "lisi"
console.log(a.name) //lisi

此时我们想定义一个不可修改的对象该如何定义呢,那就要用到Object.freeze(obj)方法了
const a ={
name:"zhangsan"
}
Object.freeze(a)
a.name = "lisi"
console.log(a.name) //zhangsan

此时又有问题了,对象的属性是基本类型还好,对象的属性也是对象的话,这个方法就行不通了

const a = {
 	name:"zhangsan",
 	skills:["Java","JavaScript","Oracle"],
 	bestFriend:{
 		name:"lisi",
 		age:18
 	}
 }
 Object.freeze(a)
 a.skills.push("Python")
 a.bestFriend.name = "wangwu"
 console.log(a) //此时a对象又变了

因为freeze是浅层冻结,那么我们就要实现一个自己的freeze方法

function myFreeze(obj){
  			Object.freeze(obj)
  			Object.keys(obj).forEach( key => {
  				if(typeof obj[key] === 'object'){
  					myFreeze(obj[key])
  				}
  			})
  		}
  		const a = {
  			name:"zhangsan",
  			skills:["Java","JavaScript","Oracle"],
  			bestFriend:{
  				name:"lisi",
  				age:18
  			}
  		}
  		myFreeze(a)
  		a.bestFriend.name = "wangwu"
  		console.log(a)

13:js如何检测对象为数组
type1:
instanceof
eg:

const arr = [1,2]
console.log(arr instanceof Array) //true

缺点:instaceof在存在多个全局作用域的时候,有可能会产生问题,比如在一个页面下包含多个iframe的时候.如果arr是在另一个frame中定义的数组,instanceof就会返回false

type2:
Array.isArray()
eg:

const arr = [1,2]
console.log(Array.isArray(arr)) //true

缺点,这是ES5中新加入的方法,浏览器支持情况为ie9+

type3:
Object.prototype.toString.call()
eg:

const arr = [1,2]
Object.prototype.toString.call(arr) == '[object Array]' //true

缺点:Object.prototype.toString()方法是有可能被修改的

14:数组操作方法
1:push()向数组末尾添加元素,并返回修改后的数组长度;pop()方法用于删除数组末尾的一个元素,并返回这个删除的元素

这个方法大家都知道,值得注意的两点是

  1. push方法会返回修改后的数组长度
  2. push方法可以配合ES6的数组展开操作符向数组中push另外一个数组
    eg:
const arr1 = [1,2,3]
const arr2 = [4,5,6]
arr1.push(...arr2) //[1,2,3,4,5,6]

2:shift()/unshinf()方法对,shift()方法用于删除数组首部的元素并返回该项,数组长度-1;unshift()方法用于向数组首部添加元素
3:重排序方法
reverse()方法和sort()方法
reverse()方法用于反转数组项的顺序
最常用的数组排序方法还是sort(),因为它可以接收一个比较函数作为参数,以便我们自定义排序逻辑
如果第一个参数应该位于第二个参数之前则返回一个负数,
如果两个参数相等就返回0,
如果第一个参数应该位于第二个参数之后,则返回正数
4:操作方法
1:concat()连接两个数组

const arr = [1,2]
const arr2 = [3,4]
arr.concat(arr2) //[1,2,3,4]

2:slice()用于复制整个数组或者数组的部分元素,规则如下
1:不传参数的时候,复制整个数组
const arr = [1,2,"red","blue"]
arr.slice() //[1,2,"red","blue"]
2:传1个参数的时候,返回从参数指定位置到数组结尾的所有元素

const arr = [1,2,"red","blue"]
arr.slice(1) //[2,"red","blue"]

3:传2个参数的时候,返回从第一个参数指定位置到第二个参数指定位置,均为数组下标位置,但不包含第二个参数索引.

const arr = [1,2,"red","blue"]
arr.slice(1,3) //[2,"red"]

15:简述浏览器兼容
16:笔试题会经常出现让你写js禁止冒泡和禁止浏览器默认行为的代码,虽然很简单,就一行代码,但请务必记住单词的拼写.
tips:addEventListener(),第三个参数(true/false),默认值为false,即在事件冒泡阶段处理回调函数
禁止事件冒泡
event.stopProgation
禁止浏览器默认行为
event.preventDefault
但是以上方法只是针对标准浏览器,IE下会出问题,所以跨浏览器的事件对象方法可以参考以下代码

const EventUtil = {
//添加事件监听
addEvent:function(element,type,handler){
  if(element.addEventListener){
    element.addEventListener(type,handler,false)//第三个参数表示在事件捕获阶段还是在事件冒泡阶段调用handler函数
  }else if(element.attachEvent){
    //IE下
    element.attachEvent("on" + type, handler)
  }else{
    element[on + "type"] = handler 
  }
}
//移除事件监听
removeEvent:function(element,type,handler){
  if(element.removeEventListener){
    element.removeEventListener(type,handler,false)
  }else if(element.detachEvent){
    //IE下
    element.detachEvent("on" +type,hanbler)
  }else{
    element["on" + type] = null
  }
}
//获取事件对象
getEvent:function(event){
  return event ? event : window.event //IE下;
}
//获取事件目标元素
getTarget:function(event){
  return event.target || event.srcElement //IE下;
}
//取消特定事件的默认行为
preventDefault:function(event){
  if(event.preventDefault){
    event.preventDefault()
  }else{
    //IE下
    event.returnValue = false
  }
}
//禁止事件冒泡
stopProgation(event){
  if(event.stopProgation){
    event.stopProgation()
  }else{
    //IE下
    event.cancleBubble = true
  }
}
}

17:jquery事件委托
根据jquery-on方法-事件委托
在使用jquery的on方法绑定事件处理程序时,可在第二个参数提供一个seletor选择器,该事件处理程序就会被指为事件委托/事件委派/事件代理,事件不会在绑定的元素上触发,但当selector参数选择器匹配到后代元素时,事件处理程序才会触发,
优势:1,当需要给多个元素绑定相同事件时,可以节省性能开销;
2:可以为还未插入文档的元素绑定事件,只需要在确保其祖先元素存在时,在祖先元素上绑定即可.

18:jquery的ready()方法和window.load()方法的区别
jquery.ready()方法:指的是在DOM结构绘制完毕时执行;
window.load()方法:指在DOM结构绘制完毕,JS文件加载完成,css文件加载完成,图片资源加载完成之后才会
执行

19:异步加载js文件的defer和async的区别
type1:
<script src="script.js"></script>
浏览器解析到这里的时候,会暂停后续的文档加载,去加载script.js文件,加载完成之后执行此js文件,执行完成之后继续加载文档元素.
type2:
<script async src="script.js"></script>
浏览器解析到这里的时候,不会暂停后续文档的加载,会并行加载js文件,但在加载完成js文件之后,会暂停后续文档的加载,先执行该js文件,执行完成之后继续解析文档元素
type3:
<script defer src="script.js"></script>
浏览器解析到这里的时候,不会暂停后续文档的加载,会并行加载js文件,加载完成后不会立即执行,而是等到后续文档元素全部加载完成之后才会执行js文件
如下图
image

绿色表示文档元素的加载过程
蓝色表示js文件的加载过程
红色表示js文件的执行过程

20:同步任务和异步任务
同步任务是那些没有被引擎挂起,在主线程上执行的任务,只有等前一个任务执行完成,后面执行后面的任务。
异步任务是那些被引擎放一边,不进入主线程,而是进入任务队列的任务。只有引擎认为某个异步任务可以执行了,才会将该任务放到主线程执行,排在异步任务后面的代码,不用等异步任务的结束,而是马上执行,就是说异步任务无“堵塞”效应

@hrpc
Copy link
Owner Author

hrpc commented Aug 10, 2018

1:事件循环和任务队列
js在运行时,除了提供一个主线程,还会提供一个/多个任务队列,里面是各种需要当前程序处理的异步任务。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant