0~100道前端面试题

1.css权重排序
!Important(∞) > 内联样式(1000) > id (100) > class、伪类、属性(10) > 标签、伪元素(1)
“题外话”:引入css的方式及优先级别
内联样式 > 内部样式 > 外部样式
内联:直接把样式写在HTML标签中
内部:在css写在head中的style标签里面
外部:css样式通过link或@import导入:
区别
@import:

2.div 绝对居中
方法1:(绝对定位)
父:
position:relative;
子:
position:absolute;
left: 50%;
top:50%;
margin-left: -半宽;
margin-top:-半高;

方法2:(css3属性:transform)
父:
position:relative;
子:
position:absolute;
left: 50%;
top:50%;
transform:translate(-50%,-50%); //如果transform计算出来的值有小数就会显示模糊,小数越接近整数越清晰

方法3:(flex布局)
父:
display:flex;
子:
margin: auto;

方法4:(margin属性)
父:
position:relative
子:
position:absolute
top:0
bottom:0
left:0
right:0
margin:auto

3.你知道的伪类
:hover ——悬停
:active ——激活
:link——未访问
:before ——元素前添加
:after ——元素后添加

CSS3新增伪类:
:first-child
:last-child
:nth-child(n)
::before
::after1.说一下promise
css3新增特性
border-radius
text-shadow

4.有五个promise怎么样让五个执行完之后执行后面的代码
利用Promise.all(若干个promise实例).then(后面要执行的代码)
例子:
let promise1 = new Promise((resolve,reject)=>{
setTimeout(resolve,3000,‘第一个promise完成’)
})
let promise2 = new Promise((resolve,reject)=>{
setTimeout(resolve,1000,‘第二个promise完成’)
})
let promise3 = new Promise((resolve,reject)=>{
setTimeout(resolve,500,‘第三个promise完成’)
})
Promise.all([promise1,promise2,promise3]).then((result)=>{ //result接收了三个promise的resolve返回的结果
console.log(result)
})
//[“第一个promise完成”, “第二个promise完成”, “第三个promise完成”]
注意:Promise.all([p1,p2,…]) // all内的promise对象必须用方括号扩起来

5.promise是一种异步解决方案,它是一个对象,保存者一个未来才会结束的事件的结果。
它可以用来去获取异步消息,然后通过then函数来定义异步操作之后的回调函数。
例子:
let promise = new Promise((resolve,reject)=>{
console.log(‘promise actived’)
resolve()
})
promise.then(()=>{
console.log(“promise is resolved”)
})
console.log(“happy ending!”)
输出顺序:
promise actived
happy ending!
promise is resolved
因为:promise一旦创建就会执行,然后同步代码会比异步代码先辈执行。

5.怎么样会产生跨域,项目上怎么解决
配置代理,怎么配置代理服务器?
浏览器提交的是前台页面的请求,它不知道服务器的存在,前台是8080,后台是4000,就产生跨域。
前台应用运行在前台服务器上,后台应用运行在后台服务器上。
打个比方,前台监听的端口号是8080,后台监听的端口号是4000.前台和后台不在同一个服务器上。
代理服务器运行在前台服务器上,负责转发请求前台的应用,代理会将前台对8080端口号的请求拦截下来,然后向4000发送请求,请求到4000端口号的资源后转交给前台。
那么代理是什么东西?代理也叫代理服务器。通过配置代理来告诉代理去哪里发请求。

6.嵌套路由怎么实现
在配置路由时添加children属性,并赋值被嵌套的路由的路径和组件名:router.js
path:‘/home’,
components:Home,
childen:[
{
path:‘header’,
component:Header
},
{
path:‘footer’,
component:Footer
}]

Header

7.你做过哪些组件
弹出框
内容搜索
网站尾部

8.父子组件怎么传递数据
(1)父组件向子组件传递数据:
props
子组件:Header
a。在中声明接受props:
props:[‘title’,’name’,…]
b。直接在组件中使用插值表达式来使用这个prop —— 如,{{prop1}}
父组件:
使用子组件时通过参数把数据传给子组件——

slot:
子组件:Header
使用slot标签,(相当于占个位置)并给slot的name属性赋值,例如:

父组件:

这是传给子组件的数据

(2)子组件向父组件传递数据:
e m i t ( ) 子 组 件 : H e a d e r a 。 在 子 组 件 中 绑 定 一 个 事 件 , 例 如 c l i c k 事 件 。 b 。 在 c l i c k 事 件 处 理 程 序 中 使 用 t h i s . emit() 子组件:Header a。在子组件中绑定一个事件,例如click事件。 b。在click事件处理程序中使用this. emit()Headeraclickbclick使this.emit把组件中的数据传递出去:
emit(‘getName’,this.name)接受两个参数,第一个函数,第二个为传给第一个函数的参数
父组件:
a。引用子组件时,把接受数据的函数当作参数传给子组件:

b。通过函数把接受的数据赋值给本组件的数据 getName(data){ //data就是子组件传给来的数据 This.name = data }

(3)组件间传递数据
利用bus事件总线的 e m i t ( 发 布 ) 和 emit(发布) 和 emiton(监听)来实现( o f f 移 除 ) : a 。 在 m i a n . j s 中 给 创 建 v u e 实 例 的 构 造 函 数 V u e 的 原 型 添 加 b u s 属 性 , 实 现 全 局 管 理 的 事 件 总 线 对 象 : V u e . p r o t o t y p e . b u s = n e w V u e ( ) / / 创 建 v u e 实 例 之 前 b 。 发 送 数 据 的 组 件 A 通 过 触 发 某 个 事 件 使 用 b u s . off移除): a。在mian.js中给创建vue实例的构造函数Vue的原型添加bus属性,实现全局管理的事件总线对象: Vue.prototype.bus=new Vue() // 创建vue实例之前 b。发送数据的组件A通过触发某个事件使用bus. off)amian.jsvueVuebus线Vue.prototype.bus=newVue()//vuebA使bus.emit()把数据发送出去:
组件A:
fn(){
this.bus.$emit(‘sendData’,data) // endData发送数据的函数名,data作为endData参数发送出去
}

c。欲接受数据的组件B通过KaTeX parse error: Expected '}', got 'EOF' at end of input: …ounted:{ this.on(‘sendData’,function(data){ // data为sendData传过来的数据
this.msg=data // 对接收过来的数据data进行操作,这里做赋值做例子
})
}
具体实例代码:
main.js:
import Vue from ‘vue’
Vue.prototype.bus=new Vue()
new Vue({
el: ‘#app’,
router,
components: { App },
template: ‘’
})

发布数据组件A:
methods:{
handleClicks(){
this.bus.KaTeX parse error: Expected 'EOF', got '}' at position 36: …组件兄弟!') }̲ } 接受数据组件B:…on(“sayHello”, msg => {
this.greet = msg
})
}

总结:
a。Vue.prototype.bus=new Vue() // mian.js
b.组件A:
this.bus. e m i t ( ‘ f n ’ , d a t a ) c 。 组 件 B : t h i s . b u s . emit(‘fn’,data) c。组件B: this.bus. emit(fn,data)cBthis.bus.on(‘fn’,(data)=>{
//dosothing
})
(4)***组件多级(跨级)传递数据$attrs $listener
例子:组件A调用了组件B,组件B又调用了组件C。
(1) a t t r s : A − − > C S t e p 1 : A 组 件 调 用 B 组 件 时 , 还 是 照 常 的 传 递 参 数 去 传 递 数 据 ; S t e p 2 : B 组 件 在 调 用 C 组 件 时 , 使 用 v − b i n d 强 制 绑 定 attrs:A-->C Step1:A组件调用B组件时,还是照常的传递参数去传递数据; Step2:B组件在调用C组件时,使用v-bind强制绑定 attrs:A>CStep1:ABStep2:BC使vbindattrs
Step3:C组件中一props生命接受来自爷爷组件的属性即可

(2) l i s t e n e r : C − − > A S t e p 1 : B 组 件 在 调 用 C 组 件 时 , 使 用 v − o n 添 加 listener:C-->A Step1:B组件在调用C组件时,使用v-on添加 listener:C>AStep1:BC使vonlistener属性
Step2:C组件通过 e m i t 把 数 据 传 递 出 去 ; S t e p 3 : A 组 件 在 调 用 B 组 件 时 , 使 用 v − o n 指 定 函 数 来 接 收 C 组 件 传 过 来 的 数 据 A 组 件 : < C h i l d B v − o n : g e t M s g = " g e t M s g " : t i t l e = " t i t l e " : s u b T i t l e = " s u b T i t l e " > < / C h i l d B > B 组 件 : < C h i l d C : m s g = " m s g " v − b i n d = " emit把数据传递出去; Step3:A组件在调用B组件时,使用v-on指定函数来接收C组件传过来的数据 A组件: <ChildB v-on:getMsg="getMsg" :title="title" :subTitle="subTitle"></ChildB > B组件: <ChildC :msg="msg" v-bind=" emitStep3:AB使vonCA<ChildBvon:getMsg="getMsg":title="title":subTitle="subTitle"></ChildB>B<ChildC:msg="msg"vbind="attrs" v-on="KaTeX parse error: Expected '}', got 'EOF' at end of input: … this.emit(“getMsg”,this.smgg)
}
}
(5)vuex
a。组件A把数据保存到vuex:
this. s t o r e . s t a t e . n a m e = ‘ p i p i ’ b 。 组 件 B 从 v u e x 中 读 数 据 : t h i s . g i r l = t h i s . store.state.name = ‘pipi’ b。组件B从 vuex中读数据: this.girl=this. store.state.name=pipibBvuexthis.girl=this.store.state.name // 读取到组件A传过去的name属性

