2020年前端面試題(10題)

想看花開發表於2020-12-26

1、判斷陣列與物件

(轉自:https://blog.csdn.net/weixin_42995876/article/details/87985843)

1.typeof
使用typeof來檢測資料型別,但是對於Function, String, Number, Undefined等這幾種基本型別來說,使用typeof來檢測都可以檢測到,比如程式碼如下:

function test(){}
console.log(typeof 1); // number
console.log(typeof test); // function 
console.log(typeof "yunxi"); // string
console.log(typeof undefined); // undefined

但是對於陣列或者正則來說,使用typeof來檢測的話,就不行,因為當我們檢測陣列或者正則的話,返回的型別將會是一個物件object,如下程式碼所示:

console.log(typeof []);  // object
console.log(typeof {}); // object
console.log(typeof null); // object  // null是一個空物件
console.log(typeof function(){}); // function
console.log(typeof NaN); // number
console.log(typeof undefined); // undefined
console.log(typeof /\d+/g); // object
  1. objectName instanceof Array

instanceof操作符用來判斷要檢測物件的原型鏈上是否存在某個建構函式的prototype屬性。

語法: A instanceof B,意思是物件A的原型是否是B.prototype。如果是,返回true,如果不是,返回false。

var a = [];
var b = {};
var c= function(){};
console.log(a instanceof Array); // true
console.log(a instanceof Object); // true  陣列也是物件
console.log(a instanceof Function); // false  
console.log(b instanceof Array); // false
console.log(b instanceof Object); // true
console.log(b instanceof Function); // false
console.log(c instanceof Array); // false
console.log(c instanceof Object); // true 函式也是物件
console.log(c instanceof Function); // true

有一個問題就是,它假定只有一個全域性作用域。如果一個網頁中有多個框架(iframe元素),那實際上就存在兩個以上不同的全域性執行環境,從而存在兩個以上不同版本的Array建構函式。如果你從一個框架向另一個框架傳入一個陣列,那麼傳入的陣列與在第二個框架中原生建立的陣列分別具有各自不同的建構函式。傳入的陣列在該框架中用instanceof操作符判斷就會返回false。

var a = {};
var b = [];
console.log(a instanceof Object);//true
console.log(b instanceof Array);//true
var frame = document.createElement("iframe"); // 建立一個框架
document.body.appendChild(frame);
console.log(window.frames);
console.log(window.frames[0]);
console.log(window.frames[0].Array); // ƒ Array() { [native code] }
var c = window.frames[0].Array; // 取得框架全域性執行環境中的Array建構函式
var d = new c(); // 在框架全域性執行環境中建立一個陣列d
console.log(d instanceof Array); // 在當前頁面的執行環境中用instanceof操作符判斷d是否為陣列,返回false
console.log(Array.isArray(d)); // true
  1. objectName.constructor == Array
var a=[]; // 陣列
var b={}; // 物件
var c=function(){}; // 函式
var d=null;
var e=NaN;
var e=undefined;
console.log(a.constructor); // ƒ Array() { [native code] }
console.log(b.constructor); // ƒ Object() { [native code] }
console.log(c.constructor); // ƒ Function() { [native code] }
// console.log(d.constructor); // Uncaught TypeError: Cannot read property 'constructor' of null
console.log(e.constructor); // ƒ Number() { [native code] }
// console.log(f.constructor); // Uncaught TypeError: Cannot read property 'constructor' of undefined

console.log(a.constructor === Array); // true 只有陣列的constructor是Array
console.log(a.constructor === Object); // false
console.log(a.constructor === Function); // false

console.log(b.constructor === Array); // false
console.log(b.constructor === Object); // true  只有物件的constructor是 Object
console.log(b.constructor === Function); // false

console.log(c.constructor === Array); // false
console.log(c.constructor === Object); // false
console.log(c.constructor === Function); // true 只有函式的constructor是 Function

// console.log(d.constructor); // 報錯
console.log(e.constructor === Number); // true

2、3判斷有誤差。
a)在不同 iframe 中建立的 Array 並不共享 prototype (2)
b)即使為true,也有可能不是陣列。 (3)

