1:css水平、垂直居中的写法,请至少写出4种?
//水平居中
行内元素: text-align: center
块级元素: margin: 0 auto
position:absolute +left:50%+ transform:translateX(-50%)
display:flex + justify-content: center
垂直居中
设置line-height 等于height
position:absolute +top:50%+ transform:translateY(-50%)
display:flex + align-items: center
display:table+display:table-cell + vertical-align: middle;
2:1rem、1em、1vh、1px各自代表的含义(了解下就可以了)?
rem是全部的长度都相对于根元素<html>元素。通常做法是给html元素设置一个字体大小,然后其他元素的长度单位就为rem。
子元素字体大小的em是相对于父元素字体大小
元素的width/height/padding/margin用em的话是相对于该元素的font-size
vw/vh
全称是 Viewport Width 和 Viewport Height,视窗的宽度和高度,相当于 屏幕宽度和高度的 1%,不过,处理宽度的时候%单位更合适,处理高度的 话 vh 单位更好。
px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。
一般电脑的分辨率有{1920*1024}等不同的分辨率
1920*1024 前者是屏幕宽度总共有1920个像素,后者则是高度为1024个像素
3:说一下盒模型?
盒模型的组成,由里向外content,padding,border,margin.
在IE盒子模型中,width表示content+padding+border这三个部分的宽度
在标准的盒子模型中,width指content部分的宽度
box-sizing的使用
box-sizing: content-box 是W3C盒子模型
box-sizing: border-box 是IE盒子模型
box-sizing的默认属性是content-box
4:说一下闭包?
闭包的实质是因为函数嵌套而形成的作用域链,有权访问另一个函数作用域中的变量的函数
闭包的定义即:函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包
闭包的作用:有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,可以重复使用。
闭包的实现:在外层函数和内层函数中间定义变量,内部函数可以使用这些变量和外层函数的参数,然后将内层函数整体return出来,就实现了一个简单的闭包
闭包的优点:
1:变量长期驻扎在内存中;
2:避免全局变量的污染;
闭包的缺点:
1:常驻内存 会增大内存的使用量
2:使用不当会造成内存泄露
5:数组去重?
var arr=['12','32','89','12','12','78','12','32'];
// 最简单数组去重法
function unique1(array){
var n = []; //一个新的临时数组
for(var i = 0; i < array.length; i++){ //遍历当前数组
if (n.indexOf(array[i]) == -1)
n.push(array[i]);
}
return n;
}
arr=unique1(arr);
// 速度最快, 占空间最多(空间换时间)
function unique2(array){
var n = {}, r = [], type;
for (var i = 0; i < array.length; i++) {
type = typeof array[i];
if (!n[array[i]]) {
n[array[i]] = [type];
r.push(array[i]);
} else if (n[array[i]].indexOf(type) < 0) {
n[array[i]].push(type);
r.push(array[i]);
}
}
return r;
}
//数组下标判断法
function unique3(array){
var n = [array[0]]; //结果数组
for(var i = 1; i < array.length; i++) { //从第二项开始遍历
if (array.indexOf(array[i]) == i)
n.push(array[i]);
}
return n;
}
es6方法数组去重
arr=[...new Set(arr)];
es6方法数组去重,第二种方法
function dedupe(array) {
return Array.from(new Set(array)); //Array.from()能把set结构转换为数组
}
6:get、post的区别
1.get传参方式是通过地址栏URL传递,是可以直接看到get传递的参数,post传参方式参数URL不可见,get把请求的数据在URL后通过?连接,通过&进行参数分割。psot将参数存放在HTTP的包体内
2.get传递数据是通过URL进行传递,对传递的数据长度是受到URL大小的限制,URL最大长度是2048个字符。post没有长度限制
3.get后退不会有影响,post后退会重新进行提交
4.get只支持ASCII字符,post没有字符类型限制
7:你所知道的http的响应码及含义?
1xx(临时响应)
2xx(成功)
3xx(已重定向)
304:请求的资源并没有被修改过
4xx(请求错误)
403:请求的资源不允许访问。就是说没有权限。
404:请求的内容不存在。
5xx(服务器错误)
500:服务器错误。
8:数组的方法有哪些?
遍历方法:
包括 map、foreach、filter等
let arr = [{
name:"西瓜",
type:"水果"
},{
name:"芒果",
type:"水果"
},{
name:"小龙虾",
type:"夜宵"
}]
arr.forEach((item, index) => {
console.log(item.name)
}) //分别打印 西瓜 芒果 小龙虾
arr.map((item, index) => {
return item.name
}) //返回数组["西瓜", "芒果", "小龙虾"]
arr.filter((item, index) => {
if (item.type == "水果")
return true;
else
return false;
}) //返回数组[{ name: 西瓜, type : 水果 }, { name: 芒果, type : 水果 }]
forEach:用于遍历数组,无返回值;
map:遍历数组之后,对每一项返回一个值,并将这些返回值都推入一个数组,最后返回这个新的数组;
filter:对数据进行过滤,回调函数返回值为false的项将被过滤掉,最后返回过滤后的数组。
操作方法:
包括 concat、push、pop、unshift、shift、splice
let listA = ["西瓜", "芒果"]
let listB = ["小龙虾"]
let listC = listA.concat(listB)
// 返回值:[西瓜, 芒果, 小龙虾]
listC.push("鸡腿")
// 返回值:4
// 数组值:[西瓜, 芒果, 小龙虾, 鸡腿]
listC.pop()
// 返回值:"鸡腿"
// 数组值:[西瓜, 芒果, 小龙虾]
listC.unshift("鸡腿")
// 返回值:4
// 数组值:[鸡腿, 西瓜, 芒果, 小龙虾]
listC.shift()
// 返回值:"鸡腿"
// 数组值:[西瓜, 芒果, 小龙虾]
listC.splice(1, 1, "冰激凌", "奶茶")
// 返回值:[芒果]
// 数组值:[西瓜, 冰激凌, 奶茶, 小龙虾]
concat:拼接数组,将参数数组拼接到调用数组末尾,并返回这个新数组;值得一提的是,这个方法并不会改变调用数组和参数数组,即上例中的listA、listB);
push:在数组尾部插入新的元素,返回插入元素之后的数组长度;
pop:从数组尾部删除元素,返回删除的元素;
unshift:在数组头部插入新的元素,返回插入元素之后的数组长度;
shift:从数组头部删除元素,返回删除的元素;
splice:删除元素并插入元素,第一个参数为操作位置X,第二个参数为需要从操作位置X删除元素数量,后面的参数为需要从操作位置X插入的元素,返回删除的元素组成的数组。
9:跨域问题有哪些处理方式
通过jsonp跨域
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
script.src = 'http://www.daxihong.com:8080/login?user=admin&callback=jsonCallback';
document.head.appendChild(script);
// 回调执行函数
function jsonCallback(res) {
alert(JSON.stringify(res));
}
</script>
跨域资源共享(CORS)
const path = require('path')
const Koa = require('koa')
const koaStatic = require('koa-static')
const bodyParser = require('koa-bodyparser')
const router = require('./router')
const cors = require('koa2-cors')
const app = new Koa()
const port = 9871
...
// 处理cors
app.use(cors({
//这里是重点
origin: function (ctx) {
return 'http://localhost:9099'
},
credentials: true,
allowMethods: ['GET', 'POST', 'DELETE'],
allowHeaders: ['t', 'Content-Type']
}))
// 路由
app.use(router.routes()).use(router.allowedMethods())
// 监听端口
...
nodejs中间件代理跨域(做了解)
利用node + webpack + webpack-dev-server代理接口跨域。在开发环境下,由于vue渲染服务和接口代理服务都是webpack-dev-server同一个,所以页面与代理接口之间不再跨域,无须设置headers跨域信息了。后台可以不做任何处理。
webpack.config.js部分配置
module.exports = {
entry: {},
module: {},
...
devServer: {
historyApiFallback: true,
proxy: [{
context: '/login',
target: 'http://www.daxihong.com:8080', // 代理跨域目标接口
changeOrigin: true,
secure: false, // 当代理某些https服务报错时用
cookieDomainRewrite: 'www.daxihong.com' // 可以为false,表示不修改
}],
noInfo: true
}
}
10:for…in 和 for…of的区别
1:for…of 是ES6新引入的特性,修复了ES5引入的for…in的不足
2:for…in 循环出的是key,for…of循环出的是value
3:for…of不能循环普通的对象,需要通过和Object.keys()搭配使用
4:推荐在循环对象属性的时候,使用for…in,在遍历数组的时候的时候使用for…of
11:new一个对象, 这个过程中发生了什么
var obj = new Object("name","sansan");
1:创建一个新对象,如:var obj = {};
2:新对象的proto属性指向构造函数的原型对象。
3:将构造函数的作用域赋值给新对象。(也所以this对象指向新对象)
4:执行构造函数内部的代码,将属性添加给obj中的this对象。
5:返回新对象obj。
12:怎么判断一个object是否是数组
1:使用 Object.prototype.toString 来判断是否是数组
function isArray(obj){
return Object.prototype.toString.call( obj ) === '[object Array]';
}
2:使用 原型链 来完成判断
function isArray(obj){
return obj.__proto__ === Array.prototype;
}
3:利用JQuery, 利用JQuery isArray 的实现其实就是方法1。
function isArray(obj){
return $.isArray(obj)
}
13:Promise相关
(1): 什么是Promise
简单说就是一个容器,里面保存着某个未来才会结束的事件的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理,让开发者不用再关注于时序和底层的结果。
(2): Promise 解决了什么问题
Promise解决了回调地狱的问题, 提高代码的可读性,使异步操作看起来简洁明了
(3): Promise 如何使用
S6规定,Promise对象是一个构造函数,用来生成Promise实例。
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由JavaScript引擎提供,不用自己部署。
resolve:未完成变为完成;
reject:未完成变为失败;
(4) :Promise 常用的方法有哪些?它们的作用是什么?
Promise.prototype.then
Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。
Promise.prototype.catch
Promise.prototype.catch方法是**.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时**的回调函数。
getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 处理 getJSON 和 前一个回调函数运行时发生的错误
console.log('发生错误!', error);
});
上面代码中,getJSON方法返回一个 Promise 对象,如果该对象状态变为resolved,则会调用then方法指定的回调函数;如果异步操作抛出错误,状态就会变为rejected,就会调用catch方法指定的回调函数,处理这个错误。
Promise.all
Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例, 返回最先执行结束的 Promise 任务的结果,不管这个 Promise 结果是成功还是失败。
需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题
Promise.race
Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。如果全部成功执行,则以数组的方式返回所有 Promise 任务的执行结果。 如果有一个 Promise 任务 rejected,则只返回 rejected 任务的结果。