9.vue生命周期
生命周期三个大的阶段:
1.初始化阶段:beforeCreate()、create()、beforeMounted()、mounted()
a。new(创建)vue实例时,马上会调用beforeCreate();-这个名称有点混淆视听,因为并不是创建实例了才调用,而是创建时就调用。
b。初始化vue实例时会调用created();
c。调用beforeMounted(),判断是否有挂载点(el),没有的话手动挂载(调用$mount(el))–很少用,然后编译模版中的内容,才会挂载到页面上,此时调用mounted()

2.数据更新:beforeUpdate()、updated()
数据更新才会调用,数据发生变化之前调用beforeUpdate(),发生变化之后调用updated()
3.死亡:beforeDestroy()、destroyed()
–此时页面还是会显示,只是不再有数据绑定,也不再有交互了,这时候vm处于死亡状态。(与react有点区别,react移除后就不会显示)
在调用$destroy()时调用,在销毁vm之前调用beforeDestroy();销毁之后调用destroyed()
死亡阶段的beforeDestroy()可以进行一些收尾工作:比如,清除定时器等

总结:
a。beforeCreate()、created()、beforeMounted()、mounted()只会执行一次
b。beforeUpdate()、updated()–可能发生0次,也可能发生n次,要看有没有数据更新,this.xxx=value更新数据
c。beforeDestroy()和destroyed()只会执行一次,而且是调用了$destroy()才会执行。
d。Mounted()、beforeDestroy()——这两个回调函数最常用!:
Mounted():发送ajax请求获取数据、启动定时器等异步任务
beforeDestroy():进行一些收尾工作,如清除定时器等

10.$nextTick作用
n e x t T i c k ( ) 接 受 一 个 函 数 作 为 参 数 界 面 更 新 立 即 调 用 , 比 如 使 用 s w i p e r 时 , 在 w a t c h 中 监 测 列 表 获 取 到 数 据 后 就 创 建 s w i p e r 会 得 不 到 理 想 的 结 果 , 因 为 已 有 数 据 就 创 建 s w i p e r 此 时 , 数 据 没 有 到 达 分 页 的 要 求 , 不 会 产 生 分 页 ; 但 是 如 果 在 监 听 到 数 据 之 后 , 在 创 建 s w i p e r 之 前 使 用 nextTick()接受一个函数作为参数 界面更新立即调用,比如使用swiper时,在watch中监测列表获取到数据后就创建swiper会得不到理想的结果,因为已有数据就创建swiper此时,数据没有到达分页的要求,不会产生分页;但是如果在监听到数据之后,在创建swiper之前使用 nextTick()使swiperwatchswiperswiperswiper使nextTick就会等到数据更新完成再在创建swiper。这时候才会得到想要的结果。
watch:{ //监听器
getName(value){ // 监听到getName有数据了触发该函数
this.KaTeX parse error: Expected '}', got 'EOF' at end of input: …{ // 在数据更新完成后触发nextTick里面的函数
new Swiper(…)
})
}
}

11.watch有没有用过
watch是一个监听器,可以用它来监听数据改变然后作出某个动作:
比如,你在异步获取数据时,可以监听存放数的变量是有有数据了,如果有数据了就打印相关提示信息。
再如,做轮播图的时候,会用到swiper,创建swiper应该再获取数据之后,所以创建swiper可以放到watch中。

12.数组有哪些方法
slice()、indexof()、lastIndexof()、filter()、some()、every()、reduce()、toString()、valueof()

13.清浮动有哪几种方法
浮动的作用:可以让块级元素不独占一行,可以用来实现多栏布局
浮动产生影响:
(1)当浮动元素宽度小于屏宽时,会对它后面的元素的布局产生影响:
原本排在它后面的元素,会跟它并排在一行上(如果使块级元素,当该块元素的宽度小于屏幕宽度-浮动元素宽度值的情况)。
(2)(包裹元素未设置高度)脱离文档流,使包裹元素高度不能撑开,即高度为0——高度坍塌
(3)当包裹元素的高度小于包裹元素的高度时,会产生高度溢出

清除浮动的几种方法:
(1)给包裹元素设置高度(不小于浮动元素的高度)
该方法解决了父元素高度因为子元素脱离文档流不能撑开的问题,但是高度要计算准确,否则也会达不到清除浮动的影响。
(2)给包裹元素后面添加一个空的div,然后设置clear:both
弊端:dom中多了一个没有实质意义的标签,不利于搜索引擎优化
(3)给包裹元素添加伪元素:
#wrap:after{ //三个属性缺一不可
content:‘’;
display:block;
clear:‘’;
}
#wrap{
Zoom:1; // ie特有的请浮动方式
}
(两个同时设定以防万无一失)

(4)给包裹元素设置:overflow:hidden -其实是触发了bfc
(5)给包裹元素设置:overflow:auto-其实也是触发了bfc
(触发bfc可以清除浮动的影响是因为bfc计算高度时浮动元素也计算在内)
(bfc不会与浮动元素重叠这一点可以用来做两列布局)
17.数据类型
基本数据类型:number、string、boolean、null、undefined
引用数据类型:object、array、function
typeof会返回什么值?
string number boolean object function undefined symbol

18.原型和原型链
每个实例对象都有一个__proto__属性,该属性指向它的构造函数的prototype,构造函数的prototype的__proto__指向的原型对象,以此类推,直到指向object对象,object的prototype的__proto__的值是null,它是作用域链的尽头。

19.闭包
什么是闭包:
一个函数内部包含另一个函数,内部函数调用了外部函数的变量,这样就形成了闭包。
红宝书总结的一句话:闭包是有权访问另一个函数内部的属性的函数。
典型例子:
function fn1(name){
var name = name
function fn2(){
console.log(name)
}
return fn2
}

var f1 = fn1('pipi')
f1() // pipi 调用的是fn2而不是fn1
 var f2 = fn1('ahaaa')
f2() // ahaaa 调用的是fn2而不是fn1

f2 = null // 结束调用时使fn2变成垃圾对象

闭包的作用:
(1)有权访问另一个函数内部的变量
(2)延长局部变量的生命周期
(3)在函数外部操作函数内部的数据(在函数内部封装函数,然后return出去)

闭包应用的场景:
(1)循环遍历加监听
html:
button1
button2
button3
js:
var btns = document.getElementsByTagName(‘button’)
for (var i = 0; i < btns.length; i++) {
var btn = btns[i]
btn.onclick = () => {
alert(i + 1) // 因为索引值从0开始
}
} //每次都会弹出3

    // 利用闭包
    for (var i = 0; i < btns.length; i++) {
        ((i) => {
            var btn = btns[i]
            btn.onclick = () => {
                alert(i + 1) // 因为索引值从0开始
            }
        })(i)
    } 

    // 利用let声明变量的唯一性
    for (let i = 0; i < btns.length; i++) {
        var btn = btns[i]
        btn.onclick = () => {
            alert(i + 1) // 因为索引值从0开始
        }
    }

(2)在一个函数中封装私有变量和操作私有变量的方法(把方法return出去,外部就可以调用了)
(3)封装js模块(开辟一个js文件,然后在文件中生命一个匿名自运行函数,然后在该函数内部定义若干个函数,最后return出去;需要调用时,只需要引入该文件然后调用)
fileA:
function myModule() {
// 1.定义私有数据
var msg = “pipixi”
// 2.定义操作数据的函数1
function sayHello() {
console.log((‘hello’)+ msg.toLocaleUpperCase())
}

    // 2.定义操作数据的函数2
    function sayGoodbye() {
        console.log(('goodbye')+ msg.toLocaleUpperCase())
    }
    return { // 3.向外暴露对象——供外部使用的方法
        sayHello: sayHello,
        sayGoodbye: sayGoodbye
    }
}

fileB:
// 引入外部js文件

闭包生成和死亡:闭包在定义时就生成,死亡是在内部函数变成垃圾对象时(结束调用)

闭包的弊端:
(1)延长了局部变量的生存期,浪费内存
(2)容易导致内存泄漏(闭包不会导致内存溢出-内存不足,因为创建时就生成,闭包内存不会越来越大)
(内存泄漏:无用的变量的内存得不到释放)
解决:尽量少用闭包、调用完毕及时释放内存

