大家好,我是梅巴哥er
。本篇打算把所有问题都集合在一起,做个整理。方便平时查阅。
1,问:说说html5语义化标签
答:
- 语义化:标签本身表达了语句的结构和内容。如header就表示头部,nav标签表示导航条等
- 语义化标签有:
<header>, <nav>, <aside>, <article>, <section>, <footer>
- 优点:
- 去掉css样式,也能呈现出页面的内容结构,不至于让页面内容挤在一堆
- 有利于SEO。爬虫依赖标签来确定关键字的权重
- 提升用户体验:比如alt, title等可以了解到大致内容,label让用户更容易获取焦点等
2,递归求和:有序求和(1+2+3+…)及斐波那契数列(0、1、1、2、3、5、8、13、21、34…)
// 递归求和
// 写一个函数,输入一个值,就得出1到这个值的加和
// 比如fn(3) 输出6
function add(num) {
if(num === 1) {
return 1
} else {
return add(num-1) + num
}
}
console.log(add(4)) // 10
// 输入一个数字,就显示对应位置的斐波那契值
// 如fn(4),输出2
function fn(num) {
if(num === 1) {
return 0
} else if(num === 2) {
return 1
} else {
return fn(num-2) + fn(num-1)
}
}
console.log(fn(5))
3,问:闭包
答:
- 一个外部变量和一个可以访问该变量的函数,组成一个闭包。
// 举例
var a = 1
function fn() {
console.log(a)
}
// 变量a和函数fn,就组成了要给闭包
// 之所以要return一个函数,是因为需要让别人拿去调用
- 闭包的作用
- 封装私有变量,提供暴露的接口
- 可以访问私有变量
4,问:内存泄露要怎么处理
答:
- 什么是内存泄露?
- 当一个变量不再被使用,但并没有被回收或释放,就叫内存泄露
- 全局变量
- 在js文件开头,声明
use strict
,用严格模式防止意外的全局变量 - 声明后的全局变量,可以让变量
=null
来清空内存
- 在js文件开头,声明
- 定时器
- 使用完定时器后,随时清除。
clearInterval(timer)
- 使用完定时器后,随时清除。
- 额外的DOM引用
- 比如在jsonp跨域中,需要创建
<script>
标签,当反复执行跨域时,就会反复的创建标签,额外增加很多的DOM元素。可以在使用后通过removeChild()
来清除。
- 比如在jsonp跨域中,需要创建
5,问:手撕代码:防抖和节流
答:
// 节流核心代码
var flag = true
function fn() {
if(...) { // 动画完成
flag = true // 打开节流阀
} else {
}
}
.addEventListener('click', function() {
if(flag) {
...
flag = false
fn()
}
})
// 防抖核心代码
function debounce(fn, delay) {
let handle
return function(e) {
clearTimeout(handle)
handle = setTimeout(() => {
fn(e)
}, delay)
}
}
.addEventListener('click', debounce(fn, delay))
6,问:箭头函数的this问题
答:
- 箭头函数没有自己的this,即不会产生自己新作用域下的this。
- 箭头函数的this,指向了他的父作用域
- 箭头函数的this,在定义箭头函数的时候就已经和环境进行了绑定,而不是在执行时绑定的。
var a = 1
var b = () => {
var a = 2
console.log(this.a)
console.log(this)
}
b()
// 在F12下的执行结果为:
// 1 window
var a = 1
var obj = {
a: 2,
b: () => {
var a = 3
console.log(this.a) // 1
console.log(this) // window
},
c: function () {
var a = 4
console.log(this.a) // 2
}
}
obj.b()
obj.c()
7,CSS画出等边三角形
// 原理,不一样长度的border
div {
width: 0px;
height: 0px;
border-right: 173.2px solid pink;
border-left: 173.2px solid transparent;
border-top: 100px solid transparent;
border-bottom: 100px solid transparent;
}
8,react项目的webpack从零搭建
对react项目进行过基础的配置,比如
const path = require('path');
module.exports = {
entry: path.resolve(__dirname, '../src/index.js'), //指定入口文件,程序从这里开始编译,__dirname当前所在目录, ../表示上一级目录, ./同级目录
output: {
path: path.resolve(__dirname, '../dist'), // 输出的路径
filename: 'bundle.js' // 打包后文件
},
module: {
rules: [
{
test: /\.(js|jsx)$/, // 编译jsx语法
use: {
loader: 'babel-loader',
options: {
presets: ['es2015', 'react'],
}
},
exclude: /node_modules/
}
]
}
}
9,问:Object.defineProperty()除了get、set外,还能做啥
答:
Object.defineProperty(obj, 属性, 值对象)
// 举例
var obj = {}
Object.defineProperty(obj, 'a', {
value: 1, // 往对象obj里添加属性a的值1
})
console.log(obj.a) // 1
// 值对象里的属性:
// value: 属性的值
// writable:默认false,即不能被重写或修改。
// enumerable: 默认false,即不能被for..in或Object.keys()枚举
// configurable:默认false,即value writable enumerable这些属性不能更改或删除
10,问:es6主要接触了哪些知识
答:
箭头函数, let const , promise, set, class继承,解构赋值等
11,问:const声明一个对象,对象里面的数据可以修改吗
答:
- 可以。
// 举例
const obj = {
a: 1,
}
obj.a = 2
console.log(obj) // { a: 2 }
12,问:解决跨域的常用方法
答:
-
jsonp:利用
<script>
标签中的src
属性不受同源政策影响的特性进行跨域 -
proxy: 在
package.json
文件里,配置"proxy": "跨域url"
-
cors:
- 请求头模式:后台设置请求头
res.setHeader("Access-Control-Allow-Origin", url 或 *)
。如果需要携带cookie,还需要加一个res.header('Access-Control-Allow-Credentials', true)
- 请求头模式:后台设置请求头
-
后台发送请求:一个后台向另一个后台请求数据,然后再返回给自己的客户端
13,cors简单请求和非简单请求的区别
答:
// 同时满足以下两个条件,就是简单请求
(1) 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、
multipart/form-data、text/plain
// 不能同时满足以上两个条件的,都是非简单请求。
- 对于简单请求,浏览器会直接发出cors请求。
// 设置请求头
Access-Control-Allow-Origin: 允许跨域的url
Access-Control-Allow-Credentials:是否允许携带cookie
Access-Control-Allow-Credentials:指定想拿到的字段
// 注:如果需要携带cookie,后台设置了请求头后,
// 还需要在前端ajax请求时设置withCredentials属性
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
// 这时的Origin字段的值不能设置为*
- 非简单请求
- 会在请求之前,增加一次http的预检,即检查客户端的域名是否在跨域名单里,以及可以使用的请求方式和字段类型,只有都满足时,才能跨域请求。
Access-Control-Allow-Methods:允许的请求方式
Access-Control-Allow-Headers:允许的头信息
Access-Control-Allow-Credentials:是否携带cookie
Access-Control-Max-Age:请求有效期
// 非简单请求一旦预检通过,就和简单请求一样,可以直接发送请求了
14,webpack打包,用了哪些loader和plugin
答:
- loader
- babel-loader :把jsx/es6 转换成标准的js代码
- style-loader:转换css样式必用
- css-loader:预处理css文件
- less-loader, sass-loader:转换成css样式
- url-loader, file-loader:处理图片。两个必须都用,否则超过大小限制的图片无法生成到目标文件夹中
- plugin
- htmlwebpackplugin:生成html文件及注入资源
15,问:图片一般用什么loader
答:
- url-loader, file-loader:处理图片
16,问:url-loader里面对图片有什么处理方法
答:
- limit:限制图片大小
- name:输出的文件名规则,即图片名称及后缀
- outputPath:表示输出文件路径前缀
- publicPath:表示打包文件中引用文件的路径前缀
17,问:怎么降低代码耦合度
答:
- 耦合度
- 即模块与模块之间的关联、感知和依赖程度
- 在实际开发中,两个高耦合度的模块,修改其中一个模块时,还需要修改另一个模块的代码,这样费时费力。
- 降低耦合度
- 一个模块的功能要尽量单一,减少其他模块调用的机会
- 一个定义只出现在一个地方,不重复定义
- 少使用全局变量
18,手写节流代码,需要看到时间戳
<body>
<button id="btn">点击</button>
<h3>0</h3>
<script>
var btn = document.getElementById('btn')
var h3 = document.getElementsByTagName('h3')[0]
var count = 0 // 显示在页面的值
function addCount() {
count++
h3.innerHTML = count
}
function throttle(fn, delay) { // 节流函数
// var that, arg
var pre = 0 // 初始时间戳
return function() {
var now = Date.now() // 当前时间戳
// that = this
if(now - pre > delay) {
// fn.apply(that, arg)
fn.apply(this)
pre = now
}
console.log(pre) // 打印出时间戳
}
}
btn.addEventListener('click', throttle(addCount, 1000))
</script>
</body>
19, 手写代码:js随机获取10-100之间的10个数,存入数组并排序
var arr = []
function getRandom(a, b) {
var num = b - a + 1
// 获取10-100之间的数(核心)
return Math.floor(Math.random()*num + a)
}
// 获取10次
for(var i = 0; i < 10; i++) {
var result = getRandom(10, 100)
// 获取到的数字放入数组
arr.push(result)
}
// 对数组排序
arr.sort((a, b) => a - b)
console.log(arr)
20, 手撕代码:写一个异步请求,每次都在之前结果的基础上加一
21,问:vue的双向绑定原理(vue小伙伴自行百度)
22,问:vue的生命周期(vue小伙伴自行百度)
23,问:vue里面的conputed和watch的区别,以及原理
24,问:css的box-shadow
box-shadow: none; // 无阴影
box-shadow: inset x y blur-radius spread-radius color;
参数说明:
1,阴影类型:默认是外阴影,不用写。如果加了inset,就是内阴影
2,x和y,分别表示水平和垂直方向的偏移量
3,blur-radius表示阴影的模糊半径,可为0
4,spread-radius表示阴影的扩展半径
5,color表示阴影的颜色
25,问:transition, transform, animation的区别及用法
答:
1,transition: property duration timing-function delay;
后面的值依次表示:要变化的属性值, 变化开始到结束需要的时间,变化速度,何时开始
2,transform的值有4类,分别是:
移动:translate
缩放:scale
旋转:rotate
倾斜:skew
3,animation
先用@keyframes 动画名 {} 来定义动画
然后在animation里启动
animation: 动画名 花费时间s 运动类型
26,手撕代码:给定一个数组,统计重复元素的个数
// 统计重复元素的个数
// 数组举例
var arr = [1, 2, 3, 4, 3, 3, 2, 5 ,1]
var obj = {}
// 遍历数组
arr.map(v => {
if(!(v in obj)) { // 元素不在对象里
obj[v] = 1 // 该元素次数为1
} else { // 在对象里
obj[v]++ // 元素次数自增1
}
})
// console.log(obj)
// { '1': 2, '2': 2, '3': 3, '4': 1, '5': 1 }
var n = 0 // 重复的元素个数
for(v in obj) {
obj[v] > 1 && n++ // 元素次数大于1的 就是重复的
}
console.log(n) // 输出重复元素的个数 3
27,手撕项目:封装一个组件。一个count值初始为0,有2个按钮+和-,实现count值的加减。一个回放按钮,实现回放。比如,一开始执行了+然后过了1s执行了减,再过2s执行了加,点击回放按钮可以使这个场景再现。
<body>
<h3>0</h3> <!-- 显示数字 -->
<button id="btnAdd">+</button> <!-- 加号按钮 -->
<button id="btnMinus">-</button> <!-- 减号按钮 -->
<button id="btnBack">查看回放</button> <!-- 点击查看回放 -->
<script>
var btnAdd = document.getElementById('btnAdd')
var btnMinus = document.getElementById('btnMinus')
var btnBack = document.getElementById('btnBack')
var h3 = document.getElementsByTagName('h3')[0]
var count = 0 // 设置数字的初始值为0
// 查看回放的核心思想是,把每一步的操作,放入数组,查看的时候就遍历数组
var arr = []
// 当数字为0时,让减号按钮禁止点击
btnMinus.setAttribute('disabled', 'disabled')
btnAdd.addEventListener('click', function() {
count++
if(count > 0) {
btnMinus.removeAttribute('disabled')
h3.innerHTML = count
// 每一步操作,都存入数组
arr.push(btnAddFn)
}
})
btnMinus.addEventListener('click', function() {
if(count === 1) {
count--
this.setAttribute('disabled', 'disabled')
h3.innerHTML = count
arr.push(btnMinusFn)
} else if(count > 1) {
count--
h3.innerHTML = count
arr.push(btnMinusFn)
}
})
// 加法函数,用来充当定时器的回调函数
function btnAddFn() {
btnAdd.click() // 相当于点击加号
}
// 减法函数
function btnMinusFn() {
btnMinus.click() // 相当于点击减号
}
// 点击查看回放
btnBack.addEventListener('click', function() {
// 查看回放时,先把数字调成0
count = 0
// 遍历数组,每过1秒,显示其中1步的操作
for(var i = 0; i < arr.length; i++) {
setTimeout(arr[i], 1000*(i+1))
}
console.log(arr)
// 查看回放后,清空数组,方便存放下次的操作
// arr = []
})
</script>
</body>
以上。