什么是閉包枚抵,優(yōu)缺點(diǎn)?
閉包實(shí)際上就是一個嵌套函數(shù)造烁,在一個函數(shù)內(nèi)定義的一個函數(shù)否过。作為閉包的必要條件,內(nèi)部函數(shù)應(yīng)該訪問外部函數(shù)中聲明的私有變量惭蟋、參數(shù)或者其他內(nèi)部函數(shù)苗桂。當(dāng)上述的兩個條件實(shí)現(xiàn)后,此時如果在外部函數(shù)外調(diào)用這個內(nèi)部函數(shù)告组,他就是成為了閉包函數(shù)煤伟。
【實(shí)例】 本例是一個經(jīng)典的閉包結(jié)構(gòu)
<script>
function fn(x) { //外部函數(shù)
var a = x; //外部函數(shù)的局部變量,并把參數(shù)值傳遞給它
var b = function () { //內(nèi)部函數(shù)
return a; //內(nèi)部函數(shù)訪問外部函數(shù)的局部變量
}
a++; //訪問后木缝,動態(tài)更新外部函數(shù)的變量
return b; //外部函數(shù)返回內(nèi)部函數(shù)
}
var c = fn(5);
console.log(c())
</script>
閉包的優(yōu)點(diǎn)
- 方便調(diào)用上下文的局部變量
- 加強(qiáng)了封裝性持偏,可以達(dá)到對變量的保護(hù)作用
- 邏輯連續(xù),當(dāng)閉包作為另一個函數(shù)調(diào)用參數(shù)時氨肌,避免脫離當(dāng)前邏輯而單獨(dú)編寫額外邏輯
閉包的缺點(diǎn)
- 由于閉包是駐留在內(nèi)存中,會增大內(nèi)存使用量酌畜,使用不當(dāng)很容易造成內(nèi)存泄露怎囚,降低程序的性能
三欄布局,都有幾種?
- 浮動布局
- 彈性盒子
- 定位布局
- 網(wǎng)格布局
- 表格布局
什么是原型鏈?原型鏈怎么實(shí)現(xiàn)繼承就珠?
定義原型
原型:聲明函數(shù)時js會自動生成prototype暴氏,prototype會生成一個空對象(也就是原型對象),原型對象的constructor默認(rèn)為你聲明的對象
原型鏈
原型鏈:從實(shí)例往上尋找構(gòu)造這個實(shí)例的相關(guān)聯(lián)的對象睹欲,然后在這個關(guān)聯(lián)的對象在往上查找創(chuàng)建它的上一級的原型對象,以此類推,一直到object.prototype終止伊群,object.prototype是原型鏈的頂端。
任何一個實(shí)例對象通過原型鏈找到它上面的原型對象策精,這個原型對象上的方法和屬性都被實(shí)例共享舰始,這就是原型鏈的原理
原型鏈實(shí)現(xiàn)繼承的幾種方法
借用構(gòu)造函數(shù)繼承
function SuperType () {
this.colors = ["red", "blue", "green"]
}
function SubType () {
// 繼承了SuperType
SuperType.call(this)
// 只能繼承構(gòu)造函數(shù)上的屬性
}
- 注意:
- 函數(shù)復(fù)用性不高
- 只能繼承實(shí)例上的屬性,原型上的方法不可見
組合繼承(偽經(jīng)典繼承)
function SuperType (name) {
this.name = name
this.colors = ["red", "blue", "green"]
}
SuperType.prototype.sayName = function () {
alert(this.name)
}
function SubType (name, age) {
// 繼承屬性
SuperType.call(this, name) // 第二次調(diào)用SuperType()
this.age = age
}
//繼承方法
SubType.prototype = new SuperType() // 第一次調(diào)用 SuperType()
Subtype.prototype.sayAge = function () {
alert(this.age)
}
- 注意:
- 組合繼承避免了原型鏈和借用構(gòu)造函數(shù)的缺陷咽袜,融合了他們的優(yōu)點(diǎn)丸卷,成為js中最常用的繼承方式。
原型式繼承
function object (o) {
function F(){}
F.prototype = o
return new F()
}
- 注意:
- 可以在不必預(yù)先定義構(gòu)造函數(shù)的情況下實(shí)現(xiàn)繼承询刹,其本質(zhì)是執(zhí)行對給定對象的淺復(fù)制谜嫉,而復(fù)制的副本還可以得到進(jìn)一步的改造
問題還是包含引用類型的屬性都會被共享萎坷。
寄生式繼承
function createAnother (original) {
var clone = object(original) // 通過調(diào)用函數(shù)創(chuàng)建一個新對象
clone.sayHi = function () { // 以某種方式來增強(qiáng)這個對象
alert("hi")
}
return clone // 返回這個對象
}
- 注意
- 基于某個對象或者某些信息創(chuàng)建一個對象,然后增強(qiáng)對象沐兰,最后返回對象哆档,為了解決組合繼承模式由于多次調(diào)用超類型構(gòu)造函數(shù)而導(dǎo)致的低效率問題,可以將這個模式與組合繼承一起使用
寄生組合式繼承
function inheritPrototype (subType, superType) {
var prototype = object(superType.prototype) // 創(chuàng)建對象
prototype.constructor = subType // 增強(qiáng)對象
subType.prototype = prototype // 指定對象
}
function SuperType (name) {
this.name = name
this.colors = {"red", "blue", "green"}
}
SuperType.prototype.sayName = function () {
alert(this.name)
}
function SubType (name, age) {
SuperType.call(this, name)
this.age = age
}
inheritPrototype(SubType, SuperType)
- 注意
- 高效率只調(diào)用了一次構(gòu)造函數(shù)僧鲁,集寄生式繼承和組合繼承的優(yōu)點(diǎn)于一身虐呻,是實(shí)現(xiàn)基于類型繼承的最有效方式
什么是深拷貝什么是淺拷貝?
在了解深拷貝和淺拷貝之前我們先來了解一下堆和棧
堆stack 和 棧heap
什么是堆內(nèi)存&&什么是棧內(nèi)存寞秃?
- stack:為自動分配的內(nèi)存空間斟叼,它由系統(tǒng)自動釋放;
- heap:為動態(tài)分配的內(nèi)存空間春寿,它大小不一定朗涩,也不會自動釋放
深拷貝和淺拷貝
使用場景:
深拷貝:在復(fù)雜對象里,對象的屬性也是對象的時候绑改;
淺拷貝:只復(fù)制一層對象谢床,當(dāng)對象的屬性是引用類型時,實(shí)質(zhì)上復(fù)制的是其引用厘线,當(dāng)引用指向的值發(fā)生變化的時候识腿,原對象屬性值也跟著變化;
淺拷貝
將原對象/原數(shù)組的引用,直接賦給新對象/新數(shù)組造壮,新對象/數(shù)組只是原對象的一個引用
let obj={a:1,arr:[2,3]};
let shallowObj=shallowCopy(obj);
function shallowCopy(srcObj){
var dest={};
for(let prop in srcObj){
console.log(prop);
if(srcObj.hasOwnProperty(prop)){
dest[prop]=srcObj[prop]
}
}// end of loop
return dest;
}
// 當(dāng)一個對象屬性的引用值改變時渡讼,會導(dǎo)致另一個也改變;
shallowObj.arr[1]=5;
深拷貝
深拷貝就是將原有對象重新拷貝一份耳璧,不論是修改哪一部分的值成箫,都不會對原有對象造成影響≈伎荩拷貝的永遠(yuǎn)是值蹬昌,而不是引用。
你是怎么做響應(yīng)式布局的攀隔?
什么是響應(yīng)式布局皂贩?
簡而言之,就是一個網(wǎng)站能夠兼容多個終端——而不是為每個終端做一個特定的版本昆汹。
優(yōu)點(diǎn):
- 面對不同分辨率設(shè)備靈活性強(qiáng)
- 能夠快捷解決多設(shè)備顯示適應(yīng)問題
缺點(diǎn):
- 兼容各種設(shè)備工作量大先紫,效率低下
- 代碼累贅,會出現(xiàn)隱藏?zé)o用的元素筹煮,加載時間加長
- 其實(shí)這是一種折中性質(zhì)的設(shè)計(jì)解決方案遮精,多方面因素影響而達(dá)不到最佳效果
- 一定程度上改變了網(wǎng)站原有的布局結(jié)構(gòu),會出現(xiàn)用戶混淆的情況
響應(yīng)式設(shè)計(jì)——設(shè)置 Meta 標(biāo)簽
大多數(shù)移動瀏覽器將HTML頁面放大為寬的視圖(viewport)以符合屏幕分辨率。你可以使用視圖的meta標(biāo)簽來進(jìn)行重置本冲。下面的視圖標(biāo)簽告訴瀏覽器准脂,使用設(shè)備的寬度作為視圖寬度并禁止初始的縮放。在<head>標(biāo)簽里加入這個meta標(biāo)簽
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
viewport
通俗的講檬洞,移動設(shè)備上的viewport就是設(shè)備的屏幕上能用來顯示我們的網(wǎng)頁的那一塊區(qū)域狸膏,在具體一點(diǎn),就是瀏覽器上(也可能是一個app中的webview)用來顯示網(wǎng)頁的那部分區(qū)域
content屬性值
- width:可視區(qū)域的寬度添怔,值可為數(shù)字或關(guān)鍵詞device-width(device-width:定義輸出設(shè)備的屏幕可見寬度湾戳。)
- height:同width
- intial-scale:頁面首次被顯示是可視區(qū)域的縮放級別,取值1.0則頁面按實(shí)際尺寸顯示广料,無任何縮放
- maximum-scale=1.0, minimum-scale=1.0;可視區(qū)域的縮放級別砾脑,
- maximum-scale用戶可將頁面放大的程序,1.0將禁止用戶放大到實(shí)際尺寸之上艾杏。
- user-scalable:是否可對頁面進(jìn)行縮放韧衣,no 禁止縮放
你是怎么用rem做自適應(yīng)的?
什么是rem购桑?
說到rem自然就會想到em畅铭,我們知道em是相對于父元素的字體大小的單位,那么rem則是相對于根元素也就是<html>元素的字體大小的單位勃蜘。
如何用rem解決移動端適配
script方法
<script>
window.addEventListener('orientationchange', setRem);
window.addEventListener('resize', setRem);
setRem();
function setRem() {
var html = document.querySelector('html');
var width = html.getBoundingClientRect().width;
html.style.fontSize = width / 16 + 'px';
};
</script>
style方法
<style>
// sass寫法
@function rem($px) {
@return $px / 46.875 + rem;
}
//less寫法
@rem: 46.875rem;
//stylus自行解決
硕噩?
</style>
用法:
如:元素寬300px,高500px缭贡;
傳入?yún)?shù)即可:width:rem(300); height:rem(500);
vue的雙向數(shù)據(jù)綁定
所謂雙向數(shù)據(jù)綁定, 無非就是數(shù)據(jù)層和視圖層中的數(shù)據(jù)同步, 在寫入數(shù)據(jù)時視圖層實(shí)時的跟著更新
實(shí)現(xiàn)mvvm的雙向綁定炉擅,是采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter匀归,getter,在數(shù)據(jù)變動時發(fā)布消息給訂閱者耗帕,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)穆端。就必須要實(shí)現(xiàn)以下幾點(diǎn):
- 實(shí)現(xiàn)一個數(shù)據(jù)監(jiān)聽器Observer,能夠?qū)?shù)據(jù)對象的所有屬性進(jìn)行監(jiān)聽仿便,如有變動可拿到最新值并通知訂閱者
- 實(shí)現(xiàn)一個指令解析器Compile体啰,對每個元素節(jié)點(diǎn)的指令進(jìn)行掃描和解析,根據(jù)指令模板替換數(shù)據(jù)嗽仪,以及綁定相應(yīng)的更新函數(shù)
- 實(shí)現(xiàn)一個Watcher荒勇,作為連接Observer和Compile的橋梁,能夠訂閱并收到每個屬性變動的通知闻坚,執(zhí)行指令綁定的相應(yīng)回調(diào)函數(shù)沽翔,從而更新視圖
-
mvvm入口函數(shù),整合以上三者
說說vuex
什么是vuex?
是專門一個為vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式
vuex的運(yùn)行機(jī)制
- 在vue組件里面仅偎,通過dispatch來觸發(fā)actions提交修改數(shù)據(jù)的操作跨蟹。
- 然后再通過actions的commit來觸發(fā)mutations來修改數(shù)據(jù)。
- mutations接收到commit的請求橘沥,就會自動通過Mutate來修改state(數(shù)據(jù)中心里面的數(shù)據(jù)狀態(tài))里面的數(shù)據(jù)窗轩。
- 最后由store觸發(fā)每一個調(diào)用它的組件的更新
如何使用promise封裝axios?
class Http {
//request 方法
request(params) {
return new Promise((resolve, reject) => {
Axios({
method: params.type || "get", //請求的方式
url: params.url, //請求的地址
data: params.data, //post 傳的參數(shù)
headers: params.headers //headers 請求頭
})
.then(res => { //請求成功觸發(fā)
if (res.data.code === 0) {
resolve(res);
} else {
resolve(res);
}
})
.catch(err => {
reject(err.statusText); ///請求失敗觸發(fā)
});
});
}
}
解釋
- 首先通過http類封裝axios
- 在http類中通過request方法return一個promise
- 通過promise傳遞兩個參數(shù)(resolve和reject)
- 設(shè)置axios請求的方式座咆、請求的地址痢艺、傳遞的參數(shù)
- 通過判斷code===0返回成功,反之請求失敗觸發(fā)
瀏覽器兼容問題如何解決介陶?
Normalize.css
不同瀏覽器的默認(rèn)樣式存在差異堤舒,可以使用 Normalize.css 抹平這些差異。當(dāng)然斤蔓,你也可以定制屬于自己業(yè)務(wù)的 reset.css
<link rel="stylesheet">
html5shiv.js
解決 ie9 以下瀏覽器對 html5 新增標(biāo)簽不識別的問題植酥。
<script type="text/javascript" src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
respond.js
解決 ie9 以下瀏覽器不支持 CSS3 Media Query 的問題。
<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
git常用指令
初始化git
git init
關(guān)聯(lián)庫
git remote add origin
克隆別人的項(xiàng)目
git clone
編寫完之后提交到庫里(更新)
- 先合并 git pull
- 再查狀態(tài) git status
- 給你新寫的內(nèi)容加入緩存區(qū) git add .
- 起別名 git commit -m 'linghu'
- 給他提交到庫里 git push
什么是回調(diào)地獄弦牡?如何解決友驮?
異步的JavaScript程序,或者說使用了回調(diào)函數(shù)的JavaScript的程序驾锰。簡單說卸留,就是函數(shù)作為參數(shù)層層嵌套(不利于維護(hù)和閱讀)
例子:
setTimeout(function (name) {
var catList = name + ','
setTimeout(function (name) {
catList += name + ','
setTimeout(function (name) {
catList += name
console.log(catList)
}, 200, 'Lion')
}, 200, 'Jaguar')
}, 200, 'Panther')
// Panther,Janguar,Lion
解決回調(diào)地獄
1. 拆解 function:將各步拆解為單個的 function
function buildCatList(list, returnVal, fn) {
setTimeout(function (name) {
var catList = list === '' ? name : list + ',' + name
fn(catList)
}, 200, returnVal)
}
buildCatList('', 'Panther', getJanguar)
function getJanguar(list) {
buildCatList(list, 'Janguar', getLynx)
}
function getLynx(list) {
buildCatList(list, 'Lion', print)
}
function print(list) {
console.log(list)
}
// Panther,Janguar,Lion
缺點(diǎn):不利于后期維護(hù)
2. 通過 Promise 鏈?zhǔn)秸{(diào)用的方式
function buildCatList(list, returnVal) {
return new Promise(function (resolve, reject) {
setTimeout(function (name) {
var catList = list === '' ? name : list + ',' + name
resolve(catList)
}, 200, returnVal)
})
}
buildCatList('', 'Panther').then(function (res) {
return buildCatList(res, 'Janguar')
}).then(function (res) {
return buildCatList(res, 'Lion')
}).then(function (res) {
console.log(res)
})
// Panther,Janguar,Lion
Promise 函數(shù)雖然改變了之前回調(diào)地獄的寫法,但是在根本上還是函數(shù)套函數(shù)椭豫,看起來不是那么的美觀
new操作符具體干了什么呢?
考察對new關(guān)鍵的深刻認(rèn)識耻瑟,是否對前端知識有專研,如果沒有專研的人赏酥,肯定說創(chuàng)建了一個對象喳整,恭喜你面試官知道你是小菜鳥來的,這次面試基本上沒有太大的希望了裸扶。一定要對new過程的4個步驟非常清楚框都,這樣才能深深地抓住面試官的心!
- 創(chuàng)建一個空對象
varobj=new Object();
- 設(shè)置原型鏈
obj.__proto__= Func.prototype;
3.讓Func中的this指向obj呵晨,并執(zhí)行Func的函數(shù)體魏保。
4.判斷Func的返回值類型:
如果是值類型,返回obj摸屠。如果是引用類型谓罗,就返回這個引用類型的對象。
sass和less都屬于CSS預(yù)處理器季二。
Sass和Less的區(qū)別
sass:
- Sass的安裝需要安裝Ruby環(huán)境檩咱。
- sass有變量和作用域。
- sass有函數(shù)的概念。
less:
- Less基于Javascript(可以寫js代碼)税手。
Less和Sass處理機(jī)制不一樣
less是通過客戶端處理的蜂筹,sass是通過服務(wù)端處理,相比較之下前者解析會比后者慢一點(diǎn)芦倒。
HTTP和HTTPS協(xié)議的區(qū)別
- http是超文本傳輸協(xié)議艺挪,信息是明文傳輸
- https則是具有安全性的ssl加密傳輸協(xié)議
HTTPS和HTTP的區(qū)別主要如下:
- https協(xié)議需要ca申請證書,并且大多數(shù)證書都是收費(fèi)的兵扬。
- http以明文的形式傳輸信息麻裳,https則是具有安全性的ssl加密傳輸協(xié)議。
- http和https使用的是完全不同的連接方式器钟,用的端口也不一樣津坑,前者是80(有時是8080),后者是443傲霸。
- http的連接簡單疆瑰,無狀態(tài);HTTPS協(xié)議是在HTTP協(xié)議的基礎(chǔ)上昙啄,加上由SSL層穆役,構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議梳凛,比http協(xié)議安全耿币。
js中數(shù)組的filter過濾器的理解
定義和用法
filter() 方法創(chuàng)建一個新的數(shù)組,新數(shù)組中的元素是通過檢查指定數(shù)組中符合條件的所有元素韧拒。
注意:filter() 不會對空數(shù)組進(jìn)行檢測淹接。
注意: filter() 不會改變原始數(shù)組。
語法
array.filter(function(currentValue,index,arr), thisValue)
參數(shù)說明
參數(shù) | 描述 |
---|---|
currentValue | 必須叛溢。當(dāng)前元素的值 |
index | 可選塑悼。當(dāng)前元素的索引值 |
arr | 可選。當(dāng)前元素屬于的數(shù)組對象 |
thisValue | 可選楷掉。對象作為該執(zhí)行回調(diào)時使用厢蒜,傳遞給函數(shù),用作 "this" 的值靖诗。如果省略了 thisValue 郭怪,"this" 的值為 "undefined" |
實(shí)例
返回?cái)?shù)組中所有年齡大于18的元素集合
<script>
var info = [
{
id: '1',
name: 'linghu',
sex: "男",
age: 24
},
{
id: '2',
name: 'yuchenglong',
sex: "女",
age: '15',
}
];
var arr = info.filter((item, index, arr) => item.age > 19)
console.log(arr)
</script>
結(jié)果是:
[{…}]
0: {id: "1", name: "linghu", sex: "男", age: 24}
length: 1
__proto__: Array(0)
想面試中基本還會問到animation支示、canvas刊橘、tranfroms、transform颂鸿,請求職的小伙伴們務(wù)必去了解一下這些促绵,祝各位求職成功!!败晴!