20.两列布局
方法1:-float
wrap:overfloat:hidden;——清除浮动
left:
width:300px;
float:left;
right:
Margin-left:300px;
//因为left浮动之后脱离文档流,遮挡在right左边

方式2:——position:absolute
#wrap:
position:relative;
left:
position:absolute;
width:300px;
right:
margin-left:300px;

方式3:——flex布局
#wrap:
display:flex;
left:
width:300px;
right:
flex:1;

方法4:bfc不会和浮动元素重叠
left:
float:left;
right:
overfloat:hidden/auto; ——触发bfc
项目中清除浮动函数:
/* 清除浮动 */
.clearfix () {
*zoom: 1;
&::after {
content: ‘’;
display: block;
clear: both;
}
}

  1. 为什么总less或sass
    less和sass都是css预编译器,因为在开发过程中,有些css样式是需要复用的,但是css并不像编程语言有类似可以复用的代码块,比如函数。复用css时需要复制粘贴。这样不仅不方便而且浪费内存。
    less可以让css像其他编程语言一样,可以去定义变量,甚至函数,然后在需要的地方直接调用函数即可。对于公共样式,单独写在一个文件中,然后在项目中需要别的模块直接引入即可,很方便。

22.同源策略
https://www.cnblogs.com/gpd-Amos/p/9043344.html
(1)什么是同源策略?
同源策略是一种浏览器安全机制,它限制(规定)了只有请求的url是同源的才能访问,否则拒绝访问。这样保证了用户的信息安全和防止了数据被窃取。
(2)同源的三个条件?
协议、域名、端口号三者必须一致,缺一不可。
(端口号默认为80,如果是80可以省略,但是不是80必须要写不能省略)
非同源受到的限制:
a。cookie不可获取
b。dom无法获得
c。ajax无法请求

(3)什么叫跨域?
跨域就是从一个域去请求另一个域的资源,只要请求的url的协议、域名、端口号之一不一致,就是跨域。一般情况下,跨域请求资源会报错。
跨域是客户端请求正常发送、服务器也会响应,但是浏览器拒绝服务器返回的数据的一种安全机制。
(4)为什么要跨域?
实际开发中,有时候公司有很多项目,每个项目中又有很多子域名,而项目与项目之间有时会共享信息资源,这时候就会用到跨域请求资源。或者,有时候网站与网站之间也会相互调用资源,也会使用到跨域。

(5)怎么解决跨域?
1.jsonp
原理:利用的是script标签不受同源策略的限制的特点去请求跨域资源
过程:
step1:创建一个script 标签
var script = document.createElement(“script”)
step2:设置请求资源的回调函数
function getDate(){
// do something
}
step:利用script标签的src属性发送请求并带上回调函数把请求结果带回
script.src=“http://localhost:8000?callback=getDate”
step4:将该script标签添加到页面中
document.body.appendChild(‘script’)
好处:方便快捷的获取数据
弊端:只能发送get请求,不能发送put请求;不方便进行异常处理和获取状态码;直接获取数据不安全。

2.cors-cross origin resource sharing(跨域资源共享)
在客户端请求的http头部添加origin属性,并赋值请求的完整的url,如http://www.xxx.com,然后由服务器决定请求失败或者成功。
如果服务器允许请求,会在响应头部添加字段Acess-Control-Allow-Origin:http://www.xxx.com,如果该字段的值为*,表明服务器接受所有域的请求。如果请求成功响应头部还有其他字段:Acess-Control-Allow-Methods(请求方式)、Acess-Control-Allow-Credentials(为布尔值,表示是否发送凭证,如cookie)等 。
cors使ajax跨域请求跟没有跨域请求一样。
cors有简单请求和非简单请求,两种请求的差异:
a。简单请求的请求方式只有get、put、head三种方式,非简单请求还有其他请求方式,比如delete,post
b。非简单请求在正是请求之前,会先进行一次“预请求”,询问服务器是否允许请求,接受的请求的方式有哪些等。然后才会进行正式的请求

cors优点:支持所有的http请求,而jsonp只支持get请求。
ajax怎么样设置可以发送cookie?
xhr.withCredentials = true

3.代理服务器——用到了两次跨域请求(客户端-》代理服务器;代理服务器-》服务器)
因为同源策略是浏览器需要遵循的原则,服务器并不需要遵循。所以,如果
step1:将客户端的请求交给代理服务器(客户端与代理服务器直接交互,用到cors)
step2:由代理服务器转发请求给服务器
step3:代理服务器接收服务器返回的数据
step4:将数据交给客户端
就可以进行跨域通信了。
这里说的代理服务器指的是,从客户端角度出发的代理服务器。负责转发客户端发出的请求。这时候客户端并不知道是哪个服务器给它返回的数据。

4.nginx反向代理
反向代理是从服务器角度出发,是从服务器向客户端返回请求结果。反向代理服务器是将请求结果返回给请求方。这时候服务器并不知道初始的请求方是谁。
参考:https://blog.csdn.net/wuliuwei1234/article/details/80803069

23.如何判断是否是一个数组
(1)instanceof
(2)constructor
(3)isPrototypeOf()
(4)Array.isArray()
var arr = [1,2,3,3]
//1.instanceof
console.log(arr instanceof Array) // true
//2.Array.isArray(arr)
console.log(Array.isArray(arr)) // true
// 3.constructor
console.log(arr.constructor === Array) // true
// 4.isPrototypeOf——测试arr对象是否存在于Array的原型链上
console.log(Array.prototype.isPrototypeOf(arr)) // true

24.for in和for of的区别
for-in读的是key值,遍历对象时读的是对象的属性名,遍历数组时,读的是数组的索引值(从零开始)
for-of读的是value,只能用来遍历数组,读的是数组的元素,不能用来遍历对象
var arr = [1, 2, 3]
var obj = {
name: ‘pipi’,
age: 18
}
for (var i in arr) {
console.log(i)
} // 0 1 2

    for (var i in obj) {
        console.log(i)
    }// name age

    for (var i of arr) {
        console.log(i)
    } // 1 2 3
    ƒ
    for (var i of obj) {
        console.log(i)
    } // 报错

25.for of什么时候用?
遍历数组、set、map、string、argumens
26.typeof null 是什么类型, 为什么
因为在js第一版的时候,是使用变量的二进制的前3位来区别数据类型。
000-object 100-string 010 -number 110-boolean
而null指向的地址全是0,所以被判定为object

27.es6你使用过什么api
箭头函数:
箭头函数和普通函数的区别:
(1)箭头函数内部的this是固定的,在定义函数时就确定了,this是定义函数时所在的对象,而不是函数的调用者。
(2)箭头函数不能做构造函数,就是不能使用new来创建对象,因为箭头函数没有prototype属性,也没有this,所以用箭头函数创建实例会报错。
(3)箭头函数不能使用arguments对象,可以使用rest代替
(4)箭头函数不能使用yield命令,所以箭头函数不能作为Generator函数

let、const关键字:
(1)let、const定义的变量有块级作用域,var声明的变量没有
(2)let、const定义的变量不可以变量提升
(3)let、const定义的变量不能重复定义否则会出错
(4)const定义的变量在定义时就必须马上赋值
(5)全局中let、const定义的变量会被放到script作用域中,而var定义的全局变量放到global中。

解构赋值:相当于庖丁解牛
把解构出来的值赋值给变量,可以解构数组,对象等
Promise

Set
Set是一种数据结构,它包含的一组不重复的数据。为此可以用来对数组、字符串等去重。
set有哪些方法?
(1)操作方法:
add(value)–添加成员,返回添加后的新的一组数
delete(value)–删除成员,有对应的元素删除返回true,否则返回 false
clear()–清除所有数据,返回undefined
has(value)–查看是否有某个成员
“题外话”:Array.from()–可以将Set结构转换成数组
例子:
var set = new Set([‘hello’, 2, 3, 4])
var set = new Set([‘hello’, 2, 3, 4])
console.log(set.add(555)) //{“hello”, 2, 3, 4, 555}
console.log(set.delete(‘hello’)) //true
console.log(set.delete(‘pipi’)) //false
console.log(set.has(2)) //true
console.log(set.clear()) //undefined

(2)遍历方法:keys() 、values()、entries()
keys()–返回键名
values()–返回键值
entries()–返回键值对,只是键名和键值的值是一样的
例子:
var set = new Set([‘hello’, 2, 3, 4])
var set = new Set([‘hello’, 2, 3, 4])
console.log(Array.from(set)) //[“hello”, 2, 3, 4]
console.log(set.keys()) //{“hello”, 2, 3, 4}
console.log(set.values()) //{“hello”, 2, 3, 4}
console.log(set.entries()) //{“hello” => “hello”, 2 => 2, 3 => 3, 4 => 4}
(3)forEach()–遍历成员
(map是迭代数组,对数组的每个元素进行操作,然后返回一个新的数组)
var set = new Set([1,2, 3, 4])
set.forEach((key,value)=>{
console.log(key+":"+value)
//1:1
//2:2
//3:3
//4:4
});
weakset是与set类似的数据解构,它的成员也是没有重复的。但是与set有两点区别:a。weakset的成员必须是类似数组的对象;b。weakset中的成员如果不再被引用就会被gc回收,所以它里面的成员是不稳定的。
const b = [3, 4];
const ws = new WeakSet(b);
console.log(ws) //报错

     const b = [[1,2],[3,4]];
    const ws = new WeakSet(b);
    console.log(ws)

