內容方面:javascript
1. 減小 HTTP 請求 (Make Fewer HTTP Requests)
php
2. 減小 DOM 元素數量 (Reduce the Number of DOM Elements) css
3. 使得 Ajax 可緩存 (Make Ajax Cacheable) html
針對CSS: 前端
1. 把 CSS 放到代碼頁上端 (Put Stylesheets at the Top) java
2. 從頁面中剝離 JavaScript 與 CSS (Make JavaScript and CSS External) webpack
3. 精簡 JavaScript 與 CSS (Minify JavaScript and CSS) 程序員
4. 避免 CSS 表達式 (Avoid CSS Expressions) web
針對JavaScript : ajax
1. 腳本放到 HTML 代碼頁底部 (Put Scripts at the Bottom)
2. 從頁面中剝離 JavaScript 與 CSS (Make JavaScript and CSS External)
3. 精簡 JavaScript 與 CSS (Minify JavaScript and CSS)
4. 移除重複腳本 (Remove Duplicate Scripts)
面向圖片(Image):
1. 優化圖片
2. 不要在 HTML 中使用縮放圖片
3. 使用恰當的圖片格式
4. 使用 CSS Sprites 技巧對圖片優化
function foo1(){ return {
bar: "hello"
};
}
function foo2(){ return
{
bar: "hello"
};
}複製代碼
出人意料的是,這兩個函數返回的內容並不相同。更確切地說是:
console.log("foo1 returns:");console.log(foo1());console.log("foo2 returns:");console.log(foo2());複製代碼
將產生:
foo1 returns:Object {bar: "hello"}foo2 returns:undefined複製代碼
這不只是使人驚訝,並且特別讓人困惑的是, foo2()
返回undefined卻沒有任何錯誤拋出。
緣由與這樣一個事實有關,即分號在JavaScript中是一個可選項(儘管省略它們一般是很是糟糕的形式)。其結果就是,當碰到 foo2()
中包含 return
語句的代碼行(代碼行上沒有其餘任何代碼),分號會當即自動插入到返回語句以後。
也不會拋出錯誤,由於代碼的其他部分是徹底有效的,即便它沒有獲得調用或作任何事情(至關於它就是是一個未使用的代碼塊,定義了等同於字符串 "hello"
的屬性 bar
)。
這種行爲也支持放置左括號於JavaScript代碼行的末尾,而不是新代碼行開頭的約定。正如這裏所示,這不只僅只是JavaScript中的一個風格偏好。
閉包就是可以讀取其餘函數內部變量的函數
閉包是指有權訪問另外一個函數做用域中變量的函數,建立閉包的最多見的方式就是在一個函數內建立另外一個函數,經過另外一個函數訪問這個函數的局部變量,利用閉包能夠突破做用鏈域
閉包的特性:
說說你對閉包的理解
使用閉包主要是爲了設計私有的方法和變量。閉包的優勢是能夠避免全局變量的污染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易形成內存泄露。在js中,函數即閉包,只有函數纔會產生做用域的概念
閉包 的最大用處有兩個,一個是能夠讀取函數內部的變量,另外一個就是讓這些變量始終保持在內存中
閉包的另外一個用處,是封裝對象的私有屬性和私有方法
好處:可以實現封裝和緩存等;
壞處:就是消耗內存、不正當使用會形成內存溢出的問題
使用閉包的注意點
window
對象即被終止,做用域鏈向下訪問變量是不被容許的每一個對象都會在其內部初始化一個屬性,就是prototype
(原型),當咱們訪問一個對象的屬性時
若是這個對象內部不存在這個屬性,那麼他就會去prototype
裏找這個屬性,這個prototype
又會有本身的prototype
,因而就這樣一直找下去,也就是咱們平時所說的原型鏈的概念
關係:instance.constructor.prototype = instance.__proto__
特色:
JavaScript
對象是經過引用來傳遞的,咱們建立的每一個新對象實體中並無一份屬於本身的原型副本。當咱們修改原型時,與之相關的對象也會繼承這一改變當咱們須要一個屬性的時,Javascript
引擎會先看當前對象中是否有這個屬性, 若是沒有的
就會查找他的Prototype
對象是否有這個屬性,如此遞推下去,一直檢索到 Object
內建對象
Event Delegation
),又稱之爲事件委託。是 JavaScript
中經常使用綁定事件的經常使用技巧。顧名思義,「事件代理」便是把本來須要綁定的事件委託給父元素,讓父元素擔當事件監聽的職務。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好處是能夠提升性能table
上代理全部td
的click
事件就很是棒構造繼承
原型繼承
實例繼承
拷貝繼承
原型prototype
機制或apply
和call
方法去實現較簡單,建議使用構造函數與原型混合方式
function Parent(){
this.name = 'wang';
}
function Child(){
this.age = 28;
}
Child.prototype = new Parent();//繼承了Parent,經過原型
var demo = new Child();
alert(demo.age);
alert(demo.name);//獲得被繼承的屬性
}
複製代碼
this
老是指向函數的直接調用者(而非間接調用者)new
關鍵字,this
指向new
出來的那個對象this
指向觸發這個事件的對象,特殊的是,IE
中的attachEvent
中的this
老是指向全局對象Window
W3C
中定義事件的發生經歷三個階段:捕獲階段(capturing
)、目標階段(targetin
)、冒泡階段(bubbling
)
DOM
事件流:同時支持兩種事件模型:捕獲型事件和冒泡型事件W3c
中,使用stopPropagation()
方法;在IE下設置cancelBubble = true
click - <a>
後的跳轉。在W3c
中,使用preventDefault()
方法,在IE
下設置window.event.returnValue = false
this
變量引用該對象,同時還繼承了該函數的原型this
引用的對象中this
所引用,而且最後隱式的返回 this
Ajax
的原理簡單來講是在用戶和服務器之間加了—箇中間層(AJAX
引擎),經過XmlHttpRequest
對象來向服務器發異步請求,從服務器得到數據,而後用javascrip
t來操做DOM
而更新頁面。使用戶操做與服務器響應異步化。這其中最關鍵的一步就是從服務器得到請求數據Ajax
的過程只涉及JavaScript
、XMLHttpRequest
和DOM
。XMLHttpRequest
是aja
x的核心機制// 1. 建立鏈接
var xhr = null;
xhr = new XMLHttpRequest()
// 2. 鏈接服務器
xhr.open('get', url, true)
// 3. 發送請求
xhr.send(null);
// 4. 接受請求
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
success(xhr.responseText);
} else { // fail
fail && fail(xhr.status);
}
}
}
複製代碼
ajax 有那些優缺點?
Ajax
在客戶端運行,承擔了一部分原本由服務器承擔的工做,減小了大用戶量下的服務器負載。Ajax
能夠實現動態不刷新(局部刷新)AJAX
暴露了與服務器交互的細節。jsonp
、 iframe
、window.name
、window.postMessage
、服務器上設置代理頁面var module1 = (function(){
var _count = 0;
var m1 = function(){
//...
};
var m2 = function(){
//...
};
return {
m1 : m1,
m2 : m2
};
})();
複製代碼
IE
async
:script
,插入到DOM
中,加載完畢後callBack
setTimeout
的第一個參數使用字符串而非函數的話,會引起內存泄漏數據體積方面
JSON
相對於XML
來說,數據的體積小,傳遞的速度更快些。數據交互方面
JSON
與JavaScript
的交互更加方便,更容易解析處理,更好的數據交互數據描述方面
JSON
對數據的描述性比XML
較差傳輸速度方面
JSON
的速度要遠遠快於XML
WebPack
是一個模塊打包工具,你可使用WebPack
管理你的模塊依賴,並編繹輸出模塊們所需的靜態文件。它可以很好地管理、打包Web
開發中所用到的HTML
、Javascript
、CSS
以及各類靜態文件(圖片、字體等),讓開發過程更加高效。對於不一樣類型的資源,webpack
有對應的模塊加載器。webpack
模塊打包器會分析模塊間的依賴關係,最後 生成了優化且合併後的靜態資源CommonJS
是服務器端模塊的規範,Node.js
採用了這個規範。CommonJS
規範加載模塊是同步的,也就是說,只有加載完成,才能執行後面的操做。AMD
規範則是非同步加載模塊,容許指定回調函數AMD
推薦的風格經過返回一個對象作爲模塊對象,CommonJS
的風格經過對module.exports
或exports
的屬性賦值來達到暴露模塊對象的目的sql
注入原理
SQL
命令插入到Web
表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令總的來講有如下幾點
"-"
進行轉換等SQL
或者直接使用存儲過程進行數據查詢存取hash
掉密碼和敏感的信息XSS原理及防範
Xss(cross-site scripting)
攻擊指的是攻擊者往Web
頁面裏插入惡意html
標籤或者javascript
代碼。好比:攻擊者在論壇中放一個看似安全的連接,騙取用戶點擊後,竊取cookie
中的用戶私密信息;或者攻擊者在論壇中加一個惡意表單,當用戶提交表單的時候,卻把信息傳送到攻擊者的服務器中,而不是用戶本來覺得的信任站點XSS防範方法
」<」,」>」,」;」,」’」
等字符作過濾;其次任何內容寫到頁面以前都必須加以encode,避免不當心把html tag
弄出來。這一個層面作好,至少能夠堵住超過一半的XSS 攻擊XSS與CSRF有什麼區別嗎?
XSS
是獲取信息,不須要提早知道其餘用戶頁面的代碼和數據包。CSRF
是代替用戶完成指定的動做,須要知道其餘用戶頁面的代碼和數據包。要完成一次CSRF
攻擊,受害者必須依次完成兩個步驟
登陸受信任網站A
,並在本地生成Cookie
在不登出A
的狀況下,訪問危險網站B
CSRF的防護
CSRF
方式方法不少樣,但總的思想都是一致的,就是在客戶端頁面增長僞隨機數工廠模式:
new
關鍵字構造函數模式
this
對象;Iframe
把真正的銀行登陸頁面嵌到他的頁面上,當你使用真實的用戶名,密碼登陸時,他的頁面就能夠經過Javascript
讀取到你的表單中input
中的內容,這樣用戶名,密碼就輕鬆到手了。offsetWidth/offsetHeight
返回值包含content + padding + border,效果與e.getBoundingClientRect()相同clientWidth/clientHeight
返回值只包含content + padding,若是有滾動條,也不包含滾動條 scrollWidth/scrollHeight
返回值包含content + padding + 溢出內容的尺寸 var obj = {};
var obj = new Object();
var obj = Object.create(Object.prototype);
png24
位的圖片在iE6瀏覽器上出現背景,解決方案是作成PNG8
margin
和padding
不一樣。解決方案是加一個全局的*{margin:0;padding:0;}
來統一,,可是全局效率很低,通常是以下這樣解決:body,ul,li,ol,dl,dt,dd,form,input,h1,h2,h3,h4,h5,h6,p{
margin:0;
padding:0;
}
複製代碼
IE
下,event
對象有x
,y
屬性,可是沒有pageX
,pageY
屬性Firefox
下,event
對象有pageX
,pageY
屬性,可是沒有x,y
屬性.Undefined
、Null
、Boolean
、Number
、String
Object
是 JavaScript
中全部對象的父對象Object
、Array
、Boolean
、Number
和 String
Function
、Arguments
、Math
、Date
、RegExp
、Error
===/!==
來比較true/false
或者數值new Array
這種形式Switch
語句必須帶有default
分支If
語句必須使用大括號for-in
循環中的變量 應該使用var
關鍵字明確限定做用域,從而避免做用域污Undefined
,Null
,Boolean
,Numbe
r、String
)stack
)中的簡單數據段,佔據空間小、大小固定,屬於被頻繁使用數據,因此放入棧中存儲;heap
)中的對象,佔據空間大、大小不固定,若是存儲在棧中,將會影響程序運行的性能;引用數據類型在棧中存儲了指針,該指針指向堆中該實體的起始地址。當解釋器尋找引用值時,會首先檢索其
javascript
建立對象簡單的說,無非就是使用內置對象或各類自定義對象,固然還能夠用JSON
;但寫法有不少種,也能混合使用
person={firstname:"Mark",lastname:"Yun",age:25,eyecolor:"black"};
複製代碼
function
來模擬無參的構造函數function Person(){}
var person=new Person();//定義一個function,若是使用new"實例化",該function能夠看做是一個Class
person.name="Mark";
person.age="25";
person.work=function(){
alert(person.name+" hello...");
}
person.work();
複製代碼
function
來模擬參構造函數來實現(用this
關鍵字定義構造的上下文屬性)function Pet(name,age,hobby){
this.name=name;//this做用域:當前對象
this.age=age;
this.hobby=hobby;
this.eat=function(){
alert("我叫"+this.name+",我喜歡"+this.hobby+",是個程序員");
}
}
var maidou =new Pet("麥兜",25,"coding");//實例化、建立對象
maidou.eat();//調用eat方法
複製代碼
var wcDog =new Object();
wcDog.name="旺財";
wcDog.age=3;
wcDog.work=function(){
alert("我是"+wcDog.name+",汪汪汪......");
}
wcDog.work();
複製代碼
function Dog(){
}
Dog.prototype.name="旺財";
Dog.prototype.eat=function(){
alert(this.name+"是個吃貨");
}
var wangcai =new Dog();
wangcai.eat();
複製代碼
function Car(name,price){
this.name=name;
this.price=price;
}
Car.prototype.sell=function(){
alert("我是"+this.name+",我如今賣"+this.price+"萬元");
}
var camry =new Car("凱美瑞",27);
camry.sell();
複製代碼
JS
代碼並運行eval
,不安全,很是耗性能(2
次,一次解析成js
語句,一次執行)JSON
字符串轉換爲JSON對象的時候能夠用eval,var obj =eval('('+ str +')')
undefined
表示不存在這個值。
undefined
:是一個表示"無"的原始值或者說表示"缺乏值",就是此處應該有一個值,可是尚未定義。當嘗試讀取時會返回 undefined
例如變量被聲明瞭,但沒有賦值時,就等於undefined
null
表示一個對象被定義了,值爲「空值」
null
: 是一個對象(空對象, 沒有任何屬性和方法)
例如做爲函數的參數,表示該函數的參數不是對象;
在驗證null
時,必定要使用 ===
,由於 ==
沒法分別null
和 undefined
[1, NaN, NaN]
由於 parseInt
須要兩個參數 (val, radix)
,其中radix
表示解析時用的基數。map
傳了 3
個(element, index, array)
,對應的 radix
不合法致使解析失敗。use strict
是一種ECMAscript 5
添加的(嚴格)運行模式,這種模式使得 Javascript 在更嚴格的條件下運行,使JS
編碼更加規範化的模式,消除Javascript
語法的一些不合理、不嚴謹之處,減小一些怪異行爲JSON(JavaScript Object Notation)
是一種輕量級的數據交換格式
它是基於JavaScript
的一個子集。數據格式簡單, 易於讀寫, 佔用帶寬小
JSON
字符串轉換爲JSON對象:
var obj =eval('('+ str +')');
var obj = str.parseJSON();
var obj = JSON.parse(str);
複製代碼
JSON
對象轉換爲JSON字符串:var last=obj.toJSONString();
var last=JSON.stringify(obj);
複製代碼
defer
和async
、動態建立DOM
方式(用得最多)、按需異步載入js
漸進加強 :針對低版本瀏覽器進行構建頁面,保證最基本的功能,而後再針對高級瀏覽器進行效果、交互等改進和追加功能達到更好的用戶體驗。
優雅降級 :一開始就構建完整的功能,而後再針對低版本瀏覽器進行兼容
defer
並行加載js
文件,會按照頁面上script
標籤的順序執行async
並行加載js
文件,下載完成當即執行,不會按照頁面上script
標籤的順序執行with
語句this
指向全局對象attribute
是dom
元素在文檔中做爲html
標籤擁有的屬性;property
就是dom
元素在js
中做爲對象擁有的屬性。html
的標準屬性來講,attribute
和property
是同步的,是會自動更新的JavaScript
提供了簡單的字符串插值功能)for-of
(用來遍歷數據—例如數組中的值。)arguments
對象可被不定參數和默認參數完美代替。ES6
將3Promise
對象歸入規範,提供了原生的Promise
對象。let
和const
命令,用來聲明變量。let
命令實際上就增長了塊級做用域。module
模塊的概念OOP
基礎的人更快上手js
,至少是一個官方的實現了js
的人來講,這個東西沒啥大影響;一個Object.creat()
搞定繼承,比class
簡潔清晰的多instanceof
方法
instanceof
運算符是用來測試一個對象是否在其原型鏈原型構造函數的屬性var arr = [];
arr instanceof Array; // true
複製代碼
constructor
方法
constructor
屬性返回對建立此對象的數組函數的引用,就是返回對象相對應的構造函數var arr = [];
arr.constructor == Array; //true
複製代碼
jQuery
正在使用的Object.prototype.toString.call(value) == '[object Array]'
// 利用這個方法,能夠寫一個返回數據類型的方法
var isType = function (obj) {
return Object.prototype.toString.call(obj).slice(8,-1);
}
複製代碼
ES5
新增方法isArray()
var a = new Array(123);
var b = new Date();
console.log(Array.isArray(a)); //true
console.log(Array.isArray(b)); //false
複製代碼
let
命令不存在變量提高,若是在let
前使用,會致使報錯let
和const
命令,就會造成封閉做用域this的指向在函數定義的時候是肯定不了的,只有函數執行的時候才能肯定this到底指向誰,實際上this的最終指向的是那個調用它的對象
《javascript語言精髓》中大概歸納了4種調用方式:
方法調用模式
函數調用模式
構造器調用模式
graph LR
A-->B
複製代碼
回調函數
事件監聽(採用時間驅動模式,取決於某個事件是否發生):
發佈/訂閱(觀察者模式)
Promise對象
Generator函數
async函數
RegExp
、JSON
、Ajax
、DOM
、BOM
、內存泄漏、跨域、異步裝載、模板引擎、前端MVC
、路由、模塊化、Canvas
、ECMAScript
CSS3
的動畫的優勢
CSS3
的動畫作一些優化JavaScript
的動畫正好彌補了這兩個缺點,控制能力很強,能夠單幀的控制、變換,同時寫得好徹底能夠兼容IE6
,而且功能強大。對於一些複雜控制的動畫,使用javascript
會比較靠譜。而在實現一些小的交互動效的時候,就多考慮考慮CSS
吧一般咱們會用循環的方式來遍歷數組。可是循環是 致使js 性能問題的緣由之一。通常咱們會採用下幾種方式來進行數組的遍歷
for in
循環
for
循環
forEach
forEach
回調中兩個參數分別爲 value
,index
forEach
沒法遍歷對象Firefox
和 chrome
支持forEach
沒法使用 break
,continue
跳出循環,且使用 return
是跳過本次循環這兩種方法應該很是常見且使用很頻繁。但實際上,這兩種方法都存在性能問題
在方式一中,for-in
須要分析出array
的每一個屬性,這個操做性能開銷很大。用在 key
已知的數組上是很是不划算的。因此儘可能不要用for-in
,除非你不清楚要處理哪些屬性,例如 JSON
對象這樣的狀況
在方式2中,循環每進行一次,就要檢查一下數組長度。讀取屬性(數組長度)要比讀局部變量慢,尤爲是當 array
裏存放的都是 DOM
元素,由於每次讀取都會掃描一遍頁面上的選擇器相關元素,速度會大大下降