Js 由哪三部分组成
ECMAScript(JS的核心内容,描述了语言的基础语法,比如var、for、数据类型(数组、字符串等)),
文档对象模型(DOM):DOM把整个HTML页面规划为元素构成的文档
浏览器对象模型(BOM)把浏览器窗口进行访问和操作
script标签里的async 和defer有什么区别
当没有async 和defer 这两个属性的时候,浏览器会立刻加载并执行指定的脚本,
有async 加载和渲染后面元素的过程将和script 的加载和执行并行进行(异步)
有defer 加载和渲染后面元素的过程将和script的加载并行进行(异步),但是它的执行事件要等所有元素解析完成之后才会执行,
延迟加载 async 、 defer
defer:等html 全部解析完成,才会执行js代码,顺序执行js脚本
Async:async是和html解析同步的(一起的),不是顺序执行js脚本(谁先加载完谁先执行)
前端内存泄漏怎么理解
JS里已经分配内存地址的对象,但是由于长时间没有释放或者没办法清除,造成长期占用内存的现象,会让内存资源大幅浪费,最终导致运行速度慢,甚至崩溃的情况。
垃圾回收机制
因素:一些为生命直接赋值的变量:一些为清空的定时器,过渡的闭包,一些引用元素没有清除
说一下事件循环
JS是一个单线程的脚本语言,主线程先执行同步任务,然后才去执行任务队列里的任务,如果在执行宏任务之前有微任务,那么先执行微任务,全部执行完之后等待主线程的调用,调用完之后再去任务队列中查看是否有异步任务,这样一个循环往复的过程就是事件循环!
事件委托是什么
又叫事件代理,原理就是利用了事件冒泡的机制来实现的,也就是说把子元素的事件绑定到了父元素的身上,如果子元素阻止了事件冒泡,那么委托也就不成立
阻止事件冒泡:event.stopPropagation(),addEventListener(‘click’,函数名,true/false) 默认是false (事件冒泡),true(事件捕获)
好处:提高性能,减少事件的绑定,也就减少了内存的占用。
Svg格式了解多少
基于XML语法格式的图像格式,可缩放矢量图,其他图像是基于像素的,SVG是属于对图像形状的描述,本质是文本文件,体积小,并且不管放大多少倍都不会失真
1.SVG可直接插入页面中,成为DOM一部分,然后用JS或CSS进行操作<svg></svg>
2.SVG可作为文件被引入<img src=“”pic.svg />
3.SVG可以转为base64引入页面
setTimeout最小执行时间是多长
HTML5的规定的内容
setTimeout 最小执行时间是4ms,setInterval最小执行时间是10ms
DOM事件的注册和移除
// 内联事件
<button onclick = "onClick('wangjianguo')">按钮</button>
function onClick(param){
console.log(`你点击了按钮,${param}`)
}
// 通过HTML DOM 设置
var button = document.getElementById('myButton')
button.onClick = function() {
console.log("点击了事件1")
}
button.onClick = function() {
console.log("点击了事件2")
}
// 移除事件处理器
button.onClick = null
// 添加事件监听器
var button = document.getElementById("myButton")
button.addEventListener = function() {
console.log("点击了事件1")
}
button.addEventListener = function() {
console.log("点击了事件2")
}
// 移除事件处理器
button.removeEventListener('click',myFunction)
// 兼容老版本IE浏览器
// button.attachEvent('onClick',myFunction)
什么是属性描述符
6种属性描述符
- value:设置属性值,默认值为undefined.
- writable:设置属性值是否能被修改,默认值为true
- enumerable:设置属性是否可枚举。比如:是否允许使用for/in 语句遍历访问,默认为true
- configurable:控制的是属性的配置,包括是否可以更改属性描述符,以及是否可以从对象中删除属性。
- get:取值函数,当访问该属性时,该方法会被执行,默认为undefined
- set:存值函数,当属性值修改时,触发执行该方法,默认为undefined
属性描述符configureable 和 writable
var obj = {} // 定义空对象
Object.defineProperty(obj,"age",{
value:18,
writable:false // 禁止修改属性值
})
obj.age = 28 // 由于禁止修改,此时修改失败
console.log(obj.age) // 结果仍难是18
console.log(Object.getOwnPropertyDescriptor(obj,"age").value)//18
var obj = {} // 定义空对象
Object.defineProperty(obj,"age",{
writable:true
configureable:false // 禁止配置(换而言之,无法修改属性描述符)
})
obj.age = 28
console.log(obj.age) //28
console.log(Object.getOwnPropertyDescriptor(obj,"age").value)//28
// 修改属性描述符
Object.definedProperty(obj,"age",{value:2}) // 抛出异常
Object.definedProperty(obj,"age",{writable:true}) // 抛出异常
Object.definedProperty(obj,"age",{enumerable:true}) // 抛出异常
Object.definedProperty(obj,"age",{configureable:true}) // 抛出异常
属性描述符get和set应用
var obj = Object.create(Object.prototype,{
_age:{
value:18,
writable:true
},
age:{
get:function(){
return this._age
},
set:function(){
this._age = value
}
}
})
console.log(obj.age) // 18
obj.age = "28"
console.log(obj.age) // 28
enumerable
var person = {
name:'wangjianguo',
age:30,
gender:"male"
}
for (var key in person) {
console.log(key + ":" + person[key])
/*打印
name:'wangjianguo',
age:30,
gender:"male"
*/
}
var obj = {}
Object.defineProperty(obj,"visibleProperty",{
value:"我是可枚举的",
enumerable:true,
})
Object.defineProperty(obj,"hiddenProperty",{
value:"我是不可枚举的",
enumerable:false,
})
console.log(Object.keys(obj)) // ['visibleProperty']
console.log(Object.getOwnPropertyNames(obj))
如何操作属性描述符
什么是柯里化 将使用多个参数的函数转换为一系列使用一个参数的函数
parseInt与Math.floor使用场景对比
相同点 都能获取小数的整数部分
console.log(Math.floor(4.95)) // 4
console.log(parseInt(4.95)) // 4
Math.floor 无论正负,Math.floor 都是简单地将一个数向下取整到最接近的整数。
console.log(Math.floor(4.95)) // 4
console.log(Math.floor(4.5)) // 4
console.log(Math.floor(4.05)) // 4
console.log(Math.floor(-4.05)) // -5
parseInt的特点
对于负数,会向上取整到最接近的整数
对于正数,会向下取整到最接近的整数
console.log(Math.floor(-4.05)) // -5
console.log(parseInt(-4.05)) // -4
parseInt的其他特点 parseInt会忽略任何数字后面的非数字字符
console.log(Math.floor('4.05abc')) // 4
console.log(parseInt("4.05abc")) // NaN
parseInt处理不同的进制数据:
parseInt("11",2)
// 结果是3 因为在2进制中,11表示的是十进制中的3
手写实现数组扁平化
遍历数组,如果每一项还是一个数组,那么就继续往下遍历,利用递归的方法
Array.prototype.customFlatten = function(){
//转化结果
let flat = []
for (let item of this) {
if (Array.isArray(item)){
flat = flat.concat(item.customFlatten())
}else {
flat.push(item)
}
}
return flat
}
let arr =[
[1,2,9],[2,3,3,3],[3,4,5,[6,6,7,8]]
]
//输出 [1,2,9,2,3,3,3,3,4,5,6,6,7,8]
console.log(arr.customFlatten())
不使用临时变量temp 交换x和y的值
临时变量temp
// 临时变量temp
let x = 1
let y = 2
let temp = x
x = y
y = temp
console.log(x,y)
ES6 解构操作
// ES6 解构操作
let x = 1
let y = 2
[y,x] = [x,y]
console.log(x,y)
异或
//异或
let x = 1
let y = 2
x = x ^ y
y = x ^ y
x = x ^ y
console.log(x,y)
加减运算
//加减运算
let x = 1
let y = 2
x = x + y // 原来两数之和
y = x - y // 两数之和 - y
x = x - y // 两数之和 - x
console.log(x,y)
自增运算符
i++ 先返回i的值,再执行i的自增运算
++i 先对i自增运算,再返回修改后的值
let i = 1
console.log(i++ + ++i) // 4
console.log(i++ + ++i * ++i) // 13
function函数length属性
第一个有默认值之前的参数,不考虑剩余参数。没有默认值的参数,那就全部是
function fun1(a){}
function fun2(b = 'a',a){}
function fun3(a,b = 'a'){}
//...arr 不考虑剩余参数
function fun3(a,...arr){}
console.log(fun1.length) // 1
console.log(fun2.length) // 0
console.log(fun3.length) // 1
console.log(fun4.length) // 1
动态执行,动态执行方式
方法一:使用eval()函数
// 方式1,传给eval函数,把字符串当成代码执行
let code = "console.log("hello Word")"
eval(code)
// 方式2,平时使用settimeout 是传一个回调函数,setTimeout(() => {},0)
setTimeout(code,0)
// 方式3
let x = 1
var script = document.createElement("script")
scipt.textContent = code
document.body.appendChild(script)
方法二:使用settimout()函数
方法三:添加新的<script>标签
动态属性和静态属性
静态属性访问:
- 通过点符号(.)访问的属性是静态的。
- 属姓名是硬编码,且在编写代码时就已知。
- 不能使用变量作为属姓名
var person = {
prop:"wangjianguo"
}
function test(){
console.log(person.prop)
}
动态属性访问
- 通过方括号访问的属性是动态的。
- 属性名可以在运行时计算得出的。我们可以使用变量、字符串字面量或表达式
var person = {
a:'wangjianguo',
b:'hello,word'
}
var prop = 'a'
setTimeout(() =>{
prop = 'b'
},2000)
function test(){
console.log(person.prop)
}
纯函数
确定性:对于相同呢大的输入,纯函数总是产生相同的输出。 无副作用:纯函数不会修改其外部环境,包括全局变量、输入参数对象等。
纯函数
function add(a ,b){
return a + b
}
不是纯函数,修改了外部变量
let globalVar = 0
function add(a,b){
globalVar += 1
return a + b + globalVar
}
JavaScript提供了哪些纯函数
toSorted()
let arr = [5,1,9]
// 返回新数组,没有改变原数组
let newArr = arr.toSorted();
console.log(newArr)
toReversed()
反转数组
let reveredArr = arr.toReversed()
toSpliced()
删除数组元素
let splicedArr = arr.toSpliced()
with()
修改数组元素
let newArr = arr.with(0,1)
属性私有化
nuxt.js
是基于vue的应用框架,关注的是渲染,可以开发服务端渲染应用的配置
SSR:服务端渲染
好处:
SSR生成的是有内容的HTML页面,有利于搜索引擎的搜索
优化了首屏加载时间
SEO:优化搜索引擎
SPA的应用不利于搜索引擎SEO的操作
SEO如何优化
- SSR
- 预渲染 prerender-spa-plugin
如何封装组件
组件一定要难点,涉及的知识点;插插、组件通信。。。
Vue3的性能为什么比vue2好
- diff算法的优化
- 静态提升
- 事件侦听缓存
Vue的性能优化怎么做
1.编码优化
不要把所有数据都放在data中
v-for时给每个元素绑定事件用事件代理
keep-alive缓存组件
尽可能拆分组件,提高复用性,维护性
key值要保证唯一
合理使用路由懒加载,异步组件
数据持久化存储的使用尽量用防抖、截流优化
2.加载优化
按需加载
内容懒加载
图片懒加载
3.用户体验
骨架屏
4.SEO优化
预渲染
服务端渲染SSR
5.打包优化
CDN形式加载第三方模块
多线程打包
抽离公共文件
6.缓存和压缩
客户端缓存、服务端缓存
服务端Gzip压缩
Vue中的修饰符有哪些?
- 事件修饰符
-
stop 阻止冒泡
-
prevent 阻止默认行为
-
capture 内部元素触发的事件先在次处理
-
self 只有在event.target是当前元素时触发
-
once 事件只会触发一次
-
passive 立即触发默认行为
-
native 把当前元素作为原生标签看待
- 按键修饰符
-
keyup键盘抬起
-
keydown 键盘按下
- 系统修饰符
-
ctrl
-
alt
-
meta
- 鼠标修饰符
-
left 鼠标右键
-
middle 鼠标中键
-
right 鼠标右键
- 表单修饰符
-
lazy 等输入完之后再显示
-
stop 删除内容前后的空格
-
type 输入是数字或专为数字
7. V-Router 几种模式的区别
V-Router 有三种模式hash,history,abstract
abstract模式是在不支持浏览器API环境使用,不依赖于浏览器历史
hash模式:hash+popState/hashChange 兼容性好但是不够美观,hash服务端无法获取。不利于seo优化
history模式:historyApi + popState 美观,刷新会出现 404 -> CLI web pack history-fallback
如何解决刷新后二次加载路由
1.window.location.reload()
2.matcher
const router = createRouter()
export function resetRouter(){
const newRouter = createRouter()
router.matcher = newRouter.matcher
}
Vue中如何做强制刷新
1.localtion.reload()
2.this.$router.go(0)
3.provide 和 inject
大文件上传是怎么做的
分片上传:
-
把需要上传的文件按照一定的规则,分隔成相同大小的数据块
-
初始化一个分片上传任务,返回本次分片上传的唯一标识
-
按照一定的规则把各个数据块上传
-
发送完成后,服务端会判断数据上传的完整性,如果完整,那么就会把数据库合并成原始文件
断点续传:
服务端返回,从哪里开始,浏览器自己也可以处理
什么是语义化标签
1.易读性和维护性更好
2.seo成分会更好,蜘蛛抓取会更好
3.IE8不兼容HTML5标签的。解决:可以通过html5shiv.js去处理。
例如:
<header></header>、<footer></footer>、<section></section>、<button></button>
title与h1的区别,b与strong的区别,i与em的区别
title与h1的区别:
定义:
title:概括了网站信息,可以告诉搜索引擎或者用户关于这个网站的内容主题是什么
h1:文章主题内容,告诉蜘蛛我们的网站内容最主要是什么
区别:
title他是显示在网页标题上、h1是显示在网页内容上
title比h1添加的重要(title > h1) => 对于seo的了解
场景:
网站的logo都是用h1标签包裹的
b与strong的区别
定义:
b:实体标签,用来给文字加粗的。
strong:逻辑标签,用来加强字符语气的
区别:
b标签只有加粗的样式,没有实际含义。
strong表示标签内字符比较重要,用以强调的
题外话:为了CSS3的规范,b尽量少用该用
i与em的区别
定义:
i:字体标签,用来文字倾斜的
em:是逻辑标签,用来强调文字内容的
区别:
i只是一个倾斜标签,没有实际含义。
em表示标签内字符重要,用以强调的
场景:
i更多的用在字体图标,em术语上(医药,生物)。
img标签的title和alt有什么区别?
区别一:
title:鼠标移入到图片显示的值
alt:图片无法加载时显示的值
区别二:
在seo的层面上,蜘蛛抓取不到图片的内容,所以前端在写img标签的时候为了增加seo效果要加入alt属性来描述这张图是什么内容或者关键词。
png,jpg,gif这些图片格式解释一下,分别什么时候用?
png:无损压缩,尺寸体积要比jpg/jpeg的大。适合做小图标,不适合做banner,加载慢。
jpg;采用压缩算法,有一点失真,比png体积要小。(做中大型图片)
gif:一般是做动图的。
webp:同时支持有损或者无损压缩,相同质量的图片,webp具有更小的体积。兼容性不是特别好。
如何关闭iOS键盘首字母自动大写
<input type autocapitalize = "off">
怎么让Chrome支持小于12px的文字?
Chrome默认font-size:16px,每个浏览器默认字体大小可能都不一样
<div>
<span>你好呀~</span>
</div>
div {
font-size:10px;
}
div span {
display:inline-block;
-webkit-transform:scale(1.6)
}
iOS系统中元素被触摸时产生的半透明灰色遮罩怎么去掉
<style>
a,button,input,textarea{
-webkit-tap-highlight-color:rgba(0,0,0,0)
}
</style>
webkit表单中输入框placeholder的颜色值能改变吗?
<style>
input::-webkit-input-placeholder{
color:red
}
</style>
禁止iOS长按时触发系统的表单,禁止iOS&android长按时下载图片
禁止iOS长按时触发系统的菜单,禁止iOS&android长按时下载图片
html,body{
touch-callout:none;
-webkit-touch-callout:none;
user-select:none;
-webkit-user-select:none;
}
禁止iOS和android用户选中文字
html,body{
user-select:none;
-webkit-user-select:none;
}
用CSS画一个三角形
用边框画(border)
{
width:0;
height:0
border-left:100px solid transparent;
border-right:100px solid transparent;
border-top:100px solid transparent;
border-bottom:100px solid #ccc;
}
在网页中的应该使用奇数还是偶数的字体?为什么呢?
偶数:让文字在浏览器上表现更好看
另外说明:Ui给前端一般设计图都是偶数的,这样不管是布局也好,转换ps也好,方便一点
什么是CSS reset
reset 是一个css文件,用来重置css样式的
Normalize.css 为了增强跨浏览器渲染的一致性,一个css重置样式库。
css sprite 是什么。有什么优缺点
1.把多个小图标合并成一张大图片,
2.优缺点:减少了http请求的次数,提升了性能,维护比较差(例如图片位置进行修改或者内容宽高修改)
页面导入样式时,使用link 和 @import 的区别?
区别一:link先有,后有@import(兼容性比@import好)
区别二:加载顺序差别:浏览器先加载的标签link,后加载@import