weakset也有has(value)、add(value)、delete(value)方法

Map
map数据结构与Object类似,但是它不像Object只能将字符串作为键名,map数据结构的键名不局限于字符串,还可以是对象、数字等。
var map = new Map()
map.set(123, ‘pipi’)

    var obj = {
        name: 'xiaoxiannv'
    }
    map.set(obj, '3333')
    console.log(map) //0:{123 => "pipi"}  1: {Object => "3333"}

Map有哪些方法?
set(key,value) – 设置键值对
size()–成员个数
has(key) – 是否有某个键名
delete(key) --删除某个键名
clear() – 清除所有成员
WeakMap和map有两点区别:
a。WeakSet的键名只能是对象
b。WeakSet的键名执行的对象不计入垃圾回收机制(gc)

28.v-if 和v-show的区别
v-if:只有在条件为真的时候才会渲染然后显示,条件为假时什么都不做。即,只有条件为真才会存在dom中
v-show:不管条件真假都会渲染,只是通过真假来决定显隐。即条件真假与否都存在在dom中。
使用情况:如若切换显隐不频繁,使用v-if,这样可以节省编译成本。如果频繁切换v-show更适合,因为元素已经存在与dom中,只需要控制css的显隐即可。

29.父子组件之间相互传递数据(怎么实现的你知道吗?)
(1)props
(2)vue自定义事件
(3)消息订阅与发布-bus事件总线, e m i t 、 emit、 emiton发送和监听数据
(4)Slot
(5)Vuex
(6)$attrs $listenner(跨组件传递数据)

30.父组件向子组件传递数据,子组件用props接收,在子组件里,是无法修改props里的数据的,这个你知道吗
是的不能改变,即使在data中定义与props传递过来的属性同名的数据,也不能覆盖(改变)props传过来的数据。

31.vue里数据双向绑定的原理是什么
利用的是Object.defineProperty()对对象的属性进行设置,给对象添加set和get属性,并分别赋值一个函数,当该属性给操作时就会触发set函数,当属性被调用时就会触发get函数,利用这一点,可以把更新view的函数放到set中,只要属性发生改变就会触发view的更新。

32.原生js里,阻止冒泡的方法,阻止浏览器默认事件的方法
阻止冒泡:stopPropagation、return false
栗子:
var btn = document.getElementById(“demo”)
btn.οnclick=function(e){
e.stopPropagation() // 阻止冒泡,ie用cancelPropagation
}

var btn1 = document.getElementById(“demo”)
btn1.οnclick=function(e){
return false // 阻止冒泡
}

阻止默认行为:preventDefault()
栗子:
打开百度
var link= document.getElementById(“link”)
link.οnclick=function(e){
e.preventDefault() // 阻止默认行为,即不会打开www.baidu.com链接
}
33.apply,call,bind区别
首先三者的作用是一样的,都是改变函数的this
apply 和call的区别:
apply(this,pram1,pram2,…)或者apply(this,[pram1,pram1,…])或者apply(this,[arguments])
call(this,pram1,pram2,…) ——参数只能一一列举
bind:var fn = fn1.bind(this) ——bind不会马上执行
fn()

34.为什么会有事件委托,事件委托什么时候使用
什么是事件委托?
事件委托就是利用事件冒泡的原理,把同一类事件的处理程序绑定在一个尽量高层的节点上。让页面更快的获取事件处理程序,也减少了绑定事件处理程序的个数,减少了内存的使用,和绑定的事件和移除事件处理程序的时间。

为什么用事件委托?
a。事件委托可以节省绑定事件处理程序和移除事件处理的时间
b。document更快的找到事件处理程序,节省了查找时间
c。事件处理程序少,页面占的内存更小,性能更佳。
事件委托什么时候可以用?
处理同一类节点的事件的时候,比如列表项、表格项等重复性元素的事件处理程序。事件委托使用不当会导致事件误判,本不应该绑定的节点被绑上了某个事件处理程序。

39.BFC
(1)什么是bfc?
fbc是块级格式化上下文,说白了就是一个独立的盒子,盒子内部的布局和外部不相干:bfc内部的布局和bfc外部的布局不会相互影响。
(2)bfc有什么特点?
a。bfc内部的块级元素会依次从上往下垂直分布,而且上下的间距由magin决定
b。bfc会紧贴它的包裹元素的左边的border
c。同一个bfc内部的上下两个块级元素的垂直margin会发生重叠,比如给上div设置margin-bottom:20px;下div设置margin-top:20px;但是这两个元素的间距却不是40px而是发生了重叠而变小了。–解决该问题:给其中一个box加包裹层,然后触发bfc使它们俩处于不同的bfc就不会产生margin重叠了。
d。bfc不会与相邻的浮动模块相重叠——可以用来做栏布局
e。计算bfc高度时,内部浮动元素的高度也算在内–可以用清除浮动的影响
f。bfc相当于与外面隔离的容器,它内部的布局和它外部的布局不会相互影响。

(3)怎么触发bfc?
a。display:flex等
b。float:不为none
c。position:absolute、fixed
d。overflow:不是visible
e。根元素

(4)bfc能做什么?
a。实现一栏定宽,另一栏自适应的两列布局
左栏:width:定宽;
float:left;
右栏:overfloat:hidden/auto; // 触发bfc

b。清除浮动:触发包裹元素的bfc——计算bfc高度时,浮动元素的高度也算在内。
wrap:overflow:hidden(最常用)、display:inline-block/flex/table-cell、position:fixed/absolute
inner:float:left/right

c。解决两个块元素垂直margin重叠问题,触发两个box其中一个的bfc:
给其中一个box添加包裹层,然后触发包裹层的bfc,使两个box处于两个不同的bfc就不会发生margin重叠了。
40.什么是宏任务?微任务?
是js异步的一个机制,宏任务:setInterval、setTimeout、I/O、script(整体代码);微任务:promise、prosess.nextTick
在执行任务是,微任务会优先于宏任务被执行。

41.数组的方法
concat() 连接两个或更多的数组,并返回结果
join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔
pop() 删除并返回数组的最后一个元素
push() 向数组的末尾添加一个或更多元素,并返回新的长度
unshift() 向数组的开头添加一个或更多元素,并返回新的长度
reverse() 颠倒数组中元素的顺序:对原数组进行操作
var arr = [1,2,3,4,5]
var arrc = arr.reverse()
console.log(arrc) //[5,4,3,2,1]
console.log(arr) //[5,4,3,2,1]

shift() 删除并返回数组的第一个元素
slice() 从某个已有的数组返回选定的元素
sort() 对数组的元素进行排序  参数必须是个函数 arr_a.sort(function(a,b){return a-b}) //对元素组进行操作
var arr = [1,2,3,4,5]
var arrc = arr.sort((a,b)=>{
return b-a
})
console.log(arrc) // [5,4,3,2,1]
console.log(arr) // [5,4,3,2,1]
辅例:
function sortNumber(a,b)
{
return a - b
}
var arr = new Array(6)
arr[0] = “10”
arr[1] = “5”
arr[2] = “40”
arr[3] = “25”
arr[4] = “1000”
arr[5] = “1”
document.write(arr + “
”)
document.write(arr.sort(sortNumber))

splice() 插入 删除  替换  数组的元素。
toString() 把数组转换为字符串,并返回结果
数组插入数据的方法
push() 向数组的末尾添加一个或更多元素,并返回新的长度
unshift() 向数组的开头添加一个或更多元素,并返回新的长度
splice() 插入 删除  替换  数组的元素。

42.防抖和截流
函数节流:在事件触发一次后,在一定时间内不让事件重复触发,也就是在规定时间内,无论你操作几次,到点我才会触发。(另种思路:设置时间段=当前时间-最后操作操作的事件,当时间大于设置的时间)
// 节流函数
方法一:——设置固定时间内只发生一次
function throttle(fn,wait){
let timeout
return ()=>{
const context = this
const args = arguments
if(!timeout){ // timeout一开始!timeout为true,所以会执行,再次点击或多次点击时,time在一定时间内才会再一次被置为null,之后 if(!timeout)再会被执行
timeout = setTimeout(()=>{
timeout = null
fn.call(context,args)
},wait)
}
}
}
btn.onclick = throttle(fn,1000)

