面試官主要還是針對簡歷上的內(nèi)容進行提問的继效,所以一定要把寫在簡歷上的內(nèi)容自己進行深挖并拓展不僅要有廣度,更要有深度愉舔,以下是我的面試題以及自己整理出來的答案炭晒,有不同意見可以評論區(qū)交流一下,我寫的答案僅供參考受楼。
題目
帶連接符的字符串轉(zhuǎn)駝峰的方法
css實現(xiàn)一個寬度為頁面寬度的正方形垦搬,幾種方法
bootstrap實現(xiàn)柵格話布局原理
移動端適配方案
構(gòu)造函數(shù)重寫,指針指向艳汽,實例化構(gòu)造函數(shù)的時候都做了什么
手寫一個復(fù)選框列表的組件猴贰,實現(xiàn)全選和取消效果<check-list v-model="checkIds" :checkList="checkList"></check-list>
promise的原理手動實現(xiàn)一個簡單的promise、 promise.all河狐、 promise.race米绕、promise實現(xiàn)一個原生ajax、promise實現(xiàn)一個圖片加載
webpack了解多少甚牲,自己做了哪些配置
loader和plugins的區(qū)別
有沒有手寫過loader
nodejs
-
react
- this.setState是怎么實現(xiàn)異步的
- 宏任務(wù)/微任務(wù)
- hook
promise的原理义郑,是怎么實現(xiàn)的(同7)
seo優(yōu)化的過程是什么樣的(自己項目上的蝶柿,有興趣可以了解一下丈钙,每一個操作的原因是什么, 為什么不直接用js交汤,反而用jsp代替了(服務(wù)端渲染ssr)
es6常用的方法
有沒有用canvas做過截圖
函數(shù)式編程
柯里化雏赦?compose劫笙?
vue 組件 data為什么必須是函數(shù)?
設(shè)計模式的實現(xiàn),工廠者模式星岗、發(fā)布者訂閱者模式手寫代碼說明
代碼中有很多console.log填大,如何做到不改動代碼的提前下,做到log內(nèi)容的上報
正則實現(xiàn)首單享受<hightLight>50</highLight>元福利
轉(zhuǎn)換成
首單享受<span class='highLight'>50</span>元福利-
flex實現(xiàn)以下布局
rem適配怎么設(shè)置0.01rem =1px
typescript
自己覺得印象最深的項目俏橘,然后都做了什么事情
-
跨端項目:如何實現(xiàn)與端之間的通信允华,
如何讓客戶端知道我需要拍照
另外canvas實現(xiàn)一個手動馬賽克的效果 函數(shù)防抖和節(jié)流
31.筆試題:求連續(xù)子數(shù)組的最大和javascript實現(xiàn)繼承的6種方式和其優(yōu)缺點
jquery鏈式調(diào)用的實現(xiàn)方式
實現(xiàn)一個Array.filter
vuex的使用和原理
小程序是如何實現(xiàn)視圖層和邏輯層的聯(lián)系的
uniapp的跨端方案是如何實現(xiàn)的
單元測試怎么查看覆蓋率的
V8引擎垃圾回收機制:導(dǎo)致內(nèi)存泄漏的原因 -> 規(guī)避遞歸導(dǎo)致的內(nèi)存泄漏:蹦床
A網(wǎng)站請求B網(wǎng)站的多個js文件,可以同時獲取嗎(HTTP2多路復(fù)用)
Set寥掐、WeakSet靴寂、Map、WeakMap的區(qū)別
內(nèi)存中的變量是如何分配存儲的
var和let的區(qū)別
查找鏈表的倒數(shù)第N個節(jié)點
flexible適配的原理召耘,rem和em區(qū)別
this指針的理解和應(yīng)用場景百炬,構(gòu)造函數(shù)中的this指針問題
jquery中的鏈式調(diào)用是怎么實現(xiàn)的
proxy相對于defineproperty的優(yōu)勢
jsBridge的回調(diào),以及客戶端實現(xiàn)
webpack的treeShaking與其他打包工具之間的差異
服務(wù)端渲染的深入了解污它,nodejs返回頁面之后是如何加載其他的script和css資源的
call, apply, bind的區(qū)別
事件冒泡和捕獲了解嗎剖踊?先冒泡還是先捕獲
axios做了哪些封裝
http和https的區(qū)別,https相對于http的優(yōu)點和缺點
http2相對于http1的優(yōu)化
cookies和session的區(qū)別
瀏覽器緩存
vue的通信方式
vuex的常用的屬性衫贬,多模塊的情況下和單模塊的異同
mvvm和mvc的區(qū)別
animation和transition的區(qū)別德澈,以及如何知道這個動畫執(zhí)行完畢
position和transform的區(qū)別和優(yōu)缺點
async返回什么,setTimeout和promise的執(zhí)行順序固惯,為什么
輸出結(jié)果是什么
var n = 0
function a() {
var n = 10
function b() {
n++
console.log(n)
}
b()
return b
}
var c = a()
c()
console.log(n)
64.js實現(xiàn)深度拷貝
Javascript的事件流模型都有什么?
promise 實現(xiàn)一個圖片加載,完成loadImg
loadImg('/a.png').then( res=>{
***
})
300px div
內(nèi)容一行內(nèi)容居中顯示多行居左顯示打印輸出
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
}).then(function() {
console.log('promise3');
})
new Promise(function(resolve) {
console.log('promise4');
resolve();
}).then(function() {
console.log('promise5');
});
console.log('script end');
- 打印輸出
var a = 10;
function a() { };
console.log(a);
(function () {
console.log(a)
a = 5
console.log(window.a)
var a = 20
})()
console.log(a)
- 父元素寬高未知圃验,子元素圖片的寬高未知,實現(xiàn)圖片居中顯示的多種方式(grid布局了解嗎缝呕,margin和padding分別是相對于誰的)
- 多種方法實現(xiàn)數(shù)組的亂排序
- 多種方式實現(xiàn)去除數(shù)組的空元素
- 如何實現(xiàn)a==1&&a==2&&a==3(結(jié)合defineProperty和proxy來做澳窑,考察對數(shù)據(jù)劫持和隱式轉(zhuǎn)換函數(shù)重寫的理解)
- nextTick的實現(xiàn)原理(考察vue異步批量更新)
- 瀏覽器緩存讀取規(guī)則:可以分成 Service Worker、Memory Cache供常、Disk Cache 和 Push Cache摊聋,那請求 的時候 from memory cache 和 from disk cache 的依據(jù)是什么,哪些數(shù)據(jù)什么 時候存放在 Memory Cache 和 Disk Cache 中栈暇?
- 原生操作dom的方法有哪些
- 求輸出結(jié)果(字節(jié)跳動)
new Promise(function(resolve) {
for (var i = 0; i < 10; i++) {
resolve(i);
}
}).then(function(i) {
console.log(i);
});
new Promise(function(resolve) {
for (var i = 0; i < 10; i++) {
function a() {
resolve(i);
}
}
a();
}).then(function(i) {
console.log(i);
});
// 0
// 10
- 實現(xiàn)一個柯里化函數(shù)
// 實現(xiàn) currying 函數(shù)麻裁,使得 curryingSum 函數(shù)輸出正確
const currying = (func) => {
var args = Array.prototype.slice.call(arguments, 1) // 除卻第一個參數(shù)
var curry = function () {
if (arguments.length === 0) {
return func.apply(this, args) // 無參數(shù)時直接返回求和的值
} else {
args = args.concat(Array.prototype.slice.call(arguments)) // 如果后續(xù)繼續(xù)有參數(shù),直接返回該函數(shù)
// console.log(args)
return curry
}
}
return curry
}
const sum = (...args) => args.reduce((prev, cur) => prev + cur, 0)
sum(1, 2, 3) // 6
const curryingSum = currying(sum)
console.log(curryingSum(1)(2)(3)())
console.log(curryingSum(1, 2)(3)())
看到題目之后先別著急看答案源祈,自己思考一下
解答:
1. 帶連接符的字符串轉(zhuǎn)駝峰的方法 (如get-element-by-id)
- 方法1. 正則匹配(面試官想要的最優(yōu)解)
let str = 'get-element-by-id'
let res = str.replace(/-\w/g, (a) => {
return a.toUpperCase()
}).replace(/-/g, '')
console.log(res)
- 方法2. 字符串分割拼接
let str = 'get-element-by-id'
function toCamelCase (str) {
let str1 = str.split('-')
for (let i = 1; i < str1.length; i++) {
str1[i][0].toUpperCase()
}
return str1.join('')
}
console.log(toCamelCase(str))
2. css實現(xiàn)一個寬度為頁面寬度的正方形
- 方法1:vw
.child {
width: 50%;
height: 50vw;
background: #ccc;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
- 方法2:百分比
.child {
width: 50%;
height: 0;
padding-bottom:50%煎源;
background: #ccc;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
- 方法3
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.child {
display: flex;
width: 50%;
height: 50vw;
background: yellow;
}
3. bootstrap實現(xiàn)柵格話布局原理
柵格化列的種類,一行根據(jù)百分比分為12列,當col相加大于12時香缺,超出部分當作下一行展示
.col-xs-* 針對超小屏幕 手機(<768px)
.col-sm-* 小屏幕 平板 (≥768px)
.col-md-* 中等屏幕 桌面顯示器 (≥992px)(柵格參數(shù))
.col-lg-* 針對特大的(≥1200px)
通過媒體查詢根據(jù)不同的屏幕適配對應(yīng)的柵格化樣式手销,添加對應(yīng)的類,比如
/*超小設(shè)備(手機:小于768px)*/
@media(max-width:768px){
.col-xs-1{ width: 8.33333333%;}
.col-xs-2{ width: 16.66666667%;}
.col-xs-3{ width: 25%;}
.col-xs-4{ width: 33.33333333%;}
.col-xs-5{ width: 41.66666667%;}
.col-xs-6{ width: 50%;}
.col-xs-7{ width: 58.33333333%;}
.col-xs-8{ width: 66.66666667%;}
.col-xs-9{ width: 75%;}
.col-xs-10{ width: 83.33333333%;}
.col-xs-11{ width: 91.66666667%;}
.col-xs-12{ width: 100%;}
}
/*小型設(shè)備 (平板電腦:768px起)0*/
@media(min-width:768px){
.col-sm-1{ width: 8.33333333%;}
...
}
/*中型設(shè)備(臺式電腦:992px起)*/
@media(min-width:992px){
.col-md-1{ width: 8.33333333%;}
...
}
/*大型設(shè)備(臺式電腦:1200px起)*/
@media(min-width:1200px){
.col-lg-1{ width: 8.33333333%;}
...
}
4. 移動端適配方案
通過postcss-px-to-viewport插件實現(xiàn)px->vw的轉(zhuǎn)化,安裝插件之后進行如下配置
loaderOptions: { // css預(yù)設(shè)器配置項
postcss: {
plugins: [
require('postcss-px-to-viewport')({
unitToConvert: 'px',
viewportWidth: 750,
viewportHeight: 1334,
unitPrecision: 5,
propList: [
'*'
],
viewportUnit: 'vw',
fontViewportUnit: 'vw',
selectorBlackList: [],
minPixelValue: 1,
mediaQuery: false,
replace: true,
exclude: [/(\/|\\)(node_modules)(\/|\\)/]
})
]
},
stylus: {}
}
5. 實例化構(gòu)造函數(shù)图张, 求輸出結(jié)果
function A() {
this.a = 1
return {
a: 2,
b: 3
}
}
A.prototype.b = 4
A.prototype.c = 5
let newObj = new A()
console.log(newObj.a)
console.log(newObj.b)
console.log(newObj.c)
輸出:
2
3
undefined
考察點:new一個構(gòu)造函數(shù)時具體執(zhí)行了什么操作锋拖?
- 在內(nèi)存中新建一個空對象;
- this指向這個內(nèi)存中的空對象诈悍;
- 根據(jù)定義的鍵值和傳入的參數(shù),依次給這個空對象添加上鍵值對兽埃;
- 返回這個新的對象
6. 手寫一個復(fù)選框列表的組件侥钳,實現(xiàn)全選和取消效果<check-list v-model="checkIds" :checkList="checkList"></check-list>
考察點:v-model語法糖
父組件
<template>
<div class="list">
<input type="checkbox" v-model="chooseAll">全選
<check-list :checkIds="checkIds" :checkList="checkList" @update="arr => checkIds=arr"></check-list>
</div>
</template>
<script>
import CheckList from '@/components/CheckList'
export default {
name: 'list',
components: {
'check-list': CheckList
},
data () {
return {
chooseAll: false,
checkIds: [],
checkList: [{
id: 1,
name: '蘋果'
}, {
id: 2,
name: '梨'
}, {
id: 3,
name: '橘子'
}]
}
},
watch: {
chooseAll () {
if (this.chooseAll) {
this.checkIds = this.checkList.map(item => { return item.id })
} else if (!this.chooseAll && this.checkIds.length === this.checkList.length) {
this.checkIds = []
}
},
checkIds () {
this.chooseAll = this.checkIds.length === this.checkList.length
}
}
}
</script>
子組件
<template>
<div class="hello">
<ul>
<li v-for="item in checkList" :key="item.id">
<input type="checkbox" v-model="ids" :value="item.id" @change="$emit('update', ids)">{{item.name}}
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'CheckList',
props: {
checkList: Array,
checkIds: Array
},
data () {
return {
ids: []
}
},
watch: {
checkIds () {
console.log(this.checkIds)
this.ids = this.checkIds
}
}
}
</script>
7. 手動實現(xiàn)一個簡單的promise, promise.all/promise.race
promise
class Promise1 {
constructor (executor) {
this.state = 'pending'
this.result = null
this.reason = null
const resolve = value => {
this.state = 'fulfilled'
this.result = value
}
const reject = reason => {
this.state = 'rejected'
this.reason = reason
}
try {
executor(resolve, reject)
} catch (err) {
reject(err)
}
}
then (onFullfilled, onRejected) {
if (this.state === 'fulfilled') {
onFullfilled(this.result)
}
if (this.state === 'rejected') {
onRejected(this.reason)
}
}
}
const a = new Promise1((resolve, reject) => {
resolve('888888')
// reject('888888')
})
a.then(data => {
console.log(data)
})
promise.all
Promise1.all = function(promiseArr) {
let length = promiseArr.length
let result = []
let hasErr = false
return new Promise1((resolve, reject) => {
for (i = 0; i < length; i++) {
promiseArr[i].then(data => {
result[i] = data
if (i === length) resolve(result)
}, error => {
!hasErr && reject(error)
hasErr = true
})
}
})
}
promise.race
Promise1.race = function(promiseArr) {
let hasValue = false
let hasErr = false
return new Promise1((resolve, reject) => {
for (let i = 0; i < promiseArr.length; i++) {
promiseArr[i].then(data => {
if (!hasValue && !hasErr) resolve(data)
hasValue = true
}, error => {
if (!hasValue && !hasErr) reject(error)
hasErr = true
})
}
})
}
promise實現(xiàn)一個原生的ajax請求
let getJSON = function () {
let promise = new Promise((resolve, reject) => {
let client = new XMLHttpRequest()
client.open('get', url)
client.onreadystatechange = handler
clent.responseType = 'json'
client.setRequestHeader('Content-Type', 'application/json')
client.send()
function handler () {
if (this.readyState === 4) {
if (this.status === 200) {
resolve(this.response)
} else {
reject(new Error(this.statusText))
}
}
}
})
return promise
}
getJSON('/getJson').then((data) => {
console.log(data)
}, (err) => {
consoel.log('出錯了')
})
給定一張圖片的url柄错,通過promise實現(xiàn)一個圖片加載
const url1 = '***.png'
const url2 = '***2.png'
loadImg(url1).then(img=>{
console.log(img.width)
return img
}).then(img=>{
console.log(img.height)
return loadImg(url2)
}).then(img2=>{
console.log(img2.width)
return img2
}).then(img2=>{
console.log(img2.height)
})
.catch(err=>{
console.log(err)
})
- webpack了解多少舷夺,自己做了哪些配置
- loader和plugins的區(qū)別
- 有沒有手寫過loader
- nodejs
- react
- this.setState是怎么實現(xiàn)異步的
- 宏任務(wù)/微任務(wù)
- hook
- promise的原理,是怎么實現(xiàn)的(同7)
- seo優(yōu)化的過程是什么樣的(自己項目上的售貌,有興趣可以了解一下冕房,每一個操作的原因是什么, 為什么不直接用js趁矾,反而用jsp代替了(服務(wù)端渲染ssr)
- es6常用的方法
- seo優(yōu)化
- 設(shè)計模式的實現(xiàn)耙册,工廠者模式、發(fā)布者訂閱者模式手寫代碼說明
- 一個對象作為特定任務(wù)或是另一對象的活動的觀察者毫捣,并且在這個任務(wù)或活動發(fā)生時详拙,通知觀察者。觀察者也被叫作訂閱者(Subscriber)蔓同,它指向被觀察的對象饶辙,既被觀察者(Publisher 或 subject)。當事件發(fā)生時斑粱,被觀察者(Publisher)就會通知觀察者(subscriber)弃揽。
// 發(fā)布者訂閱者模式
let observer = {
callbacks: [],
add: function (fn) {
this.callbacks.push(fn)
},
trigger: function () {
this.callbacks.forEach((fn) => {
fn()
})
}
}
observer.add(function() {
console.log('我是訂閱者1')
})
observer.add(function() {
console.log('我是訂閱者2')
})
observer.trigger()
- 工廠模式:所謂工廠模式就是像工廠一樣重復(fù)的產(chǎn)生類似的產(chǎn)品,工廠模式只需要我們傳入正確的參數(shù)则北,就能生產(chǎn)類似的產(chǎn)品矿微;
工廠模式根據(jù)抽象程度依次分為簡單工廠模式、工廠方法模式尚揣、抽象工廠模式涌矢;
三種模式的代碼實現(xiàn):https://www.cnblogs.com/dengyao-blogs/p/11646810.html
- javascript實現(xiàn)繼承的6種方式和其優(yōu)缺點
https://blog.csdn.net/weixin_38343894/article/details/79214821 - 在使用jQuery庫的時候,是可以連續(xù)調(diào)用多個方法的快骗,這是怎么實現(xiàn)的呢
// 方法1娜庇,通過對象屬性的方式
let A = {
name: 'hello',
get: function () {
console.log(this.name)
return this
},
set: function () {
console.log(this.name)
return this
}
}
A.get().set()
// 方法2,通過函數(shù)的形式
function A () {
this.name = 'wyn'
}
A.prototype.get = function () {
console.log(this.name)
return this
}
A.prototype.set = function () {
this.name = 'www'
return this
}
let b = new A()
- 實現(xiàn)一個Array.filter
Array.prototype.filter = Array.prototype.filter || function (func) {
let arr = this
let r = []
for (let i = 0; i < arr.length; i++) {
if (func(arr[i])) {
r.push(arr[i])
}
}
return r
}
vuex的使用和原理
-
uniapp的跨端方案
uin-app 和原生開發(fā)是有很大差別的名秀,至少在性能和需求覆蓋度上會差很多。uin-app 框架使用的其實是 cordova 的進階版,也就是把 web 代碼打包到本地,本地實質(zhì)上還是通過 WebView 運行,那性能的瓶頸不言而喻畔塔。另外 uni-app 支持使用 Weex 框架拓展性能,本質(zhì)上是通過橋的功能把 Vue 控件映射為原生控件進行渲染杖刷,效果和 react-native 差不多,雖然性能有所提升,但是和原生相比差距還是有的调塌。
jsBridge的回調(diào),以及客戶端實現(xiàn)
webpack的treeShaking與其他打包工具之間的差異
服務(wù)端渲染的深入了解惠猿,nodejs返回頁面之后是如何加載其他的script和css資源的
事件冒泡和捕獲了解嗎?先冒泡還是先捕獲
axios做了哪些封裝
-
http和https的區(qū)別偶妖,https相對于http的優(yōu)點和缺點
http2相對于http1的優(yōu)化
[cookies和session的區(qū)別]s(https://www.cnblogs.com/l199616j/p/11195667.html)
瀏覽器緩存
vue的通信方式
vuex的常用的屬性姜凄,多模塊的情況下和單模塊的異同
mvvm和mvc的區(qū)別
animation和transition的區(qū)別,以及如何知道這個動畫執(zhí)行完畢
position和transform的區(qū)別和優(yōu)缺點
async返回什么趾访,setTimeout和promise的執(zhí)行順序态秧,為什么