css
1. 水平,垂直居中的方式,各4种?
水平居中
text-align:center;(行内元素)margin: 0 auto;(块级元素)
position:absolute; left: 50%; margin-left: -xxpx; transform:translateX(-50%)
display:flex;justify-content:center;
- 垂直居中
line-height = height
position: absolute; top: 50%; margin-top: -xxpx; transform: translateY(-50%)
display: flex; align-items: center;
2. 1rem 1em 1vh 1px 各自代表的含义?
rem
rem大小相对于<html>根元素,通常是给根元素设置一个大小,其它元素长度就为rem
em
子元素大小的em是相对于父元素字体的大小
vw/vh
视窗的宽度和高度 1vw/vh相当于屏幕宽度/高度的1%
ps: 处理宽度百分比合适,处理高度vh
px
相对长度单位,像素px是相对于显示器屏幕分辨率而言的
3. 画一条0.5px的边?
height: 1px;
4. 盒模型?
盒模型的组成,由里向外content,padding,border,margin.
在IE盒子模型中,width表示content+padding+border这三个部分的宽度
在标准的盒子模型中,width指content部分的宽度
box-sizing: border-box; 是IE盒模型 box-sizing: content-box; 是标准盒模型
.xx {
width: 0;
height: 0;
border-width: 100px;
border-style: solid;
border-color: #000 transparent transparent transparent;
// transform: rotate(90deg)
}6. 伪类选择器?
7. 清除浮动有哪些方法?
- 给父元素设置宽高,或者给父元素设置 overflow:hidden
<div style="clear: both"></div>.clear:after{ content: ''; display: block; clear:both; }
8. css实现图片自适应宽高
img {
max-width: 100%;
max-height: 100%;
}9. flex? 常见属性及作用
弹性布局,用来为盒状模型提供最大的灵活性
设为Flex布局以后,子元素的float、clear和vertical-align属性将失效
巴拉巴拉
html
1. <label>标签的用法
方便鼠标点击使用,扩大可点击的范围,增强操作体验
2. 遍历A节点的父节点下的所有子节点
<script>
var b = document.getElementById('b').parentNode.children
consoel.log(b)
</script>3. 页面渲染html的过程 ?
4. 行内元素与块元素有什么区别?
- 行内元素会在同一行上水平排列(默认宽度只与内容有关)
- 块级元素各占一行
- 块级元素可以包含行内元素和块级元素。行内元素不能包含块级元素,只能包含文本或者其它行内元素
- 行内元素与块级元素属性不同,主要是盒模型属性上:行内元素设置 width/height 无效(可以设置 line-height),margin 上下无效,padding 上下无效
5. link 和 @import 的区别
link是html的标签,@import是css的语法规则;
加载页面时,link是同时加载的,@import是页面加载完后才加载
link没有兼容性的问题,@import只在较高版本的浏览器才可以识别
link可以通过js插入操作dom,@import 不可以
js
1. 事件代理?
事件委托是指将事件绑定到目标元素的父元素上,利用冒泡机制触发该事件
<div id='div' onclick='alert("div");'> <ul onclick='alert("ul");'> <li onclick='alert("li");'>test</li> </ul> </div>单击test时,会依次触发alert(“li”),alert(“ul”),alert(“div”),这就是事件冒泡。
阻止冒泡:
window.event? window.event.cancelBubble = true : e.stopPropagation();
2. target、currentTarget的区别?
currentTarget当前所绑定事件的元素
target当前被点击的元素
两者在没有冒泡的情袭况下,是一样的值,但在用了事件委托的情况下,就不一样了:
<ul id="ulT"> <li class="item1">fsda</li> <li class="item2">ewre</li> <li class="item3">qewe</li> <li class="item4">xvc</li> <li class="item5">134</li> </ul> <script type="text/javascript"> document.getElementById("ulT").onclick = function (event) { console.log(event.target); console.log(event.currentTarget); } </script>event.target返回的是点击的元素节点
4. 闭包
闭包的实质是因为函数嵌套而形成的作用域链
函数 A内部有一个函数B,函数B可以访问到函数 A 中的变量,那么函数B就是闭包
function a() { var i = 0; function b() { alert(++i); } return b; } var c = a(); c(); 函数b嵌套在函数a内部;
函数a返回函数b。这样在执行完var c=a()后,变量c实际上是指向了函数b,b中用到了变量i,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。
当函数a的内部函数b被a外的一个变量引用时,就创建了一个“闭包”。
闭包的作用和效果?
闭包的作用就是在a执行完并返回后,闭包使得js的垃圾回收机制不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。
在上面的例子中,由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。
通过保护变量的安全,实现JS私有属性和私有方法(不能被外部访问)
5.export和export default的区别
export default XXX
import XXX from 'a.js'
export xxx
import {xxx} from 'b.js6. 数组去重
var arr=['12','32','89','12','12','78','12','32'];
// 最easy
function unique1(array) {
var temp = [];
for(var i = 0; i< array.length; i++) {
if(temp.indexOf(array[i]) === -1) {
temp.push(array[i])
}
}
}
arr = unique1(arr)
function dedupe(array) {
return Array.from(new Set(array)); //Array.from()能把set结构转换为数组
}
arr = depude(arr)
7. get、post的区别
get传参方式是url传递,可以看到传递参数,通过?连接,&分割参数,安全性低;
post将参数存放在http的包体内,安全性高;
get对传递的数据长度有大小限制,post没有长度限制;
get后退不会有影响,post后退会重新提交;
get请求的记录会留在历史记录中,post不会留在历史记录;
get只支持ASCII字符,post没有字符类型限制;
8. http的响应码及含义
1xx (临时响应)
2xx (成功)
200:正确的请求返回正确的结果
202:请求是正确的,但是结果正在处理中,这时客户端可以通过轮询等机制继续请求
3xx 已重定向
4xx 请求错误(客户端类)
400:请求出现错误,eg: 请求头不对
401:没有提供认证信息。eg: 请求的时候没有带上 Token
403:请求的资源不允许访问。就是说没有权限。
404:请求的内容不存在。
5xx 服务器错误(服务器端类)
9. 同步与异步的区别
同步: 按照任务的顺序执行任务,后一个任务要等待前一个任务执行结束
异步:执行顺序不确定,异步处理可以同时执行多个
同步执行效率低,耗时间,但有利于流程控制;
异步效率高,节省时间,但是会占用更多的资源,不利于进程控制
10. 什么是变量提升
先来两个例子:
var v='hello';
(function(){
alert(v);
})() // hello
var v='Hello World';
(function(){
alert(v);
var v='I love you';
})() // undefined
变量提升,很简单,就是把变量提升提到函数的top的地方。变量提升, 只是提升变量的声明,并不会把赋值也提升上来。
我们定义三个变量:
(function(){
var a='One';
var b='Two';
var c='Three';
})()实际上这样的:
(function(){
var a,b,c;
a='One';
b='Two';
c='Three';
})()补充:函数提升
函数提升是把整个函数都提到前面去。
在我们写js 的时候,有两种写法,一种是函数表达式,另一种是函数声明方式。要注意的是,只有函数声明形式才能被提升。
函数声明方式提升【成功】
function myTest(){
foo();
function foo(){
alert("我来自 foo");
}
}
myTest(); // 我来自 foo函数表达式方式提升【失败】
function myTest(){
foo();
var foo =function foo(){
alert("我来自 foo");
}
}
myTest(); // typeError: foo is not a function
11. call,apply,bind的用法与区别
call,apply,bind这三个方法其实都是继承自Function.prototype中的,属于实例方法。
1 console.log(Function.prototype.hasOwnProperty('call')) //true
2 console.log(Function.prototype.hasOwnProperty('apply')) //true
3 console.log(Function.prototype.hasOwnProperty('bind')) //true普通的对象,函数,数组都继承了Function.prototype对象中的三个方法,所以这三个方法都可以在对象,数组,函数中使用
1. Function.prototype.call() 改变this指向
函数实例的call方法,可以指定该函数内部this的指向,然后在所指定的作用域中,调用该函数。并且会立即执行该函数
var keith = {
rascal: 123
};
var rascal = 456;
function a() {
console.log(this.rascal);
}
a(); //456
a.call(); //456
a.call(null); //456
a.call(undefined); //456
a.call(this); //456
a.call(keith); //123call()方法可以传递两个参数。
第一个参数是指定函数内部中this的指向(也就是函数执行时所在的作用域),
第二个参数是函数调用时需要传递的参数。
function keith(a, b) {
console.log(a + b);
}
keith.call(null, 1, 2); //3第一个参数是必须的,可以是null,undefined,this,但是不能为空。设置为null,undefined,this表明函数keith此时处于全局作用域。第二个参数中必须一个个添加。而在apply中必须以数组的形式添加。
2.Function.prototype.apply()
和call一样,唯一区别是第二个参数接收一个数组
function keith(a, b) {
console.log(a + b);
}
keith.apply(null, [1, 2]); //3举个应用例子:
找出数组中的最大数
var a = [2, 4, 5, 7, 8, 10];
console.log(Math.max.apply(null, a)); //10
console.log(Math.max.call(null,2, 4, 5, 7, 8, 10)); //10
Javascript中是没有提供找出数组中最大值的方法的,
结合使用继承自Function.prototype的apply和Math.max方法,就可以返回数组的最大值。将数组的空元素变为undefined
console.log(Array.apply(null, [1, , 3])); // [1, undefined, 3]
空元素与undefined的差别在于,数组的forEach方法会跳过空元素,但是不会跳过undefined和null。
遍历内部元素的时候,会得到不同的结果
3.Function.prototype.bind()
bind方法用于指定函数内部的this指向,然后返回一个新函数,bind方法并非立即执行一个函数。
1 var keith = {
2 a: 1,
3 count: function() {
4 console.log(this.a++);
5 }
6 };
7
8 keith.count(); //1 this指向keith 对象
9 keith.count(); //2
10 keith.count(); //31 var keith = {
2 a: 1,
3 count: function() {
4 console.log(this.a++);
5 }
6 };
7
8 var f = keith.count;
9 f(); //NaN // this指向window对象,window.a = undefined
var f = keith.count.bind(keith);
f(); //1
f(); //2
f(); //3当然,this也可以绑定到其他对象上。
var obj = {
a: 100
};
var f = keith.count.bind(obj);
f(); //100
f(); //101
f(); //102 function keith(a, b) {
return a + b;
}
console.log(keith.apply(null,[1,4])); //5
console.log(keith.call(null,1,4)); //5
console.log(keith.bind(null, 1, 4)); //keith()
console.log(keith.bind(null, 1, 4)()); //512. promise 原理
回调函数: 将函数A当作参数给函数B调用,A就是回调函数
1. 具名回调
function B(fn) {
fn('hahaha')
}
function A(str) {
console.log(str)
}
B(A) // hahaha
2. 匿名回调
function B(fn) {
fn('hahaha')
}
B(function(str) {
console.log(str)
})
promise解决问题:回调火车
getData1(data1 => {getData2(data1, data2 => {getData3(data2, data3 => {
getData4(data3, data4 => {
getData5(data4, data5 => {
// 终于取到data5了 }) }) }) }) })
假设上面的任务,想要换一下执行顺序,代码修改起来,就比较麻烦了。如果内容复杂,阅读代码的时候跳来跳去,也让人头大。
如果用promise
getData1() .then(getData2) .then(getData3) .then(getData4) .then(getData5) .then(data => { // 取到最终data了 })
promise原理: promise是一个构造函数,用来生成promise实例。
通过在函数内部return一个promise对象实例,就可以使用promise的属性和方法进行下一步操作了。
function fnA() {
return new Promise(function(resolve, reject) {
if (成功) {
resolve(value) // 异步操作成功时调用,把结果作为参数传递出去
}else {
reject(error) // 异步失败时调用,把错误作为参数传递出去
}
})
}- 调用构造函数得到实例的同时,作为参数的函数会立即实行;
- 参数函数接受两个回调函数参数resolve和reject;
- 在参数函数被执行的过程中,如果在其内部调用resolve,会将实例的状态变成fulfilled,调用reject,会将实例的状态变成rejected;
- 调用resolve和reject能将分别将promise实例的状态变成fulfilled和rejected,只有状态变成已完成(即fulfilled和rejected之一),才能触发状态的回调
- 调用.then可以为实例注册两种状态,当实例的状态为fulfilled,会触发第一个函数执行,当实例p的状态为rejected,则触发第二个函数执行。
所以promise就是一种异步编程模式。
promise实例有3种状态
pending(待定) fullfilled(已执行) rejected(已拒绝)
- 1个构造函数: new Promise
- 2个实例方法:.then 和 .catch
- 4个静态方法:Promise.all、Promise.race、Promise.resolve和Promise.reject
13. 各类排序
- 冒泡排序 时间复杂度O(n^2)
- 选择排序 时间复杂度O(n^2)
www.jianshu.com/p/d2cf77f78…工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
原型链
深度克隆
跨域
http相关
vue
react
git
cookie
vue
1. 生命周期
beforeCreate: vue元素的挂载元素el和数据都为undefined,还未初始化;
created:vue实例的数据对象data有了,el还没有;
beforeMount:vue实例的$el和data都初始化了,但还挂载在之前的虚拟dom节点上;
mounted:vue实例挂载完成。
更新前后:data变化时会触发beforeUpdate和updated方法;
销毁前后:beforeDestory和destoryed,在执行destoryed方法后,对data的改变不会触发周期函数,说明vue实例已经解除了事件监听以及dom绑定,但是dom结构依然存在;
vue生命周期的作用: 他的生命周期中有多个事件钩子,让我们控制整个vue实例的过程时更容易形成良好的逻辑
nextTick:更新数据后立即操作dom
2. computed和watch的区别
computed 计算结果并返回,只有被计算的属性发生改变时才会触发
watch 监听某一个值,监听的值发生变化时,执行相关操作
监听简单数据类型:
data() {
return {
val: '2'
}
},
watch: {
val() {
console.log(this.val)
}
}3. vue-router跳转方式
this.$router.push()
跳转到不同的url,这个方法会向history栈添加一个记录,点击后退会返回到上一个页面
this.$router.push({path: '/home/sort/detail',query:{id: 'abc'}}) 获取参数 {{this.$route.query.id}} this.$router.push({name: 'detail',params:{id: 'abc'}}) 获取参数:{{this.$route.params.id}} ps: query要用path来引入,params要用name来引入 query更加类似于ajax中get传参,params类似于post,前者在浏览器地址栏中显示参数,后者则不显示 1、this.$router.replace() 同样是跳转到指定的url,但是不会向history里面添加新的记录,点击返回,会跳转到上上一个页面。 上一个记录是不存在的。 2、this.$router.go(n) 相对于当前页面向前/后跳转n个页面,类似 window.history.go(n)。n可为正数可为负数声明式:
根据路由路径(/home/detail)跳转 <router-link :to="{path: '/home/query', query: {id: '12345'}}">跳转子页</router-link> 根据路由名称(detail)跳转 <router-link :to="{name: 'detail', params: {id: '12345'}}"></router-link>
4. vue中的data为什么是一个函数而不是属性值
js中只有函数才可以构成作用域(if(){}和对象的{}都不可构成作用域),data是一个函数时,每个组件实例都有一个自己的作用域,相互独立,互不干扰。
如果data不用函数返回,没有作用域,每个组件的data都是同一块内存地址,一个数据改变了其它数据也改变了
举个例子:
const MyComponent = function() {}; MyComponent.prototype.data = { a: 1, b: 2, } const component1 = new MyComponent(); const component2 = new MyComponent(); component1.data.a === component2.data.a; // true; component1.data.b = 5; component2.data.b // 5 const MyComponent = function() { this.data = this.data(); }; MyComponent.prototype.data = function() { return { a: 1, b: 2, } };这都是因为js本身的特性带来的,跟vue本身设计无关
5. vue 双向数据绑定怎么实现的
数据发生变化,视图跟着变化,视图变化,数据也随之发生改变。
核心是 Object.defineProperty()方法
Object.defineProperty( obj, prop, descriptor)
obj (要定义其上属性的对象)
prop (要定义或修改的属性)
descriptor (具体的改变方法)
简单地说,就是用这个方法来定义一个值。当调用时我们使用了它的get方法,赋值时,又用到了它的set方法;
var obj = {} Object.defineProperty(obj, 'hello', { get: function() { console.log('调用了get') }, set: function(newVal) { console.log('调用set赋值,值是'+newVal) } }) obj.hello; // 调用了get obj.hello = 'hi' // 调用set赋值,值是hi实现一个简单的双向绑定
<div id="app"> <input type="text" id="a"> <span id="b"></span> </div> <script> vat obj = {} var val = '123' Object.defineProperty(obj, 'val', { get: function () { return val; }, set: function(newVal) { val = newVal document.getElementById('a').value = val; document.getElementById('b').innerHTML = val; } }) document.addEventListener('keyup', function(e) { obj.val = e.target.value }) </script>https://www.jianshu.com/p/e7ebb1500613
http
1. http 和 https 区别
Http:超文本传输协议, 互联网上应用最广泛的一种网络协议。Http协议以明文方式发送信息,如果黑客截取了浏览器和服务器之间的传输报文,就可以直接获得其中的信息。
Https:是以安全为目标的Http通道,是Http的安全版。Https的安全基础是SSL。SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。
HTTP与HTTPS的区别
1、http是超文本传输协议,信息是明文传输,https是具有安全性的SSL加密传输协议。
2、http和https使用的是完全不同的连接方式,端口也不一样。前者是80,后者是443。
https://zhuanlan.zhihu.com/p/65798950
https://www.jianshu.com/p/83e74528892c
https://www.cnblogs.com/liuhao-web/p/11589848.html
https://segmentfault.com/a/1190000021809576