方法二:设置时间戳
function throttle(fn, delay) {
    // 记录上一次函数触发的时间
   let lastTime = 0;
   return()=>{      
       // 记录当前函数触发的时间
      let nowTime = Date.now()
      if (nowTime - lastTime > delay) {
           fn.call(this)  // 指定this指向
           // 重置时间
           lastTime = nowTime
      }   
  }   
}

防抖:用户在频繁操作使(在一定时间内),在最后一次操作时才会触发事件。比如,滑动只有在停止滑动后事件才会触发,否则滑动事件一直被触发。再比如重复点击,也只让最后一次点击事件生效。(怎么判断是最后一次操作。或者停止滑动?——设置事件间隔,在超过时间间隔就视为最后一次操作/停止操作)
防抖函数:
var btn = document.getElementById(“demo”)
let timer
btn.οnclick=()=>{
clearTimeout(timer)
timer= setTimeout(()=>{
// do sothings
alert(‘haha~重复点击是没有用的!’)
},1000)
}
封装成防抖函数:
function debounce (fn, delay) {
var timeout
return () => {
clearTimeout(timeout)
timeout = setTimeout(fn, delay)
}
}

var btn = document.getElementById(“btn”)
function fn1() {
alert(‘haha~重复点击是没有用的!’)

    }
    btn.onclick = debounce(fn1,1000)

43.vue生命周期(又叫钩子函数)
生命周期三个大的阶段:
(1)初始化阶段:beforeCreate()、create()、beforeMounted()、mounted()
a。new(创建)vue实例时,马上会调用beforeCreate();-这个名称有点混淆视听,因为并不是创建实例了才调用,而是创建时就调用。
b。初始化vue实例时会调用create();
c。调用beforeMounted(),判断是否有挂载点(el),没有的话手动挂载(调用$mount(el))–很少用,然后编译模版中的内容,才会挂载到页面上,此时调用mounted()

(2)数据更新:beforeUpdate()、updated()
数据更新才会调用,数据发生变化之前调用beforeUpdate(),发生变化之后调用updated()
(3)死亡:beforeDestroy()、destroyed()
–此时页面还是会显示,只是不再有数据绑定,也不再有交互了,这时候vm处于死亡状态。(与react有点区别,react移除后就不会显示)
在调用$destroy()时调用,在销毁vm之前调用beforeDestroy();销毁之后调用destroyed()
死亡阶段的beforeDestroy()可以进行一些收尾工作:比如,清除定时器等

总结:
a。beforeCreate()、created()、beforeMounted()、mounted()只会执行一次
b。beforeUpdate()、updated()–可能发生0次,也可能发生n次,要看有没有数据更新,this.xxx=value更新数据
c。beforeDestroy()和destroyed()只会执行一次,而且是调用了$destroy()才会执行。
d。Mounted()、beforeDestroy()——这两个回调函数最常用!:
Mounted():发送ajax请求获取数据、启动定时器等异步任务
beforeDestroy():进行一些收尾工作,如清除定时器

44.MVVM–实现数据变化更新视图,视图变化更新数据
mvvm解析参考来自:http://baijiahao.baidu.com/s?id=1596277899370862119&wfr=spider&for=pc
M:model-模版,即后台数据
V:view-视图
VM:ViewModel-视图模版
MVVM模式把视图和数据相互分离,不直接进行通信,而是通过vm来通信:vm将模版(后台数据)跟页面绑定,即将后台数据应用到页面上;页面上显示的内容也通过vm编程后台数据。vue就是基于mvvm的一个前端框架。
mvvm的思路:
1.通过数据绑定把后台数据显示在视图中
2.通过dom事件监听来收集视图中的数据

具体实现:通过Observer(观察者)劫持数据并监听–>通知订阅器Dep改变—>(Dep)通知Watcher(订阅者)更新数据–>(因为compile已经订阅了Watcher)Compile(解析器)更新视图
怎么劫持并监听数据?——利用Object.defineProperty()//对属性进行设置
var obj ={}
Obj.name=’’
Object.defineProperty(obj,“name”,{
set:function(value){ // 1.–属性变化
name =value
conosle.log(‘name属性已发生变化’)
},
get:function(){ // 2.–属性被调用
conosle.log(‘name现在的值为’+value)
}
})
obj.name=’pipi’ // 触发1.
console.log(obj) // 触发2.
当属性变化时,或触发set函数,那么利用这一点,就可以把更新数据的函数放到set中,这样数据改变视图就会被通知更新。
vue的实现是结合了数据劫持和订阅发布者的模式。
具体实现的例子:https://www.cnblogs.com/beevesnoodles/p/9844854.html
pipijie找的例子:https://www.cnblogs.com/zhouyideboke/p/9626804.html

45.标准盒子模型和旧版本的IE盒子模型的差别?
标准盒子模型:width只包括content区域
(盒子宽度=内容(content)宽度 + padding + border +margin)
IE盒子模型:width包括content部分,还包括了padding和border
(盒子宽度=内容宽度(content + padding+ border )+ margin )
46.box-sizing属性
它是选择盒子模型的属性,有两个值:content-box,border-box。默认值是content-box。
content-box就是css标准的盒子模型。设置width/height时,只是content(元素)的高度或者宽度;
border-box是IE盒子模型。设置width/height时,包括了content(元素) + padding + border

  1. 可以继承成的属性:color、font-zize、font-weight、text-align…
    不能别继承的属性:border、margin、padding、height、width…
    48.div如何水平居中?
    (1)块级元素:设置margin:0 auto --对元素本身
    行内元素:text-align:center
    浮动元素(行级元素设置浮动后也会变成块级元素):
    给浮动元素加一个包裹div,然后对包裹div设置和浮动元素一样的宽度,margin:0 auto;overflow:hidden;(不用设置高度)
    因为浮动元素已经脱离文档流,设置margin不起作用!
    (2)position:absolute方法
    设置父元素position:relative;子元素position:absolute;left:50%;margin-left:-半宽度
    (3)position:absolute + transform方法
    与(2)思路一样,最后一部不同:对子元素用transform:translate(-半宽度,0)。

49.position的值以及作用
static–默认状态,文档流从上向下布局,块级元素从上到下垂直分布,行内元素从左到右水平布局
relative–相对定位,以它自己原来的位置为参照,进行定位布局(top、bottom、left、right)–不脱离文档
absolute–绝对定位,以它最近的有position:relative的元素为参照,若不存在,就以浏览器窗口为参照,进行定位布局(top、bottom、left、right)–脱离文档
fixed–固定定位,以浏览器窗口为参照进行定位。–脱离文档

50.用css画三角形原理
div设置:
width:0;height:0; //这个很重要,否则div默认占一行的宽度
border-top、border-bottom、borde-left、border-right的宽度、形状一样,颜色不一样。得到一个由四个正三角形组成的正方形。把其中三条边的颜色设置为transparent透明,得到三角形

51.满屏品字布局
!!!设置body,html{height:100%;}----因为默认值是0,满屏不要设为100%的高度!!!!!
top:width:50%;height:50%;margin:0 auto;
bottom-wrap:width:100%;height:50%;
left 、right:width:50%;height:100%;float:left

代码实现:
css:
body,html{
		height:100%
	}
 #up{
 	width: 50%;
 	height: 50%;
 	margin: 0 auto;
 	background: pink;
 }
 #down_left,#down_right{
        width: 50%;
        height: 100%;
        float: left;
        background: blue;
    }
 #down_left{
        background: green;
    }

 html:
     <div id="up">up</div>
	 <div id="down_left">left</div>
	 <div id="down_right">right</div>

方式2:
html,body: height:100%;
top: width:50%; height:50%; margin:0 auto;
left:width:50%; height:50%;float:left;
right: width:50%; height:50%; overfloat:hidden; --触发bfc

52.为什么要初始化css?
用过的最简单的初始化:
body,html{
margin:0;
padding:0;
}
因为不同浏览器对标签的解析结果可能不同,初始化css目的是解决兼容性问题—不知道css初始化是什么东西,皮皮杰说暂时不用了解

53.display:none----不显示元素,也不分配文档空间。页面会重新布局–回流、重绘
visibility:hidden-----隐藏元素,不显示。元素还占文档流空间,也不不会重新布局–仅重绘
(重绘:重新渲染,回流:重新计算盒子的尺寸。回流肯定会重绘,重绘却不易当回流)

54.对BFC–block formatting content(块级格式化上下文)规范的理解?
BFC是一种css渲染机制,它相当于一个盒子,盒子里面的内容布局和盒子外面的布局不会相互影响。
生成BFC条件:
(1)float的值不是none–就是设置元素浮动
(2)position的值为absolute或fixed
(3)display值为inline-block、flex、table-cell, table-caption, inline-flex
(4)overflow:不是visible
(5)根元素
BFC特点:
(Box 是 CSS 布局的对象和基本单位,一个页面是由很多个 Box 组成的,有行级的box、块级的box)
(1)bfc盒子里面的box垂直方向从上到下布局,box垂直方向上的距离由margin决定
(2)bfc盒子里面相邻的两个box的margin会发生重叠
(3)元素的左外边界与包裹元素的左边界相接触,浮动元素也一样
(4)bfc区域不会和float元素重叠
(5)计算bfc高度时,浮动子元素的高度也计算在内
(6)bfc在页面上就是一个独立的容器,里面的内容和外面的内容不会相互影响
55.上下margin重合的问题
原理:在同一个bfc盒子中,margin会重合。
解决办法:给margin重合的元素各自加上一个div包裹层,然后设置overflow:hidden;触发bfc–两个元素不在同一个bfc里面就不会发生margin重合