function SubArray(){}
SubArray.prototype = [];
myArray = new SubArray;
console.log(myArray instanceof Array); // true
  1. Array.isArray(objectName);

這個方法的作用就是確定某個值到底是不是陣列,而不管它到底是在哪個全域性執行環境中建立的。

console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
console.log(Array.isArray(null)); // false
console.log(Array.isArray(undefined)); // false
console.log(Array.isArray(function(){})); // false
  1. Object.prototype.toString.call(objectName)
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call({})); // [object Object]
console.log(Object.prototype.toString.call(function(){})); // [object Function]
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
console.log(Object.prototype.toString.call(null)); // [object Null]
console.log(Object.prototype.toString.call(NaN)); // [object Number]
console.log(Object.prototype.toString.call(1)); // [object Number]
console.log(Object.prototype.toString.call('abc')); // [object String]
console.log(Object.prototype.toString.call(false)); // [object Boolean]

綜上:
1.判斷是否為陣列:可以使用Array.isArray()和Object.prototype.toString.call()方法

2.判斷是否為物件:使用Object.prototype.toString.call()方法

2、引用樣式的方式

(轉自:https://blog.csdn.net/mybelief321/article/details/50188937)

css的樣式引用由3種方式。分別為內聯定義、鏈入內部CSS和鏈入外部CSS。

內聯定義:
即在物件的標記內使用物件的style屬性定義適用的樣式表屬性,格式定義為 :

<div style="內容"><div>

鏈入內部CSS

CSS內連結是由< style >< /style >標記對放在<head /head>中,在< style >中有一個型別屬性type,後面接test/css,表示CSS文字,語法格式如下:

  <style type="text/css">

   /*CSS內容*/

 </style>

連結外部CSS

把CSS檔案放在網頁外面,通過連結使CSS檔案對本網頁的樣式有效。

< link >裡面的屬性有type、rel、href,其中type固定為text/css,rel(即樣式表)固定為stylesheet,href指的就是css檔案的地址了,語法格式為:

  <link type="text/css" rel="stylesheet"  href="css檔案的存放地址">

三種樣式範圍及優先順序

連結外部CSS:作用在引用該CSS檔案的網頁中。

連結內部CSS:只作用在該CSS檔案的網頁中。

內聯定義:只作用在定義該樣式的div層中,對其它層無效。

優先順序:

內聯定義優先順序最高。

內部CSS次之。

外部CSS優先順序最低。

3、二級選單

(轉自:https://www.cnblogs.com/yzc1341/p/7063968.html)

1.給一級選單和二級選單設定一個div,並且使其二級選單部分隱藏。

2.設定好CSS樣式後,給每一個一級選單都新增一個onmouseover事件和onmouseout事件

3.使用for迴圈結合children結構偽類選擇器來實現其滑鼠移入下拉的功能。

<div id="nav">
                <ul>
                    <li>
                        <a href="#">html元素</a>
                        <div>
                            <a href="#">list-style</a>
                            <a href="#">decoration</a>
                            <a href="#">line-height</a>
                        </div>
                    </li>
                    <li>
                        <a href="#">js部分</a>
                        <div>
                            <a href="#">事件冒泡</a>
                            <a href="#">跨域</a>
                            <a href="#">ajax</a>
                        </div>
                    </li>
                    <li>
                        <a href="">jquery方法</a>
                        <div>
                            <a href="#">filter</a>
                            <a href="#">has</a>
                            <a href="#">find</a>
                            <a href="#">html</a>
                        </div>
                    </li>
                </ul>
            </div>
<style type="text/css">
            *{
                margin: 0px;
                padding:0px;
                font-size: 20px;
            }
            #nav{
                width:440px;
                background: #9ACD32;
                margin:auto;
            }
            #nav ul{
                list-style: none;
            }
            #nav ul li{
                width:110px;
                float: left;
            }
            #nav ul li a{
                display: block;
                text-decoration: none;
                text-align: center;
                background: #FF9090;
            }
            #nav ul li a:hover{
                background: #CCCCDD;
            }
            #nav ul li div {
                font-size: 18px;
                display: none;    
                
            }
            #nav ul li div a{
                font-size: 16px;
                line-height: 25px;
                text-align: center;
                background: #CCCCDD;    
                transition: background 2s;
            }
            #nav ul li div a:hover{
                background: #FF9090;
                font-size:19px;
            }
        </style>
