考查點(diǎn):
- 基層工程師——基礎(chǔ)知識(shí)
- 高級(jí)工程師——項(xiàng)目經(jīng)驗(yàn)
- 架構(gòu)師——解決方案
- 技術(shù)沒有好壞,關(guān)鍵看使用場(chǎng)景
面試戰(zhàn)術(shù)
- 拿到一個(gè)面試題篙贸,你的第一時(shí)間看到的是什么?(考點(diǎn))
- 如何看待網(wǎng)上永遠(yuǎn)看不完的題海(不變應(yīng)萬變)
- 如何對(duì)待遇到的面試題铝侵?(題目到知識(shí)再到題目)
JS typeof 運(yùn)算符
- undefined
- string
- number
- boolean
- object
- function
==運(yùn)算符和===運(yùn)算符
==會(huì)發(fā)生強(qiáng)制類型轉(zhuǎn)換;===則不會(huì)篓像。比如obj.a==null其實(shí)就相當(dāng)于obj.a===null || obj.a===undefined,==屬于一種簡(jiǎn)寫形式,是JQuery推薦寫法皿伺,其他情況一般使用===
如何理解JSON
在js中JSON不僅僅是一種數(shù)據(jù)格式员辩,同時(shí)也是也是一個(gè)js對(duì)象。
構(gòu)造函數(shù)
function Person( name){
this.name =name;
}
var p1=new Person('John');
注意:構(gòu)造函數(shù)默認(rèn)首字母大寫
- var a={} 等價(jià)于 var a = new Object()
- var a=[] 等價(jià)于 var a = new Array();
- function Foo(){……} 等價(jià)于 var Foo = new Function(……);
- 使用instanceof判斷一個(gè)函數(shù)是否是另一變量的構(gòu)造函數(shù)
原型規(guī)則
1.所有引用類型(數(shù)組鸵鸥、對(duì)象奠滑、函數(shù)),都具有對(duì)象特性妒穴,即可自由擴(kuò)展屬性(null除外)
2.所有引用類型(數(shù)組宋税、對(duì)象、函數(shù))讼油,都有一個(gè)proto(隱式原型)屬性杰赛,屬性值是普通對(duì)象
3.所有的函數(shù),都有一個(gè)prototype(顯式類型)屬性矮台,屬性值也是一個(gè)普通對(duì)象乏屯。
4.所有的引用類型(數(shù)組、對(duì)象瘦赫、函數(shù))辰晕,proto屬性值指向它的構(gòu)造函數(shù)的“prototype”屬性值
var arr=[1,2,3];
arr._proto_===Array.prototype
5.當(dāng)試圖得到一個(gè)對(duì)象的屬性時(shí),如何這個(gè)對(duì)象本身沒有這個(gè)屬性确虱,那么就會(huì)去它的proto(即它的prototype)中尋找含友。
instanceof判斷邏輯
f instanceof Foo,f的proto一層層向上找校辩,能否找到Foo.prototype
new一個(gè)js對(duì)象的過程
- 首先有一個(gè)構(gòu)造函數(shù)創(chuàng)建一個(gè)新對(duì)象
- this指向這個(gè)對(duì)象
- 執(zhí)行代碼窘问,即對(duì)this賦值
- 返回this(默認(rèn)都沒有寫,其實(shí)系統(tǒng)已經(jīng)實(shí)現(xiàn)了)
原型和原型鏈實(shí)例
function Elem(id){
this.elem = document.getElementsByClassName(id);
}
Elem.prototype.html=function(val){
var elem = this.elem;
if(val){
elem.innerHTML(val);
return this;
}else{
return elem.innerHTML;
}
}
Elem.prototype.on=function(type,fn){
var elem = this.elem;
elem.addEventListener(type,fn);
}
var div = new Elem('search-body');
div.html("<p>hello</p>").on('click',function(){
alert('click');
});
this
- this要在執(zhí)行時(shí)才能確認(rèn)宜咒,定義時(shí)無法確認(rèn)南缓。
使用場(chǎng)景: - 作為構(gòu)造函數(shù)執(zhí)行
function Foo(name){
this.name=name;
}
var foo =new Foo("tom");
- 作為對(duì)象屬性執(zhí)行
var obj = {
name="tom"
print:function(){
alert(this.name);
}
}
obj.print();
- 作為一個(gè)普通函數(shù)執(zhí)行
function fn(){
alert(this);//window
}
fn();
- call、apply和bind
function fn(){
alert(this);//window
}
fn();
function fn(name){
alert(this); //[Object object]
}
fn.call({age:22},"tom");
>var fn =function (name){
alert(this);
}.bind({age:22});
fn("tom");
作用域
-
js沒有塊級(jí)作用域荧呐,有函數(shù)作用域和全局作用域
image.png -
作用域鏈
image.png - 一個(gè)函數(shù)的父級(jí)作用域是定義時(shí)的作用域汉形,而不是運(yùn)行時(shí)。
閉包
- 函數(shù)作為返回值
- 函數(shù)作為參數(shù)來傳遞
實(shí)際開發(fā)中的閉包的應(yīng)用 - 用于封裝變量倍阐,收斂權(quán)限
前端使用異步場(chǎng)景
- 定時(shí)任務(wù):setTimeout概疆,setInterval
- 網(wǎng)絡(luò)請(qǐng)求:ajax請(qǐng)求,
- 動(dòng)態(tài)<img/>加載
- 事件綁定
- 共同點(diǎn):都需要等待
同步和異步的區(qū)別
- 同步會(huì)阻塞代碼峰搪,而異步不會(huì)
- alert是同步岔冀,setTimeout是異步
其他API
獲取2017-07-01格式的日期
function formatDate(dt){
if(!dt){
dt=new Date();
}
var year =dt.getFullYear();
var month=dt.getMonth()+1;
var date=dt.getDate();
if(month<10)
month="0"+month;
if(date<10)
date="0"+date;
return (year+"-"+month+"-"+date);
}
var dt=new Date();
var formatDate= formatDate(dt);
console.log(formatDate);
寫一個(gè)能遍歷對(duì)象和數(shù)組的forEach函數(shù)
function forEach(obj,fn){
if(obj instanceof Array){
obj.forEach(function(item,index){
fn(index,item);
});
}else{
for(key in obj){
fn(key,obj[key]);
}
}
}
var arr=[1,2,3];
forEach(arr,function(index,item){
console.log(index,item);
});
var obj ={x:1,y:2};
forEach(obj,function(key,value){
console.log(key,value);
});
DOM節(jié)點(diǎn)的Attribute和property有何區(qū)別
- property只是一個(gè)JS對(duì)象的屬性的修改和獲取
- Attribute是對(duì)HTML標(biāo)簽屬性的修改和獲取
如何檢測(cè)瀏覽器類型
function checkBrower(){
var agent = navigator.userAgent;
if(agent.indexOf("chrome")>-1)
return "Chrome";
if(agent.indexOf("Firefox")>-1)
return "Firefox";
if (agent.indexOf("Safari")>-1)
return "Safari";
if(agent.indexOf("compatible")>-1 && agent.indexOf("MSIE")>-1)
return "IE";
}
通用事件綁定
function bindEvent(elem,type,fn){
elem.addEventListener(type,fn);
}
var a = document.getElementById("");
bindEvent(a,'click',function(e){
e.preventDefault();
alert("click");
});
事件代理
div1.addEventListener('click',function(e){
var target=e.target;
if(target.nodeName=='a')
alert(target.innerHTML);
})
代理的好處
* 代碼簡(jiǎn)潔
* 減少瀏覽器內(nèi)存的使用
通用事件綁定事件函數(shù)
function bindEvent(elem,type,selector,fn){
if(fn == null){
fn= selector;
selector =null;
}
elem.addEventListener(type,function(e){
var target;
if(selector){ //使用代理
target=e.target;
if(target.matches(selector)){
fn.call(target,e);
}
} else{ //不使用代理
fn(e);
}
})
}
手動(dòng)編寫一個(gè)ajax
var xmlhttp=null;//聲明一個(gè)變量,用來實(shí)例化XMLHttpRequest對(duì)象
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();// 新版本的瀏覽器可以直接創(chuàng)建XMLHttpRequest對(duì)象
}
else if (window.ActiveXObject)
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");// IE5或IE6沒有XMLHttpRequest對(duì)象概耻,而是用的ActiveXObject對(duì)象
}
if (xmlhttp!=null)
{
xmlhttp.onreadystatechange=state_Change;//指定響應(yīng)函數(shù)為state_Change
xmlhttp.open("GET","/example/xdom/note.xml",true);//指定請(qǐng)求使套,這里要訪問在/example/xdom路徑下的note.xml文件罐呼,true代表的使用的是異步請(qǐng)求
xmlhttp.send(null);//發(fā)送請(qǐng)求
}
else
{
alert("Your browser does not support XMLHTTP.");
}
//創(chuàng)建具體的響應(yīng)函數(shù)state_Change
function state_Change()
{
if (xmlhttp.readyState==4)
{
if (xmlhttp.status==200)
{
// 這里應(yīng)該是函數(shù)具體的邏輯
}
else
{
alert("Problem retrieving XML data");
}
}
}
跨域
- 瀏覽器有同源策略,不允許ajax訪問其他域接口侦高。
- 跨域條件:協(xié)議嫉柴、域名、端口奉呛,有一個(gè)不同就算跨域计螺。
- 三個(gè)標(biāo)簽無跨域障礙
1.<img>用于打點(diǎn)統(tǒng)計(jì),統(tǒng)計(jì)網(wǎng)站可能來自其他域瞧壮。
2.<link><script>可以使用CDN登馒、CDN也是其他域。
3.<script>可以用于JSONP
- 所有的跨域請(qǐng)求都必須經(jīng)過信息提供方允許
JSOP實(shí)現(xiàn)原理
- 加載 http://www.myname.com/index.html
- 不一定服務(wù)器端真正有一個(gè)index.html
- 服務(wù)器可以根據(jù)請(qǐng)求咆槽,動(dòng)態(tài)生成一個(gè)文件陈轿,返回
- 同理于<script src="http://www.mycode.api/js>
jsop原理
服務(wù)器端設(shè)置http header解決跨域
描述一個(gè)cookie,sessionStorage和localStorage的區(qū)別
cookie
- 本身用戶客戶端和服務(wù)器端通信
- 但是它有本地存儲(chǔ)的功能,于是被“借用了”
- 使用document.cookie=……
缺點(diǎn) - 存儲(chǔ)量太小秦忿,只有4KB
- 所有http請(qǐng)求都帶著麦射,會(huì)影響獲取資源的效率
- API簡(jiǎn)單,需要封裝才能用 document.cookie=…
locationStorage和sessionStorage - HTML5專為存儲(chǔ)而設(shè)計(jì)小渊,最大容量為5M
- API簡(jiǎn)單易用
- localStorage.setItem(key,value);
- localStorage.getItem(key);
- localStorage為持久存儲(chǔ),session為回話存儲(chǔ)
區(qū)別:
- 容量
- 是否會(huì)攜帶到ajax中
- API易用性
多人協(xié)作常用git命令
- git.add .
- git checkout xxx 還原之前
- git commit -m "xxx"
- git push origin master
- git pull origin master
- git branch 查看當(dāng)前分支
- git branch xxx(創(chuàng)建分支)/git checkout -b xxx(創(chuàng)建并切換分支) / git checkout xxx 切換分支
- git merge xxx 把xxx分支合并到當(dāng)前分支(合并前先pull最新的代碼茫叭,合并后還要push上去)
- git diff 查看變化
模塊化
AMD
- require.js http://www.ruanyifeng.com/blog/2012/11/require_js.html
- 全局define函數(shù)
- 全局require函數(shù)
-
依賴的JS會(huì)自動(dòng)酬屉、異步加載
image.png
CommonJS http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_definition.html
- nodejs模塊化規(guī)范,現(xiàn)被大量用于前端
- 前端開發(fā)依賴的插件和庫揍愁,都可以從npm中獲取
- 構(gòu)建工具的高度自動(dòng)化呐萨,使得使用npm的成本非常低
- CommonJS不會(huì)異步加載JS,而是同步一次性加載
AMD和CommonJS的使用場(chǎng)景
- 需要異步加載JS莽囤,使用AMD
- 使用了npm之后建議使用CommonJS
構(gòu)建工具webpack
npm init (生成package.json文件)
**npm install webpack --save-dev **(簡(jiǎn)寫:npm i webpack --save-dev)
"devDependencies": { //用于開發(fā)環(huán)境的依賴
"webpack": "^3.3.0"
},
npm install jquery--save
"dependencies": { //用于正式上線時(shí)的依賴
"jquery": "^3.2.1"
}卸載npm uninstall jquery--save
webpack.config.js配置
var path = require('path')
var webpack = require('webpack')
module.exports = {
context: path.resolve(__dirname,'./src'),
entry:{
app:'./app.js'
},
output: {
path: path.resolve(__dirname,'./dist'),
filename: 'bundle.js'
}
}
-
配置package.json文件中的
image.png -
執(zhí)行 npm start谬擦,生成bundle.js文件
image.png
上線流程要點(diǎn)
- 將測(cè)試完成代碼提交到git版本庫的master分支
- 經(jīng)當(dāng)前服務(wù)器的代碼全部打包并記錄版本號(hào),備份
- 將master分支的代碼提交覆蓋到線上服務(wù)器朽缎,生成新版本號(hào)
回滾流程要點(diǎn)
- 將當(dāng)前服務(wù)器的代碼打包并記錄版本號(hào)惨远,備份
- 將備份的上一個(gè)版本號(hào)解壓,覆蓋到線上服務(wù)器话肖,并生成新的版本號(hào)北秽。
頁面加載資源的過程
- 瀏覽器根據(jù)DNS服務(wù)器得到域名的IP地址
- 向這個(gè)IP的機(jī)器發(fā)送http請(qǐng)求
- 服務(wù)器收到、處理并返回http請(qǐng)求
- 瀏覽器得到返回內(nèi)容
瀏覽器渲染頁面的過程
- 根據(jù)HTML生成DOM Tree
- 根據(jù)CSS生成CSSOM
- 將DOM和CSSOM整合形成RenderTree
- 根據(jù)RenderTree開始渲染和展示
- 遇到<script>時(shí)最筒,會(huì)執(zhí)行并阻塞渲染贺氓,所以放在</body>上面。
window.onload和DOMContentLoaded區(qū)別
- load事件是在頁面的全部資源加載完才會(huì)執(zhí)行床蜘,包括圖片辙培、視頻等
- DOMContentLoaded事件是在DOM渲染完即可執(zhí)行蔑水,此時(shí)圖片、視頻還可能沒有加載完扬蕊。
加載資源優(yōu)化
- 靜態(tài)資源的壓縮合并
- 靜態(tài)資源緩存
- 使用CDN讓資源加載更快
- 使用SSR后端渲染搀别,數(shù)據(jù)直接輸出到HTML中
渲染優(yōu)化
- CSS放前面,JS放后面
-
懶加載(圖片懶加載厨相、下拉加載更多)
懶加載 -
減少DOM查詢领曼,對(duì)DOM查詢做緩存
DOM緩存 -
減少DOM操作,多個(gè)操作盡量合并在一起執(zhí)行(documentFragment)
合并操作 -
事件節(jié)流(減少一些不必要的頻繁行為蛮穿,例如增加延遲)
事件節(jié)流 -
盡早執(zhí)行操作(如DOMContentLoaded)
安全性(非重點(diǎn))
- XSS跨站請(qǐng)求攻擊
在別人的網(wǎng)站發(fā)布的信息中插入一段 <script>攻擊代碼庶骄,用于獲取查看者cookie,發(fā)送到自己的服務(wù)器。
解決方案:- 前端替換關(guān)鍵字践磅,例如替換<為<单刁;>為>
- 后端替換
- XSRF跨站請(qǐng)求偽造
一些網(wǎng)站或郵箱中隱藏的偽造請(qǐng)求,比如<img src=xxx.com/pay?id=100
解決方案:- 增加驗(yàn)證流程府适,如輸入指紋羔飞、密碼、短信驗(yàn)證碼
簡(jiǎn)歷
- 簡(jiǎn)潔明了檐春,重點(diǎn)突出項(xiàng)目經(jīng)歷和解決方案
- 把個(gè)人博客放在簡(jiǎn)歷中逻淌,并且定期維護(hù)更新博客
- 把個(gè)人的開源項(xiàng)目放在簡(jiǎn)歷中,并維護(hù)開源項(xiàng)目
- 簡(jiǎn)歷千萬不要造假疟暖,要保持能力和經(jīng)歷上的真實(shí)性
面試過程中
- 如何看待加班卡儒?加班就像借錢,救急不救窮
- 千萬不可挑戰(zhàn)面試官俐巴,不要反考面試官
- 學(xué)會(huì)給面試官驚喜骨望,但不要太多
- 遇到不會(huì)回答的問題,說出你知道就可以了
- 談?wù)勀愕娜秉c(diǎn)——說一下你最近正在學(xué)什么就可以了
PS常用
- 圖像拖到透明圖層中——裁切——透明像素
- 文件——編輯——首選項(xiàng):性能和常規(guī)
- 查看圖像大小——Ctrl+alt+I
- 合并圖層——Ctrl+E
- 切圖優(yōu)化
- 顏色代替圖片
- 雪碧圖的制作
- 字體圖標(biāo)的使用
- 切圖輔助
- TinyPng
- 前端自動(dòng)化