margin重叠:
css:
#div_{
width: 100px;
height: 100px;
margin:100px;
background: pink;
}
html:

1

2

//这时候margin会重叠,两个div间距是100px

解决margin重叠:
css:
#div_{
width: 100px;
height: 100px;
margin:100px;
background: pink;
}
html:


1



2


//这时候margin不会重叠,两个div间距是200px

56.一个元素设置float后,会变成块级元素–即display的值为block

57…margin和padding适用于什么场景?
margin:
1)border外侧添加空白!!!
2)空白处不需要背景颜色
3)抵消两个盒子之间的空白–比如可以设置margin为负值来拉近两个盒子之间的距离
padding:
1)border内侧添加空白!!!
2)空白处需要背景颜色

58.::before和after:单冒号和双冒号的区别?作用?
::before–在伪元素前面添加内容
:before-- 在伪类前面添加内容
::before和:before的异同点:
相同点:
1.都可以向元素的前面添加内容
2.都要结合content:“添加内容” 一起使用
3.都不存在真实的对象,在dom树中找不到伪类或伪元素。
4.两个都是在css层面对页面产生影响,不会改变文档的结构。js也不能操作伪类和伪元素,因为节点根本不存在dom树中
栗子:p::before{
content: “hello!”;
}

不同点:
1.:before是css2的写法,::before是css3的写法,:before兼容性更好

59.有一个高度自适应的div,里面有两个div,一个固定高度,另一个填充满剩下的部分
div高度自适应,所以要先设置body,html{ height:100%;}!!!
父元素div:position:relative;height100%;—因为默认高度为0
里面固定高度的div直接设置高度,
高度自适应的div: position:absolute;top:固定div的高度值;
栗子:
css:
body,html{
height: 100%;
position: relative;
}
#up{
width: 100%;
height: 100px;
background: pink;
}
#down{
width: 100%;
position: absolute;
background: blue;
height: 100%;
top:100px;
}

   html:
      <div id="up">up</div>
      <div id="down">down</div>

60.style写在body前和body后有什么区别?
写在body前:因为html文档是从上到下解析的,写在body前,浏览器会先加载完css样式,然后在渲染html文档。
写在body后面:浏览器解析从上到下html文档,在解析到css样式时,页面会停止渲染。等加载完css样式后重新渲染。

61.怎么理解this ?this可以用在什么地方
函数中的this其实就是指向函数的调用者,在全局环境中定义一个函数,这时候this指向window;
在想改变函数的调用环境的时候用,比如,一个函数想使用对象中的一个变量,就可以只用apply()或者call()来改变函数的调用者。
例子:
var color=“red”;
var obj={
color:“pink”
}
function color_(){
console.log(this.color)
}
color_(); // red
color_.call(obj); //pink

62.对同步和异步的理解
同步:按照顺序执行一个个任务,这个任务没有完成就不会往下执行下一个任务
异步:可以改变任务的执行顺序,不需要等这个任务完成了再执行下一个任务。
例子:
setTimeout(func,time); //time毫秒后执行函数func,而不管页面有没有加载到这一句代码–改变了任务的执行顺序
(setInterval(func,time)–间隔time毫秒后反复执行函数func )

63.什么是模块化?
把实现某种功能的细节封装成单独的模块,使用时不需要知道里面封装了什么东西,只要调用就可以实现某种功能。而且每个模块不会相互影响,还可以反复使用。
例子:函数就是一个模块化的例子,写好一个函数,需要用的时候调用就可以了,不用重复编写,也不需要知道函数封装了什么具体内容。
64.call()和apply()
都可以指定函数的调用者,差别就是参数的传入方式
直接上栗子:
function say_color(a,b){
console.log(a+" and "+b);
}
function color_1(col_1,col_2){
say_color.call(this,col_1,col_2); //在全局环境中调用say_color函数,并把col_1,col_2两个参数一个个传给它(say_color)
say_color.call(this,[col_1,col_2]); //报错,call的第二个参数起,要一个一个传入

	   say_color.apply(this,col_1,col_2); //报错,因为apply第二个参数往后的参数是数组的形式或者类数组arguments的形式传入
	   say_color.apply(this,[col_1,col_2]);  //正确
	   say_color.apply(this,arguments);  //  正确
	}
	color_1("pink","green");  //pink and green

65.理解eval()函数
eval()作用:把字符串解析成js代码,然后执行js代码
var str=“1+2+3”;
console.log(str); //1+2+3
console.log(eval(str)); //6

	var str_1="document.write('hello world!')";
	eval(str_1);  // 页面会显示 helloworld!-----因为eval()会先把str_1字符串解析成js代码,然后执行代码

注意:应该避免使用eval(),因为会解析两次代码,第一次:把字符串解析成js代码,第二次:运行该js代码

66.用new操作符创建一个对象,经历什么步骤?
1.先创建一个空的对象,如:var person = {}
2.对象都有一个prototype属性,这个属性指向原型对象
3.原型对象有实例共享的属性和方法,它的constructor属性指向构造函数
4.然后执行构造函数,把构造函数的属性和方法继承给创建的对象
5.返回创建好的对象,person
过程:创建对象,其prototype属性–>原型对象,其constructor属性–>构造函数,构造函数把属性和方法继承给创建的对象,返回创建的对象。

67.H5和CSS3的一些特性
H5新增标签:

–网页头部
–网页尾部

68.lable标签
lable标签用来圈定一个范围,for属性的值是要绑定的元素的id值。比如:

喜欢什么食物?


chiken:
//当点击lable范围内的地方都会选到单选按钮

69.浏览器渲染页面的过程:
1)解析html文档,构建DOM树
2)解析CSS文档,构建css规则树
3)DOM树和css规则树结合起来生成渲染树
4)渲染树开始页面布局,然后显示在浏览器中
参考:https://segmentfault.com/a/1190000010298038

70.什么是Web标准?W3C标准?
Web标准把页面分为结构、表现、行为三个部分。
结构由html标签构成,页面的表现通过css表现,网页的行为–交互,主要由js完成。

W3C标准是一个标准的集合,对web标准提出了实际的规范要求:
比如:
HTML的标签要闭合,标签要求为小写,标签不可以随意嵌套
css、js尽量使用外部链入的形式,使结构、表现行为分离。

71.什么是内置函数?
内置函数是js封装好的函数,供开发者直接使用,例如:
Date() Array() Boolean() String() Object()等
72.=
console.log(1true); //true
console.log(1
=true); //false
73.this
this函数的调用者,在全全局环境中调用一个函数,这个时候this指向window
var obj={
name:“kendy”,
func:function(){
console.log(this); //此时this指向obj这个对象
}
}

apply和call的作用:改变this的指向
A.apply(B,参数),在B中调用A,并把参数传给A。参数可以是数组形式,也可以是arguments形式。
A.call(B,参数),在在B中调用A,并把参数传给A。参数必须一一列举出来。

还有bind函数,
var obj = {
color: “red”
}
function color() {
return this.color;
}
var func = color.bind(obj); //把color函数绑定在obj上,然后赋值给新的函数
console.log(func()); //red ,通过调用新的函数来改变this

74.事件练习
1.

    //点击out click的时候,会输出:1 2 1
    //label冒泡阶段输出1
    //input 在label内也会被点击到,输出2
    //input冒泡到label时又会输出1

    //点击inner click的时候,会输出2 1 
    //点击input时输出2 
    //input 点事件冒泡到label时会输出1

75.offsetHeight、scrollHeight、clientHeght的区别:
clientHeght=元素的height + padding
offsetHeight=元素的height + padding + border
scrollHeight=clientHeght + 滚动条遮拦起来的部分高度

76.target和currentTarget的区别:
target:事件触发的dom元素
currentTarget:绑定事件的元素

77.怎么让Chrome显示小于12px的字体?
利用css3的transform:scale(n)或者translate:scale(x,y)
例如:
p{
fontsize:12px;
transform:scale(.5) // 显示的大小为12*0.5 = 6px
}
div{
width:100px;
height:100px;
transform:scale(2,3) // div显示的大小为:width–200px;height–300px
}
78.关于数字、字符、数组等的运算
(1)+
参与运算的字符串,它在第一位,且只要它前面没有正负号,+就会被当作连接符。例子:
console.log(‘1’ + 2) // 12
console.log(1 + ‘2’) //12
console.log(+‘1’ + 2) //3
console.log(-‘1’ + 2) //1
console.log(true + 1) //2
console.log( true+ ‘1’) //true1