<script type="text/javascript">
        window.onload=function(){
            var aLi=document.getElementById("nav").getElementsByTagName("li"); 
            for(var i=0; i<aLi.length;i++){
                
                aLi[i].onmouseover=function(){
                    this.children[1].style.display='block';//選取當前li元素的第二個子元素
                }
                aLi[i].onmouseout=function(){
                    this.children[1].style.display='none';
                }
            }
        }
    </script>

4、webstorm簡單介紹

(轉自:https://blog.csdn.net/qq_40741855/article/details/84260817)

WebStorm 是 JetBrains 推出的一款商業的 JavaScript 開發工具

我們可以理解它整合了很多你想要的功能,或者你不想要的功能。換句話說就是裝了很多外掛的 editor

任何一個編輯器都需要儲存(ctrl + s),這是所有win平臺上編輯類軟體的特點,但是webstorm編輯檔案右上角是沒有那個熟悉的 * 的。

好處:省去了ctrl + s之後,在結合Firefox的vim,基本不動滑鼠就可以看到結果頁面了。
壞處:沒有以前的 * 標識,萬一鍵盤誤操作也會被立即儲存。

任何一個編輯器只要檔案關閉了就沒有歷史記錄了,但是webstorm有。 vcs->Local History -> Show History(快捷鍵:ALT+~ -〉7)

好處:只要webstorm不關閉,你的檔案隨時可以返回到之前的操作(這也是為啥在 webstorm 裡ctrl+y是刪除一行的原因了)。
壞處:webstorm關閉重啟後這些歷史記錄就沒有了;還有一個壞處就是由此帶來的記憶體消耗也必然比較大。

任何一個編輯器,除了伺服器svn之外,沒有本地版本,但是webstorm提供一個本地檔案修改歷史記錄(快捷鍵:ALT+SHIFT+c,Mac中 ALT+Option+c)。也可以 Ctrl + E 彈出最近開啟的檔案。

好處:相當於本地svn。
壞處:記憶體消耗也必然比較大。

整合了zencoding,html5,ftp,即時編輯(chrome),自動完成,基於Mozilla的JavaScript偵錯程式,JSLint、Less支援、CoffeeScript支援、Node.JS、單元測試、整合git和svn版本控制等特性。

在編寫CSS中,會智慧的提示各種檔案以及圖片的路徑,就不用再去確認這個檔案是否存在了。

5、盒子模型(怪異模型)

(轉自:https://www.cnblogs.com/nyw1983/p/11326599.html)

盒子模型(Box Modle)可以用來對元素進行佈局,包括內邊距,邊框,外邊距,和實際內容這幾個部分。

盒子模型分為兩種 第一種是W3c標準的盒子模型(標準盒模型) 、第二種IE標準的盒子模型(怪異盒模型)

1、標準盒模型中width指內容區域content的寬度;height指的是內容區域content的高度。

標準盒模型下盒子的大小 = content + border + padding + margin在這裡插入圖片描述
2、怪異盒模型中的width指的是內容、邊框、內邊距總的寬度(content + border + padding);height指的是內容、邊框、內邊距總的高度

怪異盒模型下盒子的大小=width(content + border + padding) + margin

在這裡插入圖片描述
如果是定義完整的doctype的標準文件型別,無論是哪種模型情況,最終都會觸發標準模式,

如果doctype協議缺失,會由瀏覽器自己界定,在IE瀏覽器中IE9以下(IE6.IE7.IE8)的版本觸發怪異模式,其他瀏覽器中會預設為W3c標準模式。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>盒子模型</title>
<style>
#box1{
padding:20px;
background-color: greenyellow;
width: 100px;
height: 100px;
border:20px skyblue solid;
}
</style>
</head>
<body>
<div id="box1"></div>
</body>
</html>

在這裡插入圖片描述
除此之外,我們還可以通過屬性box-sizing來設定盒子模型的解析模式

可以為box-sizing賦三個值:

content-box: 預設值,border和padding不算到width範圍內,可以理解為是W3c的標準模型(default)

border-box:border和padding劃歸到width範圍內,可以理解為是IE的怪異盒模型

padding-box:將padding算入width範圍

當設定為box-sizing:content-box時,將採用標準模式解析計算(預設模式);

當設定為box-sizing:border-box時,將採用怪異模式解析計算;

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>怪異盒子練習</title>
    <style>
        div{
            width: 234px;
            height: 460px;
            background-color: #2e233e;
            padding: 20px 0px;
            box-sizing: border-box;
        }
        div li{
            font-size: 14px;
            height: 42px;
            line-height: 42px;
            padding-left: 30px;
        }
        a{color: white}
        li:hover{background-color: #ff6700;}
    </style>
</head>
<body>
    <div>
        <ul>
            <li><a href="">電器商城</a></li>
        </ul>
    </div>
</body>
</html>

6、圖片預載入和懶載入

(轉自:https://www.cnblogs.com/Leo_wl/p/3526254.html)

懶載入與預載入的基本概念。

懶載入也叫延遲載入:JS圖片延遲載入、延遲載入圖片或符合某些條件時才載入某些圖片。

預載入:提前載入圖片,當使用者需要檢視時可直接從本地快取中渲染。

兩種技術的本質:兩者的行為是相反的,一個是提前載入,一個是遲緩甚至不載入。

懶載入對伺服器前端有一定的緩解壓力作用,預載入則會增加伺服器前端壓力。

懶載入的意義及實現方式有:

意義: 懶載入的主要目的是作為伺服器前端的優化,減少請求數或延遲請求數。

實現方式:

1.第一種是純粹的延遲載入,使用setTimeOut或setInterval進行載入延遲.

2.第二種是條件載入,符合某些條件,或觸發了某些事件才開始非同步下載。

3.第三種是可視區載入,即僅載入使用者可以看到的區域,這個主要由監控滾動條來實現,一般會在距使用者看到某圖片前一定距離遍開始載入,這樣能保證使用者拉下時正好能看到圖片。

function loadImage(url,callback) {
    var img = new Image();
    
    img.src = url;

    if(img.complete) {  // 如果圖片已經存在於瀏覽器快取,直接呼叫回撥函式
        
        callback.call(img);
        return; // 直接返回,不用再處理onload事件
    }

    img.onload = function(){
        img.onload = null;
        callback.call(img);
    }
}

7、css選擇器的權重

(轉自:https://blog.csdn.net/u010297791/article/details/58602255)

CSS選擇器

1)id選擇器(#id)

使用ID選擇器之前需要先在html文件中的元素新增id名稱,這樣在樣式選擇器中才能找到相對應的元素,不同的是id選擇器是一個頁面中唯一的值,我們在類使用時是在相對應的類名前加上一個“.”號(.className)而id選擇器是在名稱前使用"#"如(#id)。

2)類選擇器(.className)

類選擇器是以一獨立於文件元素的方式來指定樣式,使用類選擇器之前需要在html元素上定義類名,換句話說需要保證類名在html標記中存在,這樣才能選擇類。

3)元素選擇器(E)

元素選擇器,是css選擇器中最常見而且最基本的選擇器。元素選擇器其實就是文件的元素,如html,body,p,div等等。

4)群組選擇器(selector1,selector2,…,selectorN)

群組選擇器是將具有相同樣式的元素分組在一起,每個選擇器之間使用逗號“,”隔開,如上面所示selector1,selector2,…,selectorN。這個逗號告訴瀏覽器,規則中包含多個不同的選擇器,如果不有這個逗號,那麼所表達的意就完全不同了,省去逗號就成了我們前面所說的後代選擇器。

5)通用兄弟選擇器(E 〜 F)

通用兄弟元素選擇器是CSS3新增加一種選擇器,這種選擇器將選擇某元素後面的所有兄弟元素,他們也和相鄰兄弟元素類似,需要在同一個父元素之中,換句話說,E和F元素是屬於同一父元素之內,並且F元素在E元素之後,那麼E ~ F 選擇器將選擇中所有E元素後面的F元素。

6)相鄰兄弟元素選擇器(E + F)

