前言
座標:杭州
。自己從事前端工作差不多2年,本人不是科班出身,算是一個小菜雞到現在剛入門吧。2年前去面試,因為技術菜,其實公司並沒有怎麼去了解我的技術,主要還是看個人的態度和學習能力,所以很感謝前面的倆個老東家,把我這個小菜雞帶入門了。今年,在上一個東家做的專案差不多也成型了,發現自己也到了一個一個瓶頸期吧,所以出來闖闖看。
出去面試其實就是一個快捷徑去認識到自己的不足,希望能給和我一樣在面試的江湖人一點小小的拋磚引玉吧。
筆試題
1)js的繼承是什麼?原型鏈?
function super (){
this.a = '1'
}
function sub (){
super.call(this)
}
複製程式碼
或者
function sub (){...}
sub.prototype = new super();
//直接在他的原型上new一個super的例項。
複製程式碼
在new的過程中,發生了,改變this的指向,執行super裡面的程式碼,返回一個新的函式。
es6的繼承方法。
class sub extends super(){
constructor(){
//super()和super(props)的區別
super() // cosole.log(this.props) undifined
super(props) // console.log(this.props) //列印出定義好的props
// super() 它在這裡表示父類的建構函式,用來新建父類的this物件。
//子類必須呼叫這個方法,不然繼承的話會報錯。子類必須在constructor方法中呼叫super方法,否則新建例項時會報錯。
//這是因為子類自己的this物件,必須先通過父類的建構函式完成塑造,
//得到與父類同樣的例項屬性和方法,然後再對其進行加工,
//加上子類自己的例項屬性和方法。如果不呼叫super方法,子類就得不到this物件。
}
// constractor一定是必要的嗎?
// 答 是的,就算你不宣告,也會隱式的把你宣告好一個空的constractor。
複製程式碼
2)ajax是什麼?
非同步的javascript+Xml
var xhr = new XmlHttpRequest() 或者 new ActiveXObject()
xhr.onreadyChange = function(){
if(xhr.readyState = 4){
if(xhr.status == 200){
var test = xhr.responseTest()
}
}
}
xhr.open("Get" , url ,false) //第三個引數,是否非同步
複製程式碼
3)如何對一個陣列做去重?
(1)set方法
var arr = new Set (arr);
arr = Array.from(arr);
複製程式碼
(2)還可以利用物件的key不能相同去做判斷
(3)for迴圈
4)rem和em的區別?
rem是相對於 根元素 上的font-size的大小
em是相對於 父元素 的font-size的大小
這裡對於em和rem的理解,不是很準確和深入,不想誤導新的朋友~ 下面有同學推薦了一個網站 綜合指南: 何時使用 Em 與 Rem
(更新於2018/07/03 22:51)
5)盒子模型
(1)普通盒子模型 boxsizing:content-box; (2)怪異盒子模型 boxsizing:border-box;
6)http的狀態碼
200 304 500 404 415 都可以去了解一下
7)實現一個函式能做到 function add(1)(2)(3) //6,達到function add(1)(2)(3)...(n)
這裡要引生出來倆個js內建的方法,valueOf
和toString
方法,在特定的情況下,這倆個方法都會自動呼叫,而且在使用者定義了新的valueof和tostring的時候,會優先執行新的方法。
在做字串拼接等需要呼叫tostring()方法的是有優先呼叫toString(),如果呼叫後還是不能返回原始型別的話會繼續呼叫valueOf方法。
而在做類似number的運算的時候會優先呼叫valueOf().
而對於函式而言,add 和add()的返回是不一樣的。add()會返回return的值。而add則會呼叫valueOf答應出來函式本身的程式碼.函式的轉換類似於number。
解題
function add () {
var args = [].slice.call(arguments);//這裡也用到了閉包的概念對args的儲存
var fn = function () {
var arg_fn = [].slice.call(arguments); //這裡的遞迴是為了合併引數
return add.apply(null, args.concat(arg_fn));
}
fn.valueOf = function() {
return args.reduce((a, b) => a + b);//真正的輸出是valueof
}
return fn;
}
複製程式碼
8)執行循序 setTimout和promise 這裡我們先要理解js是是單執行緒執行的。在記憶體中函式的執行是分同步和非同步的。 同步任務會放在主執行緒中一一執行,而非同步任務會先註冊到事件佇列裡。等待主執行緒任務執行完畢,才會去非同步佇列裡拿出任務放在主執行緒中去執行。
這裡還有倆個概念要去理解,巨集事件
微事件
。
巨集事件: script, setTimeout,setInterval
微事件:promise
這裡還要多說一句promise是立即執行的函式
setTimeout(function() {
console.log(1)
}, 0);
new Promise(function(a, b) {
console.log(2);
for(var i = 0; i < 10; i++) {
i == 9 && a();
}
console.log(3);
}).then(function() {
console.log(4)
});
console.log(5)
//輸出:2,3,5,4,1
複製程式碼
先執行巨集事件,再執行微事件,然後再迴圈.
9)
function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//請寫出以下輸出結果:
Foo.getName(); //2
getName(); // 4
Foo().getName(); // 1
getName(); // 1
new Foo.getName(); //2 相當於 new (Foo.getName)();
new Foo().getName(); // 3 相當於 (new Foo()).getName()
new new Foo().getName(); // 3 相當於 new ((new Foo()).getName)()
複製程式碼
new Foo.getName(); 和 new Foo().getName(); 的區別在於
new Foo 結合屬於 new 無引數列表的情況(17級)
new Foo() 結合屬於 new 有引數列表的情況(18級)
後三個可以參考js的運算子優先順序問題
- Object.defineProperty()和 {} 出來的物件有什麼區別
這個問題說實話,我還真不太確定是什麼,我覺得可能是defineProperty定義出來的物件 還可以定義是否可列舉,可讀寫的屬性吧
更新於2018/07/05
今天在列舉一個物件的時候,竟然發現defineProperty定義出來的物件, 如果不定義enumerable:true是不可以被列舉的,而{}這樣宣告出來的物件就可以直接被列舉!
11)http快取有什麼方法? 強快取,協商快取,304
強快取:carche-control :max-age
協商快取:利用304
12)call,apply的區別。這倆者和bind的區別。bind如何用原生實現出來。
call,apply的區別時後面的傳參。call時一個一個傳,apply時一個陣列。
bind能時返回一個新的函式。
Function.prototype.bind = function (context) {
//判斷呼叫此方法的是否是一個函式,不是函式就報錯
if (typeof this !== "function") {
throw new Error(this + "is not a function");
}
var self = this;
var args = [];
//把引數迴圈出來
for (var i = 1, len = arguments.length; i < len; i++) {
args.push(arguments[i]);
}
var fbound = function () {
var bindArgs = Array.prototype.slice.call(arguments);
self.apply(this instanceof self ? this : context, args.concat(bindArgs));
}
fbound.prototype = Object.create(self.prototype);
//返回的函式不僅要和 被調函式的函式體相同,也要繼承人家的原型鏈
return fbound;
}
複製程式碼
13)一句話打亂一個陣列?
arr.sort(function(){ return 0.5 - Math.random()})
複製程式碼
14)箭頭函式的this的指向問題
阮一峰部落格寫的很準確,推薦 箭頭函式
15)瀏覽器渲染原理 略(要很詳細的講,可能要寫一篇文章~,大家可以去開源社群找專門的文章去了解~)
16)右邊固定,左邊自適應。左邊固定右邊自適應。上面固定高度,下面自適應高度。
//左邊自適應,右邊固定
.float-box{
display:flex;
justify-content:end;
}
.left{
width: 100%;
border:1px solid #ddd;
}
.right{
width:300px;
border:1px solid #ddd;
}
複製程式碼
17)水平居中?水平垂直居中?
水平居中
inline 元素用text-align: center;即可,如下
.container {
text-align: center;
}
複製程式碼
block 元素可使用margin: auto;,PC 時代的很多網站都這麼搞。
.container {
text-align: center;
}
.item {
width: 1000px;
margin: auto;
}
複製程式碼
絕對定位元素可結合left和margin實現,但是必須知道寬度。
.container {
position: relative;
width: 500px;
}
.item {
width: 300px;
height: 100px;
position: absolute;
left: 50%;
margin: -150px;
}
複製程式碼
垂直居中
inline 元素可設定line-height的值等於height值,如單行文字垂直居中:
.container {
height: 50px;
line-height: 50px;
}
複製程式碼
絕對定位元素,可結合left和margin實現,但是必須知道尺寸。
- 優點:相容性好
- 缺點:需要提前知道尺寸
.container {
position: relative;
height: 200px;
}
.item {
width: 80px;
height: 40px;
position: absolute;
left: 50%;
top: 50%;
margin-top: -20px;
margin-left: -40px;
}
複製程式碼
絕對定位可結合transform實現居中。
- 優點:不需要提前知道尺寸
- 缺點:相容性不好
.container {
position: relative;
height: 200px;
}
.item {
width: 80px;
height: 40px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background: blue;
}
複製程式碼
絕對定位結合margin: auto,不需要提前知道尺寸,相容性好。
.container {
position: relative;
height: 300px;
}
.item {
width: 100px;
height: 50px;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
複製程式碼
下節預告:
演算法題
~~ 我已經在努力高產的像母豬了~
更新於 2018/7/03 11:38
噹噹噹~ 新鮮出爐~ 2018年6月前端面試經歷(中)