(2)-、*、/
遇到字符串都会被转换成数字然后再运算。例子:
console.log(‘3’ - 2) // 1
console.log(1 - ‘3’) //-2
console.log(-‘3’ + 2) //-1

    console.log('3'*2) // 6
    console.log(-'3'*2) //-6
    console.log(-'3'*-2) //6

     console.log('4' / 2) // 2
     console.log('-4' / 2) // -2
     console.log(-'4' / 2) // -2

总结:
a。跟字符串进行运算,只有进行相加+操作时,才会被转换成字符串然后拼接成另一个字符串。(特殊操作的字符数前有+、-而没有其他数了,才会把该自负传换成正负数然后参与运算)
b。只有进行加运算时要小心,-、*、/都是转成数字后再运算。

79.pomise题目
setTimeout(function() {
console.log(0);
}, 0);
var promise = new Promise((resolve, reject) => {
console.log(1);
setTimeout(function () {
var success = true;
if (success) {
resolve(‘成功’);
} else {
reject(‘失败’);
}
},2000);
}).then(
(data) => { console.log(data)},
(data) => { console.log(data)}
);
console.log(promise); // 进行中
setTimeout(function () {
console.log(promise); // 已完成
},2500);
console.log(2);

输出顺序: 1 promise 2 0 成功 promise
(读题时画出流程图)
80.px em rem
px 像素值,它是屏幕上的一个点的大小,是固定的,不会随其他属性改变;
em ,是是相对于父元素的字体大小,是不固定的,会随父元素变化;
rem,是相对跟元素的字体大小,也是不固定的,会随父元素变化。(浏览器默认:1rem = 16px)
怎么实现适配?
思路:js获取屏幕的宽度,然后设置根元素(html)大小。然后页面中使用rem做单位。

81.clientWidth = width + padding
offsetWidth = width + padding +margin

82.ComonJS AMD CMD ES6模块是什么?
(1)conmonJS的思想是模块化,将实现的某个功能的代码封装成一个个模块。
模块通过module.exports或者exports{…}暴露出去,在需要的页面通过requres引入进来,然后调用。
conmonJS特点:以同步的方式加载,等加载完毕才会执行requres后面的代码。
利用:封装js模块,然后exports出去,在需要的页面requres引入并调用。

(2)AMD- Asynchronous Module Definition(异步模块定义)
通过define()来定义模块,然后return出去,通过requres()来加载模块
define([‘module’], function() {
let name = ‘pipi’;
function sayName() {
console.log(name);
}
return { sayName }
})

// 通过 require 引入依赖
require([‘module’], function(mod) {
mod.sayName(); // pipi
})
AMD特点:异步加载模块,模块加载不影响后面代码的执行。

(3)CMD与ADM类似,也是但是不同点:哪里用到依赖就加载哪里的依赖,AMD是先异步加载依赖。
(4)es6模块
通过export或export defalt将模块暴露出去,在需要的地方import进来。
例子:vue的组件开发。

83.es6的Generator
generator函数是有function创建的函数,普通函数有声明和执行两个状态,并没有函数暂停执行的办法,但是generator函数却可以做到然后函数暂停执行,并且返回多个执行的结果。
function
fn(a, b) {
yield a + b
yield a - b
yield a * b
yield a / b
}
var f1 = fn(1, 2)
console.log(f1.next()) //{value: 3, done: false}
console.log(f1.next()) //{value: -1, done: false}
console.log(f1.next())//{value: 2, done: false}
console.log(f1.next())//{value: 0.5, done: false}
console.log(f1.next()) //{value: undefined, done: true}

gennerator函数的暂停执行功能是有yield关键字实现的,generator函数通过函数实例.next()方法来调用执行,并且执行时遇到yield时就会暂停,并且返回yield前面声明的结果。再次使用.next()调用时才会往下执行,然后遇到yiled暂停并返回结果。next()方法可以实现generator函数的分段执行。
generetor函数返回的结果是一个对象,对象包括一个value和布尔值。value 代表yeild前面执行的得到的结果,布尔值代表generator函数已经执行完内部的yield,即没有yield可以被执行了才会返回{value:undefined,done:false}
Generator函数可以实现异步编程:
function* asyncJob() {
// …其他代码
var f = yield readFile(fileA); // 在遇到yield指令时把线程的执行权交出去,这里实现异步
// …其他代码
}
asyncJob是一个线程,遇到yiled时把执行权交出去(暂停和执行)–实现异步

84.ES6的class继承
Q1:什么是语法糖?就是在某个语法的基础上变换了写法,但是实现的功能是一样的,改变后的写法更简洁、更容易理解、更方便易懂。比如箭头函数是普通函数的语法糖,解构赋值是变量赋值的语法糖。
class Father {
constructor(name, age) {
this.name = name
this.age = age
}
getName() {
return this.name
}
static name1 = ‘小仙女’
}
console.log(typeof Father ) // function
console.log(Father.prototype.construnctor ===Father ) // true

    var son1 = new Father('pipi', 18)
    console.log(son1)
    console.log(son1.getName) 

/* 返回一个函数 getName() {
return this.name
}*/
console.log(son1.getName()) // 返回pipi
console.log(son1.name1)
// undefined 类中用static声明的变量和方法,实例读不到,只有类本身能读到
console.log(Father.name1) // 小仙女
console.log(son1 instanceof Father) // true

用class声明一个类,它是一个对象,对象中constructor是创建的实例获得的属性,constructor外面声明实例可以获得的方法。
注意:
a。class必须使用new来创建实例!es5中直接调用构造函数不会出错,但是es6直接调用类回报错!
b。类不存在变量提升
c。静态方法中的this指向类,不指向实例!
d。constructor构造函数是class默认的属性,声明class若不写,则会默认创建一个空的对象,例子
class Father { // 不写constructor时
}//相当于:
constructor () {
return Object.create(null)
}
var son1 = new Father()
console.log(son1 instanceof Father) // true
console.log(son1) // Father {}

!!!class继承:
在声明子类时,使用extends说明要继承父类,然后在constructor中通过super继承父类构造函数中的属性和方法
例子:
class Father {
constructor(name, age) { // 构造函数代表构造方法
this.name = name // this代表实例对象
this.age = age
}
getName() {
return this.name
}
static phone = 1234
getNum() {
return this.phone
}
}
class Son extends Father { //Son 是基于Father 的子类,在调用super之前this不存在
constructor(name, age, sex) {
this.sex = sex // 报错,因为Son 是基于Father 的子类,在调用super之前this不存在
super(name, age)
//相当于Father.call(this)、或Father.prototype.constuctor.call(Son)
this.sex = sex
}
}
var son1 = new Son(‘pipi’, 18, “female”)
console.log(son1) //{name: “pipi”, age: 18, sex: “female”}
console.log(son1.getName()) // pipi
console.log(son1.getNum()) // undefined
class继承与js借用构造函数继承的区别:
借用构造函数继承思想:在子类构造函数中利用call去调用父类构造函数实现继承,即把父类构造函数的属性和方法添加到子类的this中,然后再去创建实例;具体:a。new一个空的对象–》b。把构造函数的prototype赋值给实例的__proto__ --》c。把构造函数的this赋值给实例 --》d。执行构造函数 --》return 创建好的实例对象

class继承的思想:通过super去把父类的属性和方法拿过来,然后再去创建实例。
具体:把父类实例对象上的属性和方法添加到this,然后在子类构造函数中修改this。

super 关键字:
两个用法:a。做函数用 b。做对象用
a。做函数用时,它代表父类构造函数
注意:
子类中必须包含super函数
(在基于父类的子类中,在调用super之前是没有this的)
子类的super只能在constructor(构造函数)中使用
子类的super的this指向子类实例

b。做对象用
class Father {
p(){
return ‘pipi’
}

    }
    class Son extends Father {
        constructor() {
            super()  // 辞职super指向Father .prototype
            console.log(super.p()) // super.p()相当于Father.prototype.p()
        }
    }
    var son1 = new Son() // pipi 

85.async await
async 函数它也是函数,调用也会被执行,只是它返回的结果是一个promise对象。async函数执行时遇到await就会停下来,等await语句得到结果后才往下执行。
例子:
function sayHello() {
console.log(1)
}
async function say() {
let greet = await sayHello()
console.log(2)
}
say()
console.log(3)
//输出顺序:1 3 2
分析:因为async中有await所以1肯定是第一个输出的;然后2是promise中的,而3是同步代码中的,所以3会被先输出。
项目中向后台请求数据的时候用到async-await,将从后台请求的结果赋值给await,当await完成后才会执行后面的代码,如将结果commit给mutation。

86.symbol-生成唯一的标识
注意:Symbol创建实例不能用new!!!!
let s1 = Symbol(‘pipi’)
let s2 = Symbol(‘pipi’)
console.log(s1 == s2) //false
console.log(s1 === s2) //false

