摘要:為了避免它,只需分配將要使用的必要構(gòu)造函數(shù)。示例對(duì)于此示例,就需要保持父構(gòu)造函數(shù)繼續(xù)正常工作。結(jié)論手動(dòng)設(shè)置或更新構(gòu)造函數(shù)可能會(huì)導(dǎo)致不同且有時(shí)令人困惑的后果。為了防止它,只需在每個(gè)特定情況下定義構(gòu)造函數(shù)的角色。
hr小姐姐說(shuō)一共有1輪筆試 + 3輪技術(shù)面 + 1輪hr面,面試地點(diǎn)在中關(guān)村天使大廈,崗位是1-3年前端筆試
筆試分為多選 簡(jiǎn)答 判斷 手寫代碼四部分,下面只寫了印象比較深的幾道。
多選1、position為relative的元素可以使用top和left進(jìn)行定位嗎
答:可以。
我自己沒(méi)見(jiàn)過(guò)這種寫法,就沒(méi)敢選,然后錯(cuò)。
2、以下哪個(gè)是加密算法
答:RES、DES。
md5不算加密算法。
這部分題目是給出代碼,讓你寫輸出
1、
setTimeout(() => {console.log(1)}) const promise = new Promise(resolve => { setTimeout(() => {console.log(2)}) resolve() }) promise.then(() => {console.log(3)})
答:312。
考察macro/micro task
2、
for(var i = 1; i < 3; i++) { setTimeout(() => {console.log(i)}) }
答:3 3
考察異步,這個(gè)題簡(jiǎn)直是必考題
變種:
for(let i = 1; i< 3; i++) { setTimeout(() => {console.log(i)}) }
答:1 2
用let的話就會(huì)每輪循環(huán)都是一個(gè)嶄新的i
3、
function A() { this.a = "hi" console.log(this.a) } A.prototype.a = "hello" const a = new A() console.log(a.a)
答:hi hi
考察原型鏈,A.prototype.a = "hello",修改的是a原型上的a屬性,與a本身的a屬性無(wú)瓜。
瀏覽器運(yùn)行截圖
4、
[] == false
答:true
考察類型轉(zhuǎn)換,雙等運(yùn)算兩邊先轉(zhuǎn)換為Number
5、
[1,2,3].push(4)
答:4
考察常用函數(shù)返回值, 數(shù)組的push和unshift都返回最新數(shù)組的長(zhǎng)度
判斷就5道題,挺簡(jiǎn)單的,沒(méi)啥印象
手寫代碼手寫一個(gè)節(jié)流函數(shù),這個(gè)網(wǎng)上一搜一大把就不說(shuō)了
一面筆試寫了大概30-40分鐘,一面的面試官就來(lái)了,看答題情況的時(shí)候順便要求介紹一下自己,然后針對(duì)題目做了一些講解,然后開(kāi)始問(wèn)問(wèn)題。
1、再手寫一個(gè)防抖,我寫了一個(gè)第一次觸發(fā)事件不會(huì)調(diào)用回調(diào)的,面試官又問(wèn)如果希望首次也會(huì)調(diào)用怎么寫,代碼如下
var debounce = function(fn, delayTime, immediate) { var timeId; return function() { var context = this, args = arguments; if(immediate) { var callNow = !timeId; if(callNow) { fn.apply(context, args); } } timeId && clearTimeout(timeId); timeId = setTimeout(function() { fn.apply(context, args); }, delayTime) } }
然后還聊了一下時(shí)間戳和定時(shí)器的方式實(shí)現(xiàn)節(jié)流的不同,需要注意箭頭函數(shù)是不可以使用arguments對(duì)象的,所以返回的函數(shù)必須要寫成return function() {}
2、有什么實(shí)現(xiàn)深拷貝的方法嗎
??????我一開(kāi)始以為他說(shuō)api,就回答JSON.parse(JSON.stringfy())和MessageChannel,他問(wèn)有什么問(wèn)題嗎。我說(shuō)不能解決復(fù)制函數(shù)和環(huán)的問(wèn)題。他又問(wèn)那你能自己實(shí)現(xiàn)一個(gè)嗎,繼續(xù)手寫代碼
function isObject(obj) { return obj !== null && typeof obj === "object" } function cloneDeep(obj) { let result = {} const keys = Object.keys(obj); for(let i = 0, len = keys.length; i < len; i++) { if(isObject(obj[keys[i]])){ result[keys[i]] = cloneDeep(obj[keys[i]]) } else { result[keys[i]] = obj[keys[i]] } } return resultset }
??????寫完之后他又問(wèn)我應(yīng)該如何判斷一個(gè)變量是數(shù)組,答Array.isArray()和Object.prototype.toString.call(arr) === "[object Array]",回來(lái)反思發(fā)現(xiàn)可能是寫深拷貝的時(shí)候忘記了數(shù)組的情況,然后他才問(wèn)的判斷數(shù)組。
3、如何用css畫一個(gè)三角形
答:heigh: 0; width: 0; border: 100px, solid, transparent; border-bottom: 100px, solid, yellow;
4、怎么實(shí)現(xiàn)垂直居中
答:position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); 還有flex;
5、簡(jiǎn)單說(shuō)一下前端優(yōu)化策略
答:減少請(qǐng)求,他:具體應(yīng)該怎么減少,我:比如圖片懶加載,配置svg-sprite-loader打包一張svg圖面,然后就是減少dom操作,減少瀏覽器回流重繪次數(shù),減少作用域鏈的查找,減少對(duì)象的深度查找。他:還有嗎。我:暫時(shí)想不起其它了
優(yōu)化涉及的東西太多了,以后再多帶帶總結(jié)吧。
6、new一個(gè)對(duì)象的時(shí)候發(fā)生了什么
這個(gè)問(wèn)題是講解筆試簡(jiǎn)答第三題時(shí)候問(wèn)的
正確答案:1.創(chuàng)建一個(gè)空對(duì)象; 2.設(shè)置創(chuàng)建對(duì)象的__proto__屬性的值為構(gòu)造函數(shù)的prototype屬性的值; 3.將第一步創(chuàng)建的空對(duì)象作為this的上下文,執(zhí)行構(gòu)造函數(shù)代碼; 如果構(gòu)造函數(shù)沒(méi)有返回對(duì)象,那么返回this
7、看你簡(jiǎn)歷上寫最近在看vue源碼,那你知道nextTick咋實(shí)現(xiàn)的嗎
答:2.6的版本是promise,mutationObserver,setTimeout,setImmediate
??????至此面試官說(shuō)一面差不多就到這里,算法啥的留給二面吧,他給我的一面評(píng)價(jià)是知識(shí)廣度不夠(因?yàn)楣P試錯(cuò)了比較多),但是感覺(jué)人比較有靈性,可以進(jìn)入二面,然后就去叫下一個(gè)boss了。
二面??????二面面試官看起來(lái)比前一個(gè)要嚴(yán)厲好多,以為要問(wèn)一些算法題,結(jié)果"一面反饋基礎(chǔ)不夠扎實(shí),那我就再問(wèn)一點(diǎn)" "GG"
1、import和require的區(qū)別
答:import輸出引用,require輸出拷貝。他:還有嗎。 我:不知道了。他:還有require是運(yùn)行時(shí)加載,import是編譯時(shí)輸出接口。
2、說(shuō)一下瀏覽器的事件傳播機(jī)制
答:不知道
正確答案: 事件傳播分為三個(gè)階段:捕獲,目標(biāo)對(duì)象,冒泡。其中捕獲是事件對(duì)象從window派發(fā)到目標(biāo)對(duì)象父級(jí)的過(guò)程;目標(biāo)階段是事件對(duì)象派發(fā)到目標(biāo)元素時(shí)的階段,如果事件類型指示不冒泡,那事件傳播在此階段終止;冒泡和捕獲相反,是以目標(biāo)對(duì)象父級(jí)到window的過(guò)程。
3、手寫一個(gè)bind
答:不知道。
平時(shí)用的都是call和apply來(lái)改this,bind只用過(guò)一兩次,手寫call也看過(guò),但是我連bind的參數(shù)是啥都沒(méi)印象,寫個(gè)錘子。
正確答案:
///使用call Function.prototype.cvBind = function() { var self = this var context = [].shift.call(arguments) var args = Array.from(arguments) return function() { return self.call(context, ...args) } } // 不用call Function.prototype.cvBind = function() { var context = [].shift.call(arguments) context.fn = this var args = [] var argument = [].slice.call(arguments, 0) for(var i = 0, len = argument.length; i < len; i++) { args.push("argument[" + i + "]") } return function() { var result = eval("context.fn(" + args + ")") delete context.fn return result } } // 測(cè)試 var obj = { a: "local", log: function(x, y) { console.log(this.a, x, y) } } var a = "window" obj.log("arg1", "arg2") var func = obj.log.cvBind(window, "arg1", "arg2") func()
需要注意不用call的版本需要拷貝一次arguments,不然return的函數(shù)中args數(shù)組里都是undefined,上面的代碼不考慮參數(shù)是引用類型變量。
4、寫一個(gè)繼承
答:不知道
正確答案:
4.1類式繼承,通過(guò)構(gòu)造函數(shù)實(shí)現(xiàn)繼承
//父類 function Parent(name) { this.name = name || "parent" } Parent.prototype.say = function() { return this.name } //子類 function Child() {}
4.1.1 父類對(duì)象繼承
Child.prototype = new Parent("child") var child = new Child() child.say()
這種繼承方式,子類繼承父類自身屬性和父類原型上的屬性,但是缺點(diǎn)在于初始化父類對(duì)象指給子類原型時(shí),并不能確定父類構(gòu)造函數(shù)的初始化參數(shù)。
4.1.2 改造子類構(gòu)造函數(shù)
function Child() { Parent.apply(this, arguments) }
弟中弟方法,只能繼承父類自身方法
4.1.3 共享原型
Child.prototype = Parent.prototype
弟中弟中弟,共享一個(gè)原型,子類修改會(huì)影響父類(然而面試的時(shí)候腦子里浮現(xiàn)的就是這種)
4.1.4 臨時(shí)構(gòu)造函數(shù)
function inherit(Child, Parent) { var F = function() {} F.prototype = Parent.protoType Child.protoype = new F() }
利用一個(gè)空函數(shù)F()充當(dāng)子類父類之間的代理,既可以實(shí)現(xiàn)父類原型屬性的繼承,也可以在子類原型上隨意拓展
使用Object.create()可以達(dá)到相同效果
Child.prototype = Object.create(Parent.prototype)
4.1.5 關(guān)于protptype.constructor
整理資料的時(shí)候,發(fā)現(xiàn)有些在繼承后又寫了一句Child.prototype.constructor = Child,有些就沒(méi)有。首先這個(gè)constructor時(shí)創(chuàng)建實(shí)例對(duì)象的構(gòu)造函數(shù)的引用,然后就是這句話到底有用沒(méi)用,下面是ctrl cv自MDN的兩個(gè)例子以及結(jié)論
示例1:
function Parent() {}; function CreatedConstructor() {} CreatedConstructor.prototype = Object.create(Parent.prototype); CreatedConstructor.prototype.create = function create() { return new this.constructor(); } new CreatedConstructor().create().create(); // error undefined is not a function since constructor === Parent
在上面的示例中,將顯示異常,因?yàn)闃?gòu)造函數(shù)鏈接到Parent。為了避免它,只需分配將要使用的必要構(gòu)造函數(shù)。
function Parent() {}; function CreatedConstructor() {} CreatedConstructor.prototype = Object.create(Parent.prototype); CreatedConstructor.prototype.constructor = CreatedConstructor; // set right constructor for further using CreatedConstructor.prototype.create = function create() { return new this.constructor(); } new CreatedConstructor().create().create(); // it"s pretty fine
示例2:
function ParentWithStatic() {} ParentWithStatic.startPosition = { x: 0, y:0 }; ParentWithStatic.getStartPosition = function getStartPosition() { return this.startPosition; } function Child(x, y) { this.position = { x: x, y: y }; } Child.prototype = Object.create(ParentWithStatic.prototype); Child.prototype.constructor = Child; Child.prototype.getOffsetByInitialPosition = function getOffsetByInitialPosition() { var position = this.position; var startPosition = this.constructor.getStartPosition(); // error undefined is not a function, since the constructor is Child return { offsetX: startPosition.x - position.x, offsetY: startPosition.y - position.y } };
對(duì)于此示例,就需要保持父構(gòu)造函數(shù)繼續(xù)正常工作。
結(jié)論:手動(dòng)設(shè)置或更新構(gòu)造函數(shù)可能會(huì)導(dǎo)致不同且有時(shí)令人困惑的后果。為了防止它,只需在每個(gè)特定情況下定義構(gòu)造函數(shù)的角色。在大多數(shù)情況下,不使用構(gòu)造函數(shù),并且不需要重新分配構(gòu)造函數(shù)。
4.2 通過(guò)復(fù)制屬性實(shí)現(xiàn)繼承
淺拷貝和4.1.3的共享原型沒(méi)區(qū)別,深拷貝繼承之后修改父類,子類不會(huì)改變。都有問(wèn)題不過(guò)也是一種思路,順帶一提。
5、跨域有哪些解決方案
答:iframe, jsonp, cors。他:用過(guò)jsonp嗎。答:沒(méi)有,用的都是cors。他:那說(shuō)一下cors是怎么解決跨域問(wèn)題的。我:不知道。他:那請(qǐng)求頭里有哪些相關(guān)的字段。我:(我知道你真的很給機(jī)會(huì)了但是對(duì)不起我是個(gè)菜雞我真的)不知道。他:用過(guò)nginx嗎。我:沒(méi)有。
正確答案:點(diǎn)這里
balabala一些客套話,問(wèn)我有什么問(wèn)題,我說(shuō)沒(méi)有,然后結(jié)束。
路漫漫其修遠(yuǎn)兮認(rèn)識(shí)到差距也更有前進(jìn)的動(dòng)力,繼續(xù)加油
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/106266.html
摘要:這是一次失敗的面經(jīng)但是吃一塹才能長(zhǎng)一智不是嗎字節(jié)跳動(dòng)校招面經(jīng)前端開(kāi)發(fā)崗一介紹以及項(xiàng)目經(jīng)歷吧啦吧啦此處省略字面試官會(huì)從項(xiàng)目經(jīng)歷入手,考察項(xiàng)目中遇到的難題,以及解決方法,強(qiáng)調(diào)個(gè)人的努力以及在解決過(guò)程中扮演的角色是主導(dǎo)還是參與。 這是一次失敗的面經(jīng)……但是吃一塹才能長(zhǎng)一智不是嗎? 字節(jié)跳動(dòng)2019校招面經(jīng) - 前端開(kāi)發(fā)崗(一) 1. 介紹以及項(xiàng)目經(jīng)歷 吧啦吧啦……此處省略10000字 面試官...
摘要:春招前端實(shí)習(xí)面試記錄從就開(kāi)始漸漸的進(jìn)行復(fù)習(xí),月末開(kāi)始面試,到現(xiàn)在四月中旬基本宣告結(jié)束。上海愛(ài)樂(lè)奇一面盒模型除之外的面向?qū)ο笳Z(yǔ)言繼承因?yàn)槭且曨l面試,只記得這么多,只感覺(jué)考察的面很廣,前端后端移動(dòng)端都問(wèn)了,某方面也有深度。 春招前端實(shí)習(xí)面試記錄(2019.3 ~ 2019.5) 從2019.1就開(kāi)始漸漸的進(jìn)行復(fù)習(xí),2月末開(kāi)始面試,到現(xiàn)在四月中旬基本宣告結(jié)束。在3月和4月經(jīng)歷了無(wú)數(shù)次失敗,沮...
摘要:面試后面試后及時(shí)總結(jié),有可能下一個(gè)面試官會(huì)問(wèn)你同樣的問(wèn)題。同時(shí)面試官也對(duì)我的未來(lái)技術(shù)發(fā)展提出了很多建議。總的來(lái)說(shuō),四面的氛圍并沒(méi)有想象得那么嚴(yán)肅,面試官也說(shuō)面試得很愉快。 ...
摘要:為什么狀態(tài)需要經(jīng)過(guò)最大報(bào)文段生存時(shí)間才能返回到狀態(tài)雖然按道理,四個(gè)報(bào)文都發(fā)送完畢,我們可以直接進(jìn)入狀態(tài)了,但是我們必須假象網(wǎng)絡(luò)是不可靠的,有可以最后一個(gè)丟失。所以狀態(tài)就是用來(lái)重發(fā)可能丟失的報(bào)文。 1、TCP的三次握手和四次揮手 1.1 三次握手: 客戶端請(qǐng)求 -> 服務(wù)器響應(yīng) -> 客戶端確認(rèn)收到響應(yīng),建立連接(保證網(wǎng)絡(luò)正常) showImg(https://segmentfault....
閱讀 3093·2021-11-22 09:34
閱讀 593·2021-11-22 09:34
閱讀 2437·2021-10-08 10:18
閱讀 3372·2021-09-22 15:57
閱讀 2585·2021-09-22 15:25
閱讀 2398·2019-08-30 15:54
閱讀 2093·2019-08-30 15:44
閱讀 1799·2019-08-29 11:18