初级前端高频面试题总结一

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 任务的结果

  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值