2.87.怎么对checkbox全选或反选(js原生操作回去看!)
var boxs = document.getElementsByTagName(‘input’)
//全选
function checkAll() {
for (var i = 0, n = boxs.length; i < n; i++) {
boxs[i].checked = true
}
}
var btn = document.getElementById(‘checkAll’)
btn.onclick = checkAll
//全不选
function noCheck() {
for (var i = 0, n = boxs.length; i < n; i++) {
boxs[i].checked = false
}
}
var btn1 = document.getElementById(‘noCheck’)
btn1.onclick = noCheck
//反选
function noCheckAll() {
for (var i = 0, n = boxs.length; i < n; i++) {
if (boxs[i].checked) {
boxs[i].checked = false
} else {
boxs[i].checked = true
}
}
}
var btn2 = document.getElementById(‘noCheckAll’)
btn2.onclick = noCheckAll
88.各个浏览器的内核是什么?这个都不知道还好意思说你是做前端的。
Chrome:Blink
Opera:Blink
Safari:Webkit
Firefox:Gecko
IE:Thrident
(CB OB FG SW IT)
89.取ul的最后一个li
(1)ul :last-child()//ul后面必须跟一个空格,否则失效
(2)var nodeList = document.getElementsByTagName(‘li’)
var target
console.log(nodeList.length) // 3
for (var i = 0; i < nodeList.length; i++) {
if (i === nodeList.length - 1) {
target = nodeList[i] // 取到最后一个li
}
}
90.两个变量交换值不需要第三个变量
var a=1,b=2;
[a,b]=[b,a] // a=2,b=1

91.js原生
(1)switch语句:
switch(value){
case value>0:
alert(‘xxx’);
break;
case value<0:
alert(‘xx’);
break;
defualt: alert(‘false’)

}
(2)classList的操作://所有元素都有classList属性
a。添加类名:div.classList.add(‘demo’)
b。查看是否存在类名:div.contain(‘demo’) //返回布尔值
c。去掉类名:div.classList.remove(“demo”)
d。动态取决添加/删除类名:div.classList.toggle(“demo”) //有demo就删除,没有就添加

(3)document.fucus()–元素获得焦点
(4)添加/读自定义属性
添加:以‘data-’开头
读:以‘dataset’来读
例子:

var div = document.getElementById(“myDiv”);
//取得自定义属性的值
var appId = div.dataset.appId;
var myName = div.dataset.myname;
console.log(appId) //undefined
console.log(div.dataset.myname) //undefined
//在标签上设置的自定义的属性不可见,与渲染无关,但是可以提供语义信息
//设置值
div.dataset.mgage = 18;
//有没有"mgage "值呢?
if (div.dataset.mgage) {
console.log("im " + div.dataset.mgage); // im 18
}

(5)innerHTML outerHTML
innerHTML替换目标元素的里面的内容
outerHTML替换整个目标元素

(6)querySlector()、querySlectorAll()、matchesSlector()
querySlector() --只会获取到第一个匹配的元素
querySlectorAll()–找出所有匹配的元素,即返回的是nodeList
matchesSlector() – 检查是否有匹配的节点,返回一个布尔值
(7)js原生添加样式
btn.style.color=”red”
92.js异步编程有哪几种?
回调函数、promise 、事件监听、发布订阅、ES6的Generator函数
93.Diff-待完善!!!
参考:https://www.cnblogs.com/wind-lanyan/p/9061684.html
Q1:diff是什么?
是一种算法
Q2:diff是干嘛的?
当数据改变时,diff算法会触发patch函数去比较新旧节点有没有变化,如果有变化进行布丁,而不是整个dom去重新渲染。
Q3:diff是怎么工作的?
逐层去比较节点是否发生变化(不是跨层比较),若有则进行替换,将新的数据替换旧的数据。

94.路由懒加载
路由懒加载就是延迟加载(延迟到需要的时候)、动态加载、需要的时候才加载(按需加载)
解决方案:
把引入组件的动作封装在一个函数中,并赋值给一个变量,然后把该变量赋值给路由配置中对应的component。因此只有在路由跳转的时候才会去触发引入组件这个动作。这样就可以做到按需加载。
例子:
import Vue from ‘vue’
import Router from ‘vue-router’
Vue.use(Router)
const HelloWorld = ()=>import("@/components/HelloWorld")
export default new Router({
routes: [
{
path: ‘/’,
name: ‘HelloWorld’,
component:HelloWorld
}
]
})

95.动态路由
a。在路由配置时使用动态参数的的路由路径,如path:‘/header/:id’-id是动态的。
b。在路由跳转时, path会去匹配动态路由然后实现跳转
routes:[ // 把所有的路由放到一个数组中
{path:’/home/:id’,component:Home},
])


//动态路由多用来解决多个路由跳转到同一个页面(组件)。

96.嵌套路由
对外层的路由添加childred属性来配置被潜逃的子路由:path、component

97.路由的基本配置
(1)安装vue-router:npm install vue-router --save
(2)在router文件夹中index.js配置路由:
a。引入vue
b。引入vueRouter
c。export default new Router(
routes:[ // 把所有的路由放到一个数组中
{path:’/home’,
component:Home},
{path:’/header,
component:Header},
{path:’/footer,
component:Footer,
child:{
path:’/child,
component:Child,
}}
])
//有嵌套路由时使用child属性,并添加child组件的路径和组件名称
// 会匹配到路由配置中的顶级路由,上面的例子会匹配到Home、Header、Footer,是这个意思吗????

(3)在页面中使用去跳转,router-link就相当于一个a标签。
98.页面输入url到页面显示新的内容经历了什么?
浏览器接收到url --> 分析url --> 交给DNS域名解析系统,把域名解析成ip地址 --> 使用ip地址建立tcp连接(三次握手 --> 浏览器发起http请求 --> 浏览器获取服务器响应资源 --> 关闭tcp连接(四次挥手) --> 解析资源文件(如html、css文件) --> 浏览器渲染页面

99.DNS解析域名的过程
浏览器接收到url时,首先在自己的缓存中查找有没有对应的ip地址(如果之前访问过这个域名而且没有删除记录,就可以查找到),如果没有找到,
就到操作系统中host文件下查找(host文件会保存常用的域名对应的ip地址),如果找不到,
就到路由器缓存中查找,如果找不到,
就到ISP 域名服务器上去找(网络服务运营商,如中国移动、联通等),如果还是找不到,
直接到根域名服务器上去找(根域名服务器是最高层次的域名服务器),找到就返回给本地域名服务器,找不到就告诉本地域名服务器应该去哪个顶级域名去查找,并把告知本地域名服务器该ip地址,
如果能在顶级域名服务器上找到,就返回这个ip地址,如果没有找到,顶级域名服务器就会告诉本地域名服务器应该去哪个主域名服务器去找,并把这个主域名的IP地址告诉本地域名服务器,
如果,主域名服务器还是找不到,就以同样的方式告诉本地域名服务器去哪里找。(主域名服务器就是分管一个固定范围内的域名的服务器)
本地域名服务器找到IP地址后,先保存下来(保留给下次访问使用),然后返回给浏览器。

100.(1)
var x = 10;
function fn(){
  console.log(x);
}
function show(f){
  var x = 20;
  f();
}
show(fn); //10

(2)
var fn = function(){
  console.log(fn)
}

fn();
var obj = {
  fn2:function(){
    console.log(fn2);
  }
}
obj.fn2(); //报错因为在全局中调用fn2,但是全局中并没有fn2
答案:
fn = function(){
  console.log(fn)
}
console.log(fn2);报错
理解:默认指向window,而全局中没有fn2这个方法,所以报错。改成console.log(this.fn2)可以打印出fn2函数

(3)
var name = “The Window”;
var object = {
  name:“My Object”,
  getNameFunc:function(){
    return function(){
      return this.name;
    }
  }
}
console.log(object.getNameFunc()());

答案:The Window

函数内,this默认指向window

改成:

getNameFunc:function(){
    return this.name;
  }

则打印 My Object
(4)
var A = function(){}
A.prototype.n = 1;
var b = new A();
A.prototype = {
  n:2,
  m:3
}
var c = new A();
console.log(b.n,b.m,c.n,c.m);
答案:1 undefined 2 3
理解:A.prototype.n = 1;时,开辟一个内存块,该内存块内容为n=1,A.prototype指向该内存块。var b = new A();时,b的隐式原型链指向该内存块。
A.prototype = {
  n:2,
  m:3
}时,开辟一个内存块,该内存块内容为n:2,m:3,A.prototype指向该内存块。var c = new A();时,c的隐式原型链指向该内存块。

(5)
var F = function(){};
Object.prototytotype.a = function()
{
  console.log(‘a’);
}
Function.prototytotype.b = function()
{
 console.log(‘b’);
}
var f = new F();
f.a();
f.b();
F.a();
F.b();

答案:

f.a(); 打印a

f.b();报错

F.a(); 打印a

F.b();打印b

理解:原型链最终指向object

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值