相鄰兄弟選擇器可以選擇緊接在另一元素後的元素,而且他們具有一個相同的父元素,換句話說,EF兩元素具有一個相同的父元素,而且F元素在E元素後面,而且相鄰,這樣我們就可以使用相鄰兄弟元素選擇器來選擇F元素。

7)子元素選擇器(E>F)

子元素選擇器只能選擇某元素的子元素,其中E為父元素,而F為子元素,其中E>F所表示的是選擇了E元素下的所有子元素F。這和後代選擇器(E F)不一樣,在後代選擇器中F是E的後代元素,而子元素選擇器E > F,其中F僅僅是E的子元素而以。

8)後代選擇器(E F)

後代選擇器也被稱作包含選擇器,所起作用就是可以選擇某元素的後代元素,比如說:E F,前面E為祖先元素,F為後代元素,所表達的意思就是選擇了E元素的所有後代F元素,請注意他們之間需要一個空格隔開。這裡F不管是E元素的子元素或者是孫元素或者是更深層次的關係,都將被選中,換句話說,不論F在E中有多少層關係,都將被選中:

9)萬用字元選擇器(*)

萬用字元選擇器是用來選擇所有元素,,也可以選擇某個元素下的所有元素。

10)偽類選擇器

:link:未訪問的連結;
:visited:已訪問的連結,不建議使用;
:hover:滑鼠移動到容器,不僅限於連結,可用於頁面中的任何元素;
:active:被啟用時的狀態,不僅限於連結,可用於任何具有tabindex屬性的元素;
:focus:獲得焦點時狀態,不僅限於連結,可用於任何具有tabindex屬性的無線:
:enabled:已啟用的介面元素:
:disabled:已禁用的介面元素:
:target:該選擇器定位當前活動頁面內定位點的目標元素:

11)偽元素選擇器

偽元素可用於定位文件中包含的文字,為與偽類進行區分,偽元素使用雙冒號 :: 定義,但單冒號 : 也能被識別。這裡也只是列舉了幾個常用的。

::first-line:匹配文字首行;
::first-letter:匹配文字首字母;
::before 與 ::after :使用 contnet 屬性生成額外的內容並插入在標記中:
::selection:匹配突出顯示的文字:

12)屬性選擇器

E[attr]:該選擇器定位具有屬性attr的任何元素E:
E[attr=val]:該選擇器定位具有屬性attr且屬性值為val的任何元素E:
E[attr|=avl]:該選擇器定位具有屬性attr且屬性值為val或以val-開始的任何元素E:
E[attr~=val]:該選擇器定位具有屬性attr且屬性值為完整單詞 val 的任何元素E:
E[attr^=val]:該選擇器定位具有屬性attr且屬性值以val開頭的任何元素E:
E[attr$=val]:該選擇器與E[attr^=val]正好相反,定位具有屬性attr且屬性值以val結尾的任何元素E:
E[attr*=val]:該選擇器與E[attr~=val]相似,但更進一步,定位具有屬性attr且屬性值任意位置包含val的元素E,val可以是一個完整的單詞,也可以是一個單詞中的一部分:

2、權重計算規則
第一等:代表內聯樣式,如: style=””,權值為1000。
第二等:代表ID選擇器,如:#content,權值為0100。
第三等:代表類,偽類和屬性選擇器,如.content,權值為0010。
第四等:代表型別選擇器和偽元素選擇器,如div p,權值為0001。
萬用字元、子選擇器、相鄰選擇器等的。如*、>、+,權值為0000。
繼承的樣式沒有權值。

8、減少頁面載入時間的方法

(轉自:https://www.cnblogs.com/shenxiaolin/p/5390237.html)

1、重複的HTTP請求數量應儘量減少

(1)減少呼叫其他頁面、檔案的數量。

(2)在使用css格式時,常會採用background載入圖形檔案,而每個background的影像都會產生1次HTTP 請求,為了讓頁面生動活潑大量使用background來載入背景圖,可以採用css的1個有用的background-position屬 性來載入背景圖加以改善,將需要頻繁載入的多個圖片合成為1個單獨的圖片,載入時採用:background:url(…) no-repeat x-offset y-offset的形式載入,圖片載入的HTTP請求縮減為1個。

2、 壓縮Javascript、CSS程式碼

一般js、css檔案中存在大量的空格、換行、註釋,這些利於閱讀,如果能夠壓縮掉,將會很有利於網路傳輸。

3、在檔案頭部放置css樣式的定義

這項設定對於使用者端是慢速網路或網頁內容比較龐大的情況比較有利,可以在網頁逐步呈現的同時仍會保持格式資訊,不影響網頁美感。

4、在檔案末尾放Javascript指令碼

網頁檔案的載入是從上到下載入的,很多Javascript指令碼執行效率較低,或者在網頁前面都不需要執行的,如果將這些指令碼放置到頁面比較靠前的位置, 可能導致網站內容載入速度下降或載入不了,將這些指令碼放置在網頁檔案末尾,一定要放 置在前面的指令碼要改用所謂的“後載入”方式載入,在主體網頁載入完成後再載入,防止其影響到主體網頁的載入速度。

5、css、javascript改由外部呼叫

如果css、js內容比較龐大,儘量不要寫到同1個頁面中去,改由外部載入比較妥當,因為瀏覽器本身會對css、js檔案進行快取。

6、儘可能減少DCOM元素
  儘可能減少網頁中各種<>元素數量,例如

的冗餘很嚴重,而我們完全可以用
取代之。

7、避免使用CSS指令碼(CSS Expressions)

有時為了要css的引數動態改變,可能會採用css expression來實現,但這樣做得不償失,會使使用者端瀏覽器負擔明顯加重,所以不建議這樣做,如果需要改變,可以使用Javascript指令碼去實現。

9、手機號的正規表示式(以1開頭的11位數字)

表示式寫法是:/^1\d{10}$/

解析:^1 以1開頭,\d表示數字,\d{10}表示數字出現10次,加上前面以1開頭,正好是11個數字,X 表 示 以 X 結 尾 , 這 裡 用 表示以X結尾,這裡用 X表示後面沒有了,11個數字後已經是匹配字串的結尾。

10、列舉兩種清除浮動的方法(程式碼實現或者描述思路)

(1)、父級div定義height

解決了父級div無法自動獲取到高度的問題。
只適合固定高度的佈局,要給出精確的高度,如果高度和父級div不一樣時,會產生問題

(2)、結尾處加空div標籤 clear:both
新增一個空div,利用css提高的clear:both清除浮動,讓父級div能自動獲取到高度
如果頁面浮動佈局多,就要增加很多空div

(3)、父級div定義 偽類:after 和 zoom

(4)、父級div定義 overflow:hidden
必須定義width或zoom:1,同時不能定義height,使用overflow:hidden時,瀏覽器會自動檢查浮動區域的高度
不能和position配合使用,因為超出的尺寸的會被隱藏。

(5)、父級div定義 overflow:auto
必須定義width或zoom:1,同時不能定義height,使用overflow:auto時,瀏覽器會自動檢查浮動區域的高度
內部寬高超過父級div時,會出現滾動條。如果需要出現滾動條或者確保程式碼不會出現滾動條就使用。

相關文章