前言
坐标深圳
2023.6.16 完成了工作交接,算是正式结束了第二份工作。
休息了一个月后,开始在招聘平台投递简历,但大部分都是送达,已读不回。
没有面试的时候就去附近的图书馆准备。
还没有找到合适的工作。
看到这篇文章的朋友如果贵公司也在招人的话麻烦看看能不能帮我内推。😁
2023.09.18 已入职新公司。
持续更新
A 公司 (两位面试官,技术面试官感觉实力不错)
笔试题
const arr = ["1","2","3"].map(parseInt)
以上代码输出结果是什么?为什么?
parseInt(string, radix) 解析一个字符串并返回指定基数的十进制整数,
radix
是2-36
之间的整数,表示被解析字符串的基数。
实际执行的的代码是:
['1', '2', '3'].map((item, index) => {
return parseInt(item, index)
})
即返回的值分别为:
parseInt('1', 0) // 1
parseInt('2', 1) // NaN
parseInt('3', 2) // NaN, 3 不是二进制
parseInt
计算规则:
str
左起第一个数大于进制数radix
,返回NaN
;str
左起第一个数小于进制数radix
,就去做运算,直到遇到一个大于等于radix
,就不加了。
示例:parseInt('4215213', 5)
输出 111
4 * Math.pow(5,2) + 2 * Math.pow(5,1) + 1 * Math.pow(5,0) = 111
事件循环
setTimeout(function () {
console.log(1)
}, 0);
new Promise(function executor(resolve) {
console.log(2)
for (let i = 0; i < 10000; i++) {
i == 9999 && resolve()
}
console.log(3)
}).then(function () {
console.log(4)
})
console.log(5)
输出结果:2 3 5 4 1
防抖
在事件被触发n
秒后再执行回调,如果在这n
秒内又被触发,则重新计时。
function debounce(fn) {
// 创建一个标记用来存放定时器的返回值
let timeout = null;
return function () {
// 每次当用户点击/输入的时候,把前一个定时器清除
clearTimeout(timeout);
// 然后创建一个新的 setTimeout,
// 这样就能保证点击按钮后的 interval 间隔内
// 如果用户还点击了的话,就不会执行 fn 函数
timeout = setTimeout(() => {
fn.call(this, arguments);
}, 1000);
};
}
节流
规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
function throttle(fn, delay) {
var prev = Date.now();
return function () {
var context = this;
var args = arguments;
var now = Date.now();
if (now - prev >= delay) {
fn.apply(context, args);
prev = Date.now();
}
}
}
CSS 实现瀑布流布局
multi-column 多栏布局实现瀑布流(排列顺序是先从上往下
再从左至右
)
.masonry {
column-count: 3; /* 设置共有几列 */
column-gap: 10px; /* 设置列与列之间的间距 */
}
不使用 column-count,可设置 column-width
: 设置每列宽度,列数由总宽度
与每列宽度
计算得出
多行文本垂直居中
.text {
display: flex;
justify-content: center;
flex-direction: column;
}
浅拷贝
浅拷贝:只进行一层复制,深层次的引用类型还是共享内存地址,原对象和拷贝对象还是会互相影响。
实现方法:
- Object.assign
const obj = {
name: 'lin'
}
const newObj = Object.assign({}, obj)
obj.name = 'xxx' // 改变原来的对象
console.log(newObj) // { name: 'lin' } 新对象不变
console.log(obj == newObj) // false 两者指向不同地址
- 数组的
slice
和concat
方法
slice
const arr = ['lin', 'is', 'handsome']
const newArr = arr.slice(0)
arr[2] = 'rich' // 改变原来的数组
console.log(newArr) // ['lin', 'is', 'handsome']
console.log(arr == newArr) // false 两者指向不同地址
concat
const arr = ['lin', 'is', 'handsome']
const newArr = [].concat(arr)
arr[2] = 'rich' // 改变原来的数组
console.log(newArr) // ['lin', 'is', 'handsome'] // 新数组不变
console.log(arr == newArr) // false 两者指向不同地址
- 数组静态方法 Array.from
const arr = ['lin', 'is', 'handsome']
const newArr = Array.from(arr)
arr[2] = 'rich' // 改变原来的数组
console.log(newArr) // ['lin', 'is', 'handsome']
console.log(arr == newArr) // false 两者指向不同地址
- 扩展运算符
const arr = ['lin', 'is', 'handsome']
const newArr = [...arr]
arr[2] = 'rich' // 改变原来的数组
console.log(newArr) // ['lin', 'is', 'handsome'] // 新数组不变
console.log(arr == newArr) // false 两者指向不同地址
深拷贝
深拷贝:无限层级拷贝,深拷贝后的原对象不会和拷贝对象互相影响。
基础版:
const obj = {
person: {
name: 'lin'
}
}
const newObj = JSON.parse(JSON.stringify(obj))
obj.person.name = 'xxx' // 改变原来的深层对象
console.log(newObj) // { person: { name: 'lin' } } 新的深层对象不变
这种方式存在以下弊端:
- 忽略
undefined
、symbol
和函数
NaN
、Infinity
、-Infinity
会被序列化为null
- 不能解决循环引用的问题
完整版:
function deepClone (target, hash = new WeakMap()) { // 额外开辟一个存储空间WeakMap来存储当前对象
if (target === null) return target // 如果是 null 就不进行拷贝操作
if (target instanceof Date) return new Date(target) // 处理日期
if (target instanceof RegExp) return new RegExp(target) // 处理正则
if (target instanceof HTMLElement) return target // 处理 DOM元素
if (typeof target !== 'object') return target // 处理原始类型和函数 不需要深拷贝,直接返回
// 是引用类型的话就要进行深拷贝
if (hash.get(target)) return hash.get(target) // 当需要拷贝当前对象时,先去存储空间中找,如果有的话直接返回
const cloneTarget = new target.constructor() // 创建一个新的克隆对象或克隆数组
hash.set(target, cloneTarget) // 如果存储空间中没有就存进 hash 里
Reflect.ownKeys(target).forEach(key => { // 引入 Reflect.ownKeys,处理 Symbol 作为键名的情况
cloneTarget[key] = deepClone(target[key], hash) // 递归拷贝每一层
})
return cloneTarget // 返回克隆的对象
}
判断数据类型
列举几种常见的方法:
- typeof
//可返回想要的结果
typeof "a" //"string"
typeof true //"boolean"
typeof 1 //"number"
typeof undefined //"undefined"
typeof Symbol() //"symbol"
typeof function a(){} //"function"
//不可返回想要的结果
typeof null //object
typeof [] //object
typeof new Date() //object
- constructor
"1".constructor == String //true
true.constructor == Boolean // true
Symbol().constuctor == Symbol // false
[1].constructor == Array //true
[1].constructor == Object //false
new Date().constructor == Date //true
new Function().constructor == Function //true
1.constructor == Number //Uncaught SyntaxError: Invalid or unexpected token
null.constructor == null //Uncaught TypeError: Cannot read properties of null (reading 'constructor')
undefined.constructor == undefined //Uncaught TypeError: Cannot read properties of undefined (reading 'constructor')
- instanceof
var simpleStr = "This is a simple string";
var myString = new String();
var newStr = new String("String created with constructor");
var myDate = new Date();
var myObj = {};
var myNonObj = Object.create(null);
simpleStr instanceof String; // 返回 false,非对象实例,因此返回 false
myString instanceof String; // 返回 true
newStr instanceof String; // 返回 true
myString instanceof Object; // 返回 true
myObj instanceof Object; // 返回 true,尽管原型没有定义
({}) instanceof Object; // 返回 true,同上
myNonObj instanceof Object; // 返回 false,一种创建非 Object 实例的对象的方法
myString instanceof Date; //返回 false
myDate instanceof Date; // 返回 true
myDate instanceof Object; // 返回 true
myDate instanceof String; // 返回 false
- Object.prototype.toString
function type(obj) {
return Object.prototype.toString.call(obj).slice(8, -1);
}
type(1); //"Number"
type("1"); //"String"
type(true); //"Boolean"
type(undefined); //"Undefined"
type(null); //"Null"
type(Symbol()); //'Symbol'
type({}); //"Object"
type([]); //"Array"
type(new Date); //"Date"
type(/\d/); //"RegExp"
type(function() {}); //"Function"
type(new Point(1, 2)); //"Object"
js
数据类型
基础数据类型:String
,Boolean
,Number
,Null
,Undefined
,Symbol
(Symbol
为ES6
新增)
引用类型:Object
(其中包含了Array
,Date
,Function
等)
区别: 基本数据类型保存在栈内存,引用数据类型在栈里存地址,而在堆里存内容。
typeof
与 instanceof
的区别
typeof
返回一个变量的类型字符串,instanceof
返回的是一个布尔值。typeof
可以判断除了null
以外的基础数据类型,但是判断引用类型时,除了function
类型,其他的无法准确判断。instanceof
可以准确地判断各种引用类型,但是不能正确判断原始数据类型。
typeof null
为什么是 object
JavaScript
中不同对象在底层都表示为二进制,而 JavaScript
中会把二进制前三位都为 0
的判断为 object
类型,而 null
的二进制表示全都是 0
,自然前三位也是 0
,所以执行 typeof
时会返回 object
。
数组扁平化
flat 方法
const arr = [1, [2, [3, [4, [5]]]], 6]
arr.flat(Infinity) // [1,2,3,4,5,6]
reduce
实现 flat
函数
const arr = [1, 2, 3, 4, [1, 2, 3, [1, 2, 3, [1, 2, 3]]], 5, "string", { name: "弹铁蛋同学" }]
// 首先使用 reduce 展开一层
arr.reduce((pre, cur) => pre.concat(cur), []);
// [1, 2, 3, 4, 1, 2, 3, [1, 2, 3, [1, 2, 3]], 5, "string", { name: "弹铁蛋同学" }];
// 用 reduce 展开一层 + 递归
const flat = arr => {
return arr.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? flat(cur) : cur);
}, []);
};
// [1, 2, 3, 4, 1, 2, 3, 1, 2, 3, 1, 2, 3, 5, "string", { name: "弹铁蛋同学" }];
数组去重
ES6方法:
var unique = (a) => [...new Set(a)] // 此方法对象不去重
键值对方法:
function unique(array) {
var obj = {};
return array.filter(function (item, index, array) {
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
原型链
这可能是掘金讲「原型链」,讲的最好最通俗易懂的了,附练习题!
Vue3
与Vue2
的区别。
Composition API
- 响应式原理
- 生命周期钩子名称
- 自定义指令钩子名称(指令钩子)
framents
(支持有多个根节点)createRenderer
(自定义渲染器)- 新的内置组件(
<Teleport>
、<Suspense>
) diff
算法
Object.defineProperty
与 Proxy
的区别
以下代码为 Vue
响应式原理部分片段:
Object.defineProperty
Object.keys(target).forEach(key => {
const dep = new Dep()
let value = target[key]
Object.defineProperty(target, key, {
get() {
const dep = getDep(target, key)
dep.depend()
return value
},
set(newValue) {
console.log('newValue', newValue)
const dep = getDep(target, key)
value = newValue
dep.notify()
}
})
})
return target
Proxy
const handler = {
get(target, key, receiver) {
const dep = getDep(target, key)
let result = Reflect.get(target, key, receiver)
dep.depend()
return result
},
set(target, key, value, receiver) {
const dep = getDep(target, key)
let result = Reflect.set(target, key, value, receiver)
dep.notify()
return result
}
}
return new Proxy(target, handler)
Proxy
是对整个对象的代理,而Object.defineProperty
只能代理某个属性。- 对象上新增属性,
Proxy
可以监听到,Object.defineProperty
不能。 - 数组新增修改,
Proxy
可以监听到,Object.defineProperty
不能。 - 若对象内部属性要全部递归代理,
Proxy
可以只在调用的时候递归,而Object.definePropery
需要一次完成所有递归,性能比Proxy
差。 Proxy
不兼容IE
,Object.defineProperty
不兼容IE8
及以下。
为什么要升级 Vue3
- 速度更快
- 体积减少
- 更易维护
- 更接近原生
- 更易使用
- 更好地支持 TypeScript
项目开发的前期工作
- 需求评审
- 技术选型
- 任务拆分
- 项目排期
B 公司(前端架构师)
JS 中强制类型转换为 Number
类型的方法有哪些?
Number()
函数- 使用
parseInt()
或者parseFloat()
- 算术运算符
let a = '123';
a - 0 = 123;
a * 1 = 123;
a / 1 = 123;
- 隐式转换
let a = "123";
a = +a; // 123
a = -(-a); // 123
创建一个子节点、插入一个节点、在已有元素之前插入节点、删除子节点有哪些方法?
- 创建一个子节点
createElement()
- 插入一个节点
appendChild()
- 在已有元素之前插入节点
insertBefore()
- 删除子节点
removeChild()
获取元素的第一个子节点、获取元素的最后一个子节点、获取上一个兄弟节点、获取下一个兄弟节点的方法有哪些?
下列属性直接匹配节点。
- 获取元素的第一个子节点
firstElementChild
- 获取元素的最后一个子节点
lastElementChild
- 获取上一个兄弟节点
previousElementSibling
- 获取下一个兄弟节点
nextElementSibling
上述属性都有与之对应的属性 firstChild
、lastChild
、previousSibling
、nextSibling
,会匹配字符,包括换行和空格,而不是节点。
代码题
var a = 1;
function fn1(a) {
alert(a)
a = 2
}
fn1()
alert(a)
输出结果是:undefined
、1
rem
布局的原理,怎么计算body
的font-size
的值?
rem
布局的本质是等比缩放,基于html
元素字体大小计算。
Vue 在 data
里定义值,改变它触发 DOM
更新,这个过程是同步
还是异步
,为什么?
Vue 中 transition 的理解?
<Transition>
会在一个元素或组件进入和离开 DOM 时应用动画。
Vue 组件的通信(父子组件和非父子组件)
props
/$emit
$children
/$parent
(Vue2
)provide
/inject
ref
/refs
(Vue2
)eventBus
Vuex
$nextTick的使用?
$nextTick() 的作用就是可以将里面的回调函数延迟下次 DOM 更新循环结束之后执行。在修改数据之后立即使用这个方法,获取更新后的 DOM。
$emit、$on、$once、$off 理解?
- $on:监听事件
- $off:移除监听事件
- $emit:触发事件
- $once:监听事件,只监听一次
$roots、$refs、$parent 的使用?
- $root:当前组件树的根组件实例。如果当前实例没有父组件,那么这个值就是它自己。
- $refs:一个包含 DOM 元素和组件实例的对象,通过模板引用。
- $parent:当前组件可能存在的父组件实例,如果当前组件是顶层组件,则为
null
。
在上一家公司有什么成长或是不一样的地方
答:前端专业技能更熟悉,做项目更熟练。
下一家公司
进什么样的团队、做什么样的业务?
答:研发体系完善的团队,互联网业务。
未来 3
到 5
年想做一些什么样项目?
答:稳定,给很多人使用的项目。(类似于朴朴)
C 公司(人事、前端、后端、产品、老板等 6 人视频面试)
多个文件一起上传怎么处理
修改input标签,添加multiple属性。详细请查阅: 前端文件上传常见场景 -- 多文件上传。
canvas 画一个正方形
const canvas = document.getElementById("canvas"); // 得到DOM对象
if (canvas.getContext) {
var ctx = canvas.getContext("2d"); // 得到渲染上下文
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(10, 10, 100, 100);
}
鼠标滑入滑出事件回调函数
不知道问的这个问题是什么意思,我回答回调函数是自己定义。
微信小程序开发和网页开发的区别
- 运行环境:小程序的运行环境是微信客户端,网页则是在浏览器中。
- 开发能力:小程序可以使用微信提供很多开发能力(支付、分享、卡券等),而网页应用没有。
- 支付能力:小程序只支持微信支付,网页里可以选择使用其他支付平台提供的支付方式。
图片已经更新了,前端页面如何实现更新。
轮询:setInterval
箭头函数和普通函数的区别
- 箭头函数不会创建自己的
this
,它只会从自己的作用域链的上一层继承this
。 - 箭头函数继承而来的
this
指向永远不变 call
、apply
、bind
无法改变箭头函数中this
的指向- 箭头函数不能作为构造函数使用
- 箭头函数没有自己的
arguments
- 箭头函数没有原型
prototype
- 箭头函数不能用作
Generator
函数,不能使用yeild
关键字
v-if
和 v-for
为什么不能同时使用?
存在优先级的问题。
当它们同时存在于一个节点上时,v-if
比 v-for
的优先级更高。这意味着 v-if
的条件将无法访问到 v-for
作用域内定义的变量别名:
<!--
这会抛出一个错误,因为属性 todo 此时
没有在该实例上定义
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo.name }}
</li>
在外新包装一层 <template>
再在其上使用 v-for
可以解决这个问题 (这也更加明显易读):
<template v-for="todo in todos">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>
Vue 父子组件的生命周期执行顺序
创建挂载过程
父组件先创建,然后子组件创建;子组件先挂载,然后父组件挂载。
- 父
beforeCreate
-> 父created
-> 父beforeMount
- 子
beforeCreate
-> 子created
-> 子beforeMount
-> 子mounted
- 父
mounted
更新过程
父 beforeUpdate
-> 子 beforeUpdate
-> 子 updated
-> 父 updated
销毁过程
父 beforeDestroy
-> 子 beforeDestroy
-> 子 destroyed
-> 父 destroyed
watch
和 computed
区别
- 功能上:
computed
是计算属性,watch
是监听一个值的变化,然后执行对应的回调。 - 是否调用缓存:
computed
中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而watch
在每次监听的值发生变化的时候都会执行回调。 - 是否调用
return
:computed
中的函数必须要用return
返回,watch
中的函数不是必须要用return
。 computed
默认第一次加载的时候就开始监听;watch
默认第一次加载不做监听,如果需要第一次加载做监听,添加immediate
属性,设置为true
(immediate:true
)- 使用场景:
computed
当一个属性受多个属性影响的时候,使用computed
购物车商品结算。watch
当一条数据影响多条数据的时候,使用watch
搜索框。
D 公司(笔试题和面试题)
快到公司附近的照片
HTML5 Canvas 元素有什么用
Canvas
中文名叫 “画布”,是HTML5
新增的一个标签。Canvas
允许开发者通过JS
在这个标签上绘制各种图案。Canvas
拥有多种绘制路径、矩形、圆形、字符以及图片的方法。Canvas
在某些情况下可以 “代替” 图片。Canvas
可用于动画、游戏、数据可视化、图片编辑器、实时视频处理等领域。
HTML5 本地存储数据的方式和它们之间的区别
Web
存储的特性:
- 设置、读取方便。
- 容量较大,
sessionStorage
约5M
、localStorage
约20M
。 - 只能存储字符串,可以将对象
JSON.stringify()
编码后存储。
window.localStorage
:
- 存储的数据将保存在浏览器会话中。
- 永久生效,除非手动删除(比如清理垃圾的时候)。
- 可以多窗口共享。
window.sessionStorage
:
- 保存在内存中。
- 生命周期为关闭浏览器窗口。也就是说,当窗口关闭时数据销毁。
- 在同一个窗口下数据可以共享。
webstorage
与 cookie
的区别
cookie
数据始终在同源的http
请求中携带,cookie
在浏览器和服务器端来回传递,而localstorage
和sessionstorage
不会自动把数据传送给服务器端,仅在本地保存。- 存储大小限制不同,
cookie
的存储数据大小要求不能超过4k
,每次的http
请求都会携带cookie
,所以保存的数据需要比较小。sessionstorage
和localstorage
存储数据大小限制比cookie
要大,可以达到5M
或者更大,不同浏览器设置可能不同。 - 数据生命周期有所不同。
cookie
的生命周期一般在其设置的过期时间之前有效。而sessionstorage
仅在关闭窗口前有效,localstorage
持久有效,直到手动删除。 - 作用域不同,
sessionstorage
不在不同浏览器中共享,即使是同一页面也不支持。而localstorage
在所有同源窗口中都是共享的,同样,cookie
在所有同源窗口中也是可以共享。 cookie
的数据还有路径的概念,可以通过设置限制cookie
只属于某一个路径。webstorage
支持事件通知机制,可以将数据更新的通知发送给监听者。
使用 webstorage
的好处:
- 减少网络流量:使用
webstorage
将数据保存在本地中,不用像cookie
那样,每次传送信息都需要发送cookie
,减少了不必要的数据请求,同时减少数据在浏览器端和服务器端来回传递。 - 快速显示数据:从本地获取数据比通过网络从服务器获取数据效率要高,因此网页显示也要比较快。
- 临时存储:很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用
sessionStorage
. 非常方便。 - 不影响网站性能:因为
webstorage
只作用在客户端的浏览器,不会占用频宽,不影响网站性能,安全性低的资料存储在webstorage
中,提高网站效能。
bind、call、apply 用法及区别
- 三者都可以改变函数的
this
对象指向。 - 三者第一个参数都是
this
要指向的对象,如果如果没有这个参数或参数为undefined
或null
,则默认指向全局window
。 - 三者都可以传参,但是
apply
是数组,而call
是参数列表,且apply
和call
是一次性传入参数,而bind
可以分为多次传入 bind
是返回绑定this之后的函数,apply
、call
则是立即执行。
原型和原型链的区别
原型:Father.prototype
就是原型,它是一个对象,我们也称它为原型对象。
原型的作用,就是共享方法。通过 Father.prototype.method
可以共享方法,不会开辟新的内存空间存储方法。
原型链:原型与原型层层相链接的过程即为原型链。
Promise
和 async/await
的区别
async
函数是一种兼顾了基于Promise
的实现和 「生成器」(也就是ES6的新特性Generator
)的同步写法。
手写 Promise
Vue 组件间的通信有哪些
props
/$emit
$children
/$parent
(Vue2
)provide
/inject
ref
/refs
(Vue2
)eventBus
Vuex
$attrs
与$listeners
(Vue2
)
简述 Vuex
state
:用于数据的存储,是store中的唯一数据源getters
:如vue中的计算属性一样,基于state数据的二次包装,常用于数据的筛选和多个数据的相关性计算mutations
:类似函数,改变state数据的唯一途径,且不能用于处理异步事件actions
:类似于mutation
,用于提交mutation
来改变状态,而不直接变更状态,可以包含任意异步操作modules
:类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护
MVVM 框架是什么
MVVM 由 Model、View、ViewModel 三部分构成
- Model 代表数据模型,也可以在 Model 中定义数据修改和业务逻辑;
- View 代表 UI 组件,它负责将数据模型转化成 UI 展现出来;
- ViewModel 是一个同步View 和 Model的对象;
Vue 的两大核心点是什么,并简述它们的作用
Vue
的两大核心是数据驱动和组件化。
- 数据驱动是指
Vue
通过数据响应系统,实现了视图与数据的自动同步,当数据发生变化时,视图会自动更新,无需手动操作。这种数据驱动的方式让开发者能够更加专注于数据本身的处理,而不需要考虑视图的更新。 - 组件化是指
Vue
将一个页面拆分成一个个的组件,每个组件都是独立的,具有自己的样式、模板和逻辑,可以实现组件的复用和组合,简化了开发复杂页面的过程。通过组件化的方式,开发者可以更好地管理代码,提高代码的可维护性和可重用性。
Vue 响应式原理
怎么理解 Nuxt 的中间件
怎么处理多站点共享一个 token(同一个域名下多个标签页,有一个已经登录(可以是子域名),其他的标签页就不用登录。)
👉👉 多站点单点登录实现方案
如何实现一个团购的功能
我的回答是:需要看看别人是怎么实现的。
简述 uniapp 的应用生命周期和页面生命周期
应用生命周期:
生命周期 | 说明 |
---|---|
onLaunch | 当uni-app 初始化完成时触发(全局只触发一次) |
onShow | 当 uni-app 启动,或从后台进入前台显示 |
onHide | 当 uni-app 从前台进入后台 |
onError | 当 uni-app 报错时触发 |
onUniNViewMessage | 对 nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯(opens new window)| |
onUnhandledRejection | 对未处理的 Promise 拒绝事件监听函数(2.8.1+) |
onPageNotFound | 页面不存在监听函数 |
onThemeChange | 监听系统主题变化 |
<script>
// 只能在App.vue里监听应用的生命周期
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
onLaunch函数,会在APP打开时,只运行一次,通常用于App系统版本检测;
页面生命周期函数
函数名 | 说明 | 平台差异说明 | 最低版本 |
---|---|---|---|
onInit | 监听页面初始化,其参数同 onLoad 参数,为上个页面传递的数据,参数类型为 Object(用于页面传参),触发时机早于 onLoad | 百度小程序 | 3.1.0+ |
onLoad | 监听页面加载,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例 | ||
onShow | 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 | ||
onReady | 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发 | ||
onHide | 监听页面隐藏 | ||
onUnload | 监听页面卸载 | ||
onResize | 监听窗口尺寸变化 | App、微信小程序、快手小程序 | |
onPullDownRefresh | 监听用户下拉动作,一般用于下拉刷新,参考示例 | ||
onReachBottom | 页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。具体见下方注意事项 | ||
onTabItemTap | 点击 tab 时触发,参数为Object,具体见下方注意事项 | 微信小程序、QQ小程序、支付宝小程序、百度小程序、H5、App、快手小程序、京东小程序 | |
onShareAppMessage | 用户点击右上角分享 | 微信小程序、QQ小程序、支付宝小程序、字节小程序、飞书小程序、快手小程序、京东小程序 | |
onPageScroll | 监听页面滚动,参数为Object | nvue暂不支持 | |
onNavigationBarButtonTap | 监听原生标题栏按钮点击事件,参数为Object | App、H5 | |
onBackPress | 监听页面返回,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack ;详细说明及使用:onBackPress 详解 (opens new window)。支付宝小程序只有真机能触发,只能监听非navigateBack引起的返回,不可阻止默认行为。 | app、H5、支付宝小程序 | |
onNavigationBarSearchInputChanged | 监听原生标题栏搜索输入框输入内容变化事件 | App、H5 | 1.6.0 |
onNavigationBarSearchInputConfirmed | 监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发。 | App、H5 | 1.6.0 |
onNavigationBarSearchInputClicked | 监听原生标题栏搜索输入框点击事件(pages.json 中的 searchInput 配置 disabled 为 true 时才会触发) | App、H5 | 1.6.0 |
onShareTimeline | 监听用户点击右上角转发到朋友圈 | 微信小程序 | 2.8.1+ |
onAddToFavorites | 监听用户点击右上角收藏 |
前后端分离和不分离有什么区别
👉👉 聊聊前后端分离
上一家公司的项目主要做了哪些模块
独立负责简历上所列举的项目
项目中的难点
- 大文件上传
- 动态路由
- 权限管理
E 公司
如何实现按钮级别权限管理
如何实现动态路由
如何实现大文件上传
项目封装过哪些组件
- 打印插件
- 富文本编辑器
SVG
图标- 添加标签插件
如何全局注册并引用
封装了一个弹窗组件,调用时如何控制这个弹窗的显示和隐藏
Vue2 和 Vue3 的区别
Composition API
- 响应式原理
- 生命周期钩子名称
- 自定义指令钩子名称(指令钩子)
framents
(支持有多个根节点)createRenderer
(自定义渲染器)- 新的内置组件(
<Teleport>
、<Suspense>
) diff
算法
组合式 API 和选项式 API 的区别
ES6 有哪些新特性
箭头函数和普通函数的区别
- 箭头函数不会创建自己的
this
,它只会从自己的作用域链的上一层继承this
。 - 箭头函数继承而来的
this
指向永远不变 call
、apply
、bind
无法改变箭头函数中this
的指向- 箭头函数不能作为构造函数使用
- 箭头函数没有自己的
arguments
- 箭头函数没有原型
prototype
- 箭头函数不能用作
Generator
函数,不能使用yeild
关键字
说下你对 Promise 的理解
说下你对 Promise.all() 的了解
如何保证 Promise.all() 回调函数顺序和传入时的一致
如何实现数组中的对象去重
说下你对弹性布局的了解
说下你对 grid 布局的了解
说下你对小程序开发的了解
有对小程序或公众号的分享(分享到朋友圈、好友)进行过封装吗?
说下你对 uniapp 的了解
F 公司(前端,CTO 两人面试,历时近两个小时。)
前端性能优化
重绘和回流
Webpack 热更新原理
减速构建工具的流程
Vuex 的原理
说一下前端路由
浏览器存储的方式
强缓存和协商缓存
常见的 http 状态码
前端安全问题
多点登录(例如淘宝上已经登录了,再去天猫的话就不用登录。)
前端错误上报(性能监控、错误监控)
前端代码是否需要写单元测试、测试用例等
项目的前期准备工作
需求不太合理的地方如何处理?
工作上遇到冲突如何和同事沟通解决?
最近的项目遇到哪些问题?你是如何处理?
最近的几个月在做些什么事?
前端发展日新月异,如何保证自己能跟上趋势?
作为前端开发,你的优势是什么?
工作近五年,有什么引以为傲的地方?
最近在做些什么?学习什么东西?
生产环境出现问题,如何调试处理?
怎么看待前端的前景?
了解 Node.js,是否会做后端,或是全栈
最喜欢工作中的哪一部分?
上一家公司工作氛围怎么样?
工作项目中哪一个模块最难?
假如生产环境的数据量非常大,开发时如何考虑避免卡顿等问题?
对内和对外系统有哪些不同的点,需要考量的地方?
对工作项目有特殊的需求吗?
下一份工作有什么期望?
G 公司(视频面试)
谈谈你对 Vuex 的理解
H 公司(先前端面试,再 CTO 面)
项目中承担的是什么角色
项目主要解决了什么问题
如何实现请求接口压缩、解压,加密、解密?
在axios
的请求拦截器中带上token
传给后端,在响应拦截器中进行错误处理等。
举一反三的能力
在axios
的请求拦截器进行接口压缩、加密。
在axios
的响应拦截器进行接口解压、解密。
接触过 canvas 画图的工具吗?(医疗产品绘制心电图)
做过混合开发吗?(知道思路吗?)
如何解决跨域问题?
前端哪一方面较强?
接触过 WebSocket 通信吗?
接触过音视频(直播)系统吗?
如何保证系统健壮性、扩展性、可维护性等?
从零搭建项目框架(架构能力)
自己还未形成知识体系
做一个系统,需要考虑哪些点(站在 CSS 角度、JS 角度、选用哪个前端框架、UI框架、做自己的封装、路由的拆分、接口请求拦截、响应、异常捕获怎么解决、弹窗提示、消息提醒、缓存(清理)、加密、跨站脚本攻击、前端安全)
合作伙伴的效率(大家一眼就能看到)
项目中命名问题
定义什么样的规范
如何规划数据存放(WebStorage、Vuex、cookie)
一直都是在别人的带领下做项目,没有自己独立负责过项目吗?
工作效率如何?
京东的首页还原要多久?
为什么离职了?(刚好在时局不稳的时候出来)
有没有做过 uniapp 开发
CTO 的教诲
不要老是想着别人给你搭建好项目框架等,站在自己的角度,怎么去架构?去设计规划:
- 用先进的技术体系;
- 按照行业的通用(标准)规范执行落地。
其他问题
接受不了什么样的同事
- 没有责任心、团队精神。
- 自以为是。
- 充满负能量。
你的优势是什么
- 经验方面的优势:我有匹配胜任该岗位的从业经历。
- 技能方面的优势:我具备能够做好该岗位工作的必备技能。
- 兴趣方面的优势:我对该岗位比较感兴趣,大多数人对该岗位可能只认为是一份工作,而这个工作确是我的爱好。
- 工作风格方面的优势:我为人踏实靠谱,勤恳努力,愿意从基础工作做起。
- 性格方面的优势:我具备该岗位的某种特质。
- 正在准备或进行的优势:我为这个岗位做了很充分的准备,以便我能快速的上手。