1、如何实现”两边固定,中间自适应
2、什么是盒子模型?
3、null和undefined有什么区别?
4、let和const他们有什么区别?
5、什么是伪类和伪元素,他们有什么不同?
6、有什么方法可以检查数据类型,这些检测方法有什么不一样?
7、js创建函数的方法有哪些?他们之间有什么区别呢?
8、通过构造函数new一个实例对象,它的具体实现过程是什么样子的?
9、为什需要原型?原型和原型链是什么?
10、js中深拷贝和浅拷贝的区别是什么?说下实现深拷贝的几种方式。
11、js中的this
12、普通函数和箭头函数有什么区别?
13、js定义对象的方式?
14、请解释什么是事件代理?
15、事件模型
16、ajax原理
17、模块化开发怎么做
18、哪些操作会造成内存泄漏?
19、异步加载js的方式有哪些?
20、说几条写js的基本规范
21、json与xml的区别
22、html5有哪些新元素
23、css sprite是什么?
24、http和HTTPS的区别
25、px和rem的区别
26、link和@import的区别
27、改变原数组的方法有哪些?
28、vue的生命周期
29、父元素塌陷以及解决方法
<keep-alive></keep-alive>是干什么的?它有哪几种属性?各自的作用是什么?它独有的生命周期钩子是什么?并讲述钩子函数触发的场景。
如何局部(自定义组件中)覆盖UI库的默认样式(如element-ui)
请详细说下你对vue声明周期的理解?并简述在项目中,对应生命周期中一般实现哪些功能?
你怎么看待前端这个岗位
1、如何实现”两边固定,中间自适应“:https://blog.csdn.net/sleepwalker_1992/article/details/82802202
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p>通过absolute</p>
<div class="content">
<div class="left">left</div>
<div class="right">right</div>
<div class="middle">middle</div>
</div>
<p>通过自身浮动</p>
<div class="content1">
<!---->
<div class="left1">left</div>
<div class="right1">right</div>
<div class="middle1">middle</div>
</div>
<p>通过flex</p>
<div class="content2">
<!---->
<div class="left2">left</div>
<div class="right2">right</div>
<div class="middle2">middle</div>
</div>
<p>通过display:tabel-cell</p>
<div class="content3">
<!---->
<div class="left3">left</div>
<div class="middle3">middle</div>
<div class="right3">right</div>
</div>
<p>通过margin负值</p>
<div class="content4">
<!---->
<div class="box-middle">
<div class="middle4">middle</div>
</div>
<div class="left4">left</div>
<div class="right4">right</div>
</div>
</body>
</html>
<style>
* {
margin: 0;
padding: 0
}
.left {
height: 100px;
width: 200px;
position: absolute;
left: 0;
background: #987;
}
.right {
height: 100px;
width: 300px;
position: absolute;
right: 0;
background: #369;
}
.middle {
height: 100px;
margin-left: 220px;
margin-right: 320px;
background: #192;
}
.left1 {
height: 100px;
width: 200px;
background: #987;
float: left;
}
.right1 {
height: 100px;
width: 300px;
background: #369;
float: right;
}
.middle1 {
height: 100px;
margin-left: 220px;
margin-right: 320px;
background: #192;
}
.content2 {
display: flex;
}
.left2 {
height: 100px;
width: 200px;
background: #987;
}
.right2 {
height: 100px;
width: 300px;
background: #369;
order: 2;
}
.middle2 {
height: 100px;
margin: 0 20px;
background: #192;
flex: 1;
order: 1;
}
.content3 {
display: table;
width: 100%
}
.left3 {
height: 100px;
width: 200px;
background: #987;
display: table-cell;
}
.right3 {
height: 100px;
width: 300px;
background: #369;
display: table-cell;
}
.middle3 {
height: 100px;
margin: 0 20px;
background: #192;
}
.box-middle {
width: 100%;
float: left;
}
.left4 {
height: 100px;
width: 200px;
background: #987;
float: left;
margin-left: -100%;
}
.right4 {
height: 100px;
width: 300px;
background: #369;
float: left;
margin-left: -300px;
}
.middle4 {
height: 100px;
margin-left: 220px;
margin-right: 320px;
background: #192;
}
</style>
2、什么是盒子模型:https://blog.csdn.net/qq_42720683/article/details/83584970
1、盒子模型就是指在在网页中占有一定空间的元素,这种元素的总宽度包括内容、边框、内边距以及外边距
2、盒子模型主要分两种:一种是标准盒子模型,一种是怪异盒子
(1)在声明了<!DOCTYPE html>使用的盒子就是标准盒子模型,如果没有添加这个的话具有IE内核的浏览器使用的盒子就是怪异盒子
(2)他们的总宽度都是content+padding+border+margin
(3)但是各自所对应的的width不同,标准盒子的width一般都是指内容的宽度;但是怪异盒子的width是包含了border以内的宽度也就是content+padding+border
3、伪元素、伪类的区别:https://www.jianshu.com/p/996d021bced3
伪类的功能:
(1)格式化DOM树以外的信息。比如: <a> 标签的:link、:visited 等。这些信息不存在于DOM树中。
(2)不能被常规CSS选择器获取到的信息。比如:要获取第一个子元素,我们无法用常规的CSS选择器获取,但可以通过 :first-child 来获取到。
伪元素的功能:
(1)创建一些文档语言无法创建的虚拟元素。比如:文档语言没有一种机制可以描述元素内容的第一个字母或第一行,但伪元素可以做到(::first-letter、::first-line)。
(2)伪元素可以创建源文档不存在的内容,比如使用 ::before 或 ::after。
两者的区别:
1、写法上:
::表示伪元素
:表示伪类
2、
伪类其实是弥补了CSS选择器的不足,用来更方便地获取信息。
而伪元素本质上是创建了一个虚拟容器(元素),我们可以在其中添加内容或样式。
3、
一个选择器可以同时使用多个伪类(但有的伪类会互斥)
一个选择器只能同时使用一个伪元素(未来的版本可能会支持多伪元素)
4、检查数据类型的几种方法以及他们之间的区别:https://blog.csdn.net/zjy_android_blog/article/details/81023177
1、typeof只能检测出原始类型,对于引用类型无法检测
2、instanceof只能直接检测出引用类型,对于原始类型无法直接检测,只有将原始类型实例化才可以检测出。因为instanceof判断对象是否是某一数据类型(原始类型、数据类型)的实例
3、constructor可以判断出他们的原始类型,但如果创建一个对象,更改它的原型constructor就会失效
4、Object.prototype.toString.call()可以精准判断出所有的数据类型‘[Object 数据类型]’
5、let、const的区别
相同点:
1、生成块级作用域,在块作用域之外无法访问到
2、都存在暂时死区;使用变量必须先声明
3、都不存在变量提升
4、都不能在同一片区域内重复声明
区别:
let可以修改值
const指向的内存地址不得改动
对于简单类型(number、string、bool)来说,值就保存在内存地址所指向的内存地址中,等同于常量
对于复合类型(Object、array)来说,变量内存地址所指向的就只是一个指针,指针所指向的内容存储在堆中,const只能保证复合类型的指针不变。
6、null和undefined的区别
相同点:
(1)都是基本数据类型,保存在栈中
(2)在做==操作时两者进行类型转换后相等null==undefined(
区别:
1、使用typeof检测时null指向的是Object;而typeof检测undefined指向的是undefined
2、定义不同:
undefined表示声明变量未赋值时变量值为undefined
null更像是一个空对象指针,表示一个变量不再指向任何对象地址,如果声明的变量之后需要保存对象,最好将其优先初始化为unll
3、在做===操作时两者不等
对于==,实际上undefined的值是派生自unll的值,js规范中提到要比较相等性之前,不能将 null 和 undefined 转换成其他任何值,并且规定null 和 undefined 是相等的。null 和 undefined都代表着无效的值。
对于===,进行比较是不能进行类型转换,他们是属于不同类型,所以无法恒等。
7、js创建函数的方法有哪些?他们之间有什么区别呢?
函数声明:function a(){}
函数表达式:var a=function(){}
函数方法 a:function(){}
通过第一种方法创建的函数会被在执行上下文过程中被提升到代码头部
而第二种通过函数表达式创建的函数在执行上下文时会变量提示,但是函数赋值部分依旧保持原来的位置
通过a:的形式创建的函数一般都是作为对象方法使用且只能在对象中生效
8、通过构造函数new一个实例对象,它的具体实现过程是什么样子的?
1、创建一个空对象
2、对象原型指向构造函数
3、通过call、apply方法调用改变this指向至新对象
4、返回新对象
function New(Func){
var obj={};
obj._proto=Func.prototype;
Func.apply(obj,...arguments)
return obj;
}
9、为什么需要原型?原型和原型链是什么?
由构造函数创建的实例对象会开辟各自的内存空间,各自内存地址中都存储着相同的属性和方法,如果这些实例对象都调用同一个属性和方法,就会导致空间浪费,将这些公用属性或方法保存在prototype原型对象上,在调用时如果在构造函数中查找不到可以去prototype上查找,解决空间浪费问题。
一个对象实例对象会自动生成一个原型指针_proto_指向原型对象,在调用属性或方法时,如果在构造函数上查找不到,通过原型指针索引到原型对象上查找,如果原型对象上没有,就去原型对象的上一级原型对象上查找,这个查找原型的过程形成原型链
10、js中深拷贝和浅拷贝的区别是什么?说下实现深拷贝的几种方式。
https://www.cnblogs.com/dreamingbaobei/p/9815962.html
js中的数据类型在内存中存储方式分为栈存储和堆存储
基本类型存储在栈中,如果给一个变量赋值,系统自动分配栈内存空间给这个直接值,变量指针指向该值,如果复制此变量,系统会给这个新变量开辟新的栈内存空间,新变量指针指向该值,与被复制变量互不影响
对于引用类型变量内容保存在堆内存中,js无法直接访问对象内容,在栈中保存的是此对象的引用也就是变量地址,通过这个变量地址索引到保存在堆内存中的变量内容,如果对象中还嵌套了对象或数组,会在堆中重新开辟一个空间存放对象或数组并将会内存地址赋给属性指针
在创建了一个对象实例后,系统为对象变量开辟栈内存空间,存储着变量地址,通过变量地址可以查找到与之对应的存储在堆内存中的对象内容
对此对象进行复制后,会在栈内存中开辟一个新的空间,同样也存储着该内存地址,复制对象变量与被复制变量对象都指向堆中同一个对象,通过其中一个变量修改对象内容,另一个也会变化。
为了避免这种情况的发生,可以通过深浅拷贝来解决。
浅拷贝实质上是拷贝对象指针,因此只能拷贝到对象的第一层属性,内容是对象或数组的属性通过浅拷贝只能拷贝到它们的内存地址,修改新旧对象属性内容为对象或数组的内容仍然会相互影响,可以使用深拷贝来解决浅拷贝此问题
Object.assign({},Obj)//使用Object.assign()拷贝只有一层属性的对象内容
深拷贝会创建一个新对象(开辟新的内存空间以及新的内存地址),对象中存储内容与原对象相同,修改新旧对象属性不会互相影响(通过json或递归复制实现深拷贝)
DeepCopy (obj) {
let str;
let newobj;
if (typeof obj !== 'object') {
return obj;
} else if (window.JSON) {
str = JSON.stringify(obj);
newobj = JSON.parse(str);
} else {
newobj = obj.constructor === Array ? [] : {};
for (var i in obj) {
newobj[i] = typeof obj[i] === 'object' ? this.DeepCopy(obj[i]) : obj[i];
}
}
return newobj;
}
11、js中的this
作为普通函数(特别注意在对象中作为普通函数调用的情况),this指向window;严格模式下的函数内部this不允许指向window,为undefined
作为对象方法调用,this指向调用该方法的对象;
作为构造函数实例调用,this指向实例对象
作为apply、call、bind调用,this指调用这些方法的对象,为空默认是全局对象
作为箭头函数调用,由于箭头函数本身没有this,所以出现在其内部的this指向包裹箭头函数的第一个普通函数或当前对象的执行环境
//针对在对象中作为普通函数调用的情况
//
对于嵌套函数,嵌套函数作为方法调用时,其this指向调用它的对象;
嵌套函数作为普通函数调用时,其this指向window
var name = "window"
var obj = {
name: 'aaa',
getName: function() {//函数作为方法调用
return function() {//函数作为普通函数调用
console.log(this.name)
}
}
}
obj.getName()() //"window"
和变量不同,关键字this没有作用域的限制,嵌套的函数不会从调用它的函数中继承this。如果嵌套函数作为方法调用,其this的值指向调用它的对象。如果嵌套函数作为函数调用,其this值不是全局对象(非严格模式下)就是undefined(严格模式下)。
通过箭头函数可以解决上述问题
var name = "window"
var obj = {
name: 'aaa',
getName: function() {
return () => {
console.log(this.name)
}
}
}
obj.getName()() //"aaa"
12、普通函数和箭头函数有什么区别?
1、this指向不同。
普通函数this指向调用它的对象,箭头函数中没有this,内部出现的this指向定义时的执行环境
2、获取参数方式不同。
普通函数可以使用arguments获取参数
箭头函数无法使用arguments,但可以通过rest(...)来获取
3、箭头函数没有this指针,不能作为构造函数new一个实例对象
4、箭头函数没有this指针,使用call、apply、bind方法改变this指向也就无效了
4、箭头函数没有原型对象
let a = () => {
console.log("1")
}
console.log(a.prototype)//undefined
let b = function() {
console.log("i")
}
console.log(b.prototype)//{constructor:f}
13、js定义对象的方式 https://blog.csdn.net/longyin0528/article/details/80504282
1、字面量创建对象
var obj={...}
2、构造函数创建对象实例
var object=new 函数名()
3、工厂模式封装
function factory(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.print = function() {
console.log(obj.name)
}
return obj;
}
var pesron = factory('pam', 24)
pesron.print()
4、原型对象(将所有方法都写到原型属性上去)
function Person() {}
Person.prototype.name = 'pam'
Person.prototype.age = 24
Person.prototype.print = function() {
console.log(this.name)
}
var pesron = new Person('pam', 24)
pesron.print()
5、构造函数和原型混合(构造函数内部属性为个性,原型方法作为公共数据)
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.print = function() {
console.log(this.name)
}
var pesron = new Person('pam', 24)
pesron.print()
6、动态原型模式(将原型属性方法写到构造函数内部)
function Person(name, age) {
this.name = name;
this.age = age;
if (typeof this.print !== 'function') {
Person.prototype.print = function() {
console.log(this.name)
}
}
}
var pesron = new Person('pam', 24)
pesron.print()
7、寄生构造模式(创建一个额外方法但不直接修该原对象属性)
function Person(name, age) {
var o = []
o.push.apply(o, arguments)
o.toString = function() {
alert(this.join('|'))
}
return o
}
var pesron = new Person('pam', 24)
pesron.toString()
8、稳妥 构造函数模式(不使用this)
function Person(name, age) {
var obj = {}
obj.name = name;
obj.age = age;
obj.print = function() {
console.log(name)
}
return obj
}
var pesron = new Person('pam', 24)
pesron.print()
16、ajax原理
通过ajax实现客户端向服务端发起资源请求以及服务器响应的过程
创建XMLHttpRequrst请求
设置请求方式(GET\POST\DELETE\OPTIONS\PUT)、请求路径、服务器响应方式(同步或异步)
如果是异步请求添加回调函数 onreadystatechange()
发送请求
解决跨域:
1、在服务端写入'Access-Control-Allow-Origin'
2、jsonp
17、模块化开发怎么做
commonJS
AMD(Asynchronous Module Definition)
CMD((Common Module Definition)
21、json与xml的区别
json、xml都是数据交换格式
(1)写法上
xml是可扩展标记性语言,可以使用自定义的便签,写法类似于html写法,但是结构清晰,因此也更容易理解
json不存在标签等语义化元素, 写法上是对象的写法并且字符串加双引号,看上去就是一个数据块
(2)体积上
xml是重量级数据交换格式,但是它的结构体比较庞大,在进行远程调用时占用带宽大;
json是一种轻量级数据交换格式,体积小,远程调用占用带宽小
(3)时间上
xml需要先转换成dom树再进行遍历,解析时间长
json数据通过js可以快速获取,解析时间短
(4)使用上
xml主要用于与其他系统远程交互,数据共享比较方便
json主要用于调用接口,占用带宽少
22、html5有哪些新元素
语义化便签<Header><footer><nav>
<canvas>画布
无需插件的音视频播放<video><audio>
<!DOCTYPE html>表示h5结构
新的表单属性:<placeholder>
新增表单事件:
本地离线存储
23、css sprite(雪碧图)
因为浏览器向服务器请求页面资源时,每一张图片也都是都要向服务器发送请求的,
如果请求页面中图片太多,客户端发送请求、服务器接收请求并发送响应的次数过多,
会影响页面加载速度。通过雪碧图将很多小的背景图都放到一张大图中去,这些图片
只需要发送一次请求就可以了,发送和接收请求以响应的次数会减少,也就能提升页
面加载速度,主要通过css的backg-position对这些背景图位置进行调整。
25、px\rem的区别
px是绝对尺寸,在定义了之后会把尺寸定死
rem是相对尺寸,相对于根元素html的font-size进行计算
em是相对于父元素可继承字体样式进行计算
26、link和@import的区别
css定义有三种方式:
1、内联式 将css样式直接写在dom元素便签内 <li class="class-6" style="background:pink">
2、嵌入式 将css样式写在<style>标签中并直接放入到html中
3、外部引用式
3.1 通过link链接接外部的css样式文件
3.2 通过@import引入外部的css样式文件
link和@import的区别:
(1)
link属于XHTML范畴,不存在浏览器兼容问题
@import属于css范畴,低版本浏览器不支持
(2)
通过link可以链接到外部的css样式并写在<head>中
<link rel="stylesheet" type="text/css" href="css文件名">
@import只能写在style标签首部
@import url('css文件名');
(3)
link支持js去修改dom样式
@import不支持
(4)
link可以在页面加载同时加载
@import需要等到页面加载完成后才会加载
27、改变原数组的方法有哪些?
push():向数组内添加元素
pop():弹出数组内最上面元素
sort():给数组排序
reverse():数组逆操作
splice(index):从index索引位置开始删除值
unshift(val):在数组首部添加val值
shift():从数组首部删除值
28、vue的生命周期:https://blog.csdn.net/mqingo/article/details/86031260
beforeCreate()创建vue实例,此时data、methods等还未初始化
created() data、methods初始化完成
beforeMount()编译模板生成模板字符串也就是通过vdom执行render函数生成Vnode,模板编译完成但还未挂载到实例上
mounted()通过patch方法将Vnode也就是模板渲染成dom到页面上(挂载成功此时才有$el),首次渲染成功,
beforeUpdate() data数据更改,通过set监听到并立即更新,重新执行render函数
updatad() 数据更改生成Vnode并通过patch方法与原先的PreVnode对比并将修改部分渲染到页面上
beforeDestroy() 此时vue实例从运行阶段进入销毁阶段,但是所有的方法、指令、data数据等仍可用
destroyed() 所有的方法、指令、data数据等均不可用,子组件被销毁
29、父元素塌陷以及解决方法
父元素没有设置高度,由内部子元素的高度将其撑开,但是对子元素设置float让其浮动后子元素脱离文档流,父元素无法撑开高度就会出现父元素塌陷。
在父元素上添加overflow:hidden
添加一个空的子元素,并对其设置clear:both
给父元素设置伪类(最推荐方式) :after{ clear:both; content:' ';display:block}