7種!javascript
其中,除了Object是引用類型外,都是基本類型css
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------html
null是一個空指針,是一個特殊的object,會被前端
undefined是指一個被調用但未被賦值的變量html5
他們在if條件下都爲falsejava
null 轉爲數字是0,而undefined轉爲數字是NaNwebpack
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ios
一、標記清除nginx
二、引用計數git
對於性能問題:若是在運行期間,分配的內存不少,那麼垃圾收集的工做量也會至關大,所以,每一次垃圾收集的時間間隔如何肯定是一個很重要的問題。
從IE7開始,js改變了垃圾收集的工做方式:觸發垃圾收集的變量分配。相似於TCP擁塞窗口的控制。。。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
先捕獲,再冒泡
如上圖所示,你點擊了一個div裏的text,會先從window捕獲,直到text,而後從text冒泡,一直到冒泡到window
那麼什麼是捕獲,什麼是冒泡?
好比:
element.addEventListener('click', function(e){
console.log(e.target)
}, true|false);
其中,咱們經常使用的false就是冒泡,true就是捕獲。
return不只阻止事件冒泡,也阻止事件自己,stopPropagation()只阻止事件冒泡
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{} === {} // false [] === [] // false (function () {} === function () {}) // false
上面代碼分別比較兩個空對象、兩個空數組、兩個空函數,結果都是不相等。
緣由是對於複合類型的值,嚴格相等運算比較的是,它們是否引用同一個內存地址,而運算符兩邊的空對象、空數組、空函數的值,都存放在不一樣的內存地址,結果固然是。
false
注意:NaN與任何值都不相等,包括自身。
NaN === NaN // false
a !== b 等價於
!(a === b)
1 == true // true // 等同於 1 === Number(true) 0 == false // true // 等同於 0 === Number(false) 2 == true // false // 等同於 2 === Number(true) 2 == false // false // 等同於 2 === Number(false) 'true' == true // false // 等同於 Number('true') === Number(true) // 等同於 NaN === 1 '' == 0 // true // 等同於 Number('') === 0 // 等同於 0 === 0 '' == false // true // 等同於 Number('') === Number(false) // 等同於 0 === 0 '1' == true // true // 等同於 Number('1') === Number(true) // 等同於 1 === 1 '\n 123 \t' == 123 // true // 由於字符串轉爲數字時,省略前置和後置的空格
// 對象與數值比較時,對象轉爲數值 [1] == 1 // true // 等同於 Number([1]) == 1 // 對象與字符串比較時,對象轉爲字符串 [1] == '1' // true // 等同於 String([1]) == '1' [1, 2] == '1,2' // true // 等同於 String([1, 2]) == '1,2' // 對象與布爾值比較時,兩邊都轉爲數值 [1] == true // true // 等同於 Number([1]) == Number(true) [2] == true // false // 等同於 Number([2]) == Number(true)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ajax
全稱是異步 javascript 和 XML
,用來和服務端進行數據交互的,讓無刷新替換頁面數據成了可能。
https://www.html5rocks.com/zh/tutorials/file/xhr2/#toc-examples
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
這個東西,細節不少,短期內想要基本熟悉很難。
let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { console.log(xhr.responseText); } } xhr.open(); xhr.send();
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
let add = (function () { let i = 0; return function () { return ++i; } })()
能夠這樣理解這個閉包,add函數return的是一個匿名函數,所以,訪問不到函數內的全局變量i,所以i被隱藏起來了。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
for(var i=0;i<10;i++) { setTimeout((function (x) { return function () { console.log(x) } })(i), 1000) }
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
其中,function meili () {}是函數聲明,會有函數聲明提高,全局可用。
function mogu () {}是函數表達式,必須先聲明,後使用。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 - 2 - 3 - be - also - 4 - test。
https://blog.csdn.net/cjgeng88/article/details/79846670
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
我通常用這三種,cors
,nginx反向代理
,jsonp
jsonp
: 單純的 get 一些數據,侷限性很大...就是利用script標籤的src屬性來實現跨域。nginx 反向代理
: 主要就是用了nginx.conf
內的proxy_pass http://xxx.xxx.xxx
,會把全部請求代理到那個域名,有利也有弊吧..cors
的話,可控性較強,須要先後端都設置,兼容性 IE10+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CSRF工具的防護手段
1. 儘可能使用POST,限制GET
GET接口太容易被拿來作CSRF攻擊,看第一個示例就知道,只要構造一個img標籤,而img標籤又是不能過濾的數據。接口最好限制爲POST使用,GET則無效,下降攻擊風險。
固然POST並非萬無一失,攻擊者只要構造一個form就能夠,但須要在第三方頁面作,這樣就增長暴露的可能性。
2. 瀏覽器Cookie策略
IE六、七、八、Safari會默認攔截第三方本地Cookie(Third-party Cookie)的發送。可是Firefox二、三、Opera、Chrome、Android等不會攔截,因此經過瀏覽器Cookie策略來防護CSRF攻擊不靠譜,只能說是下降了風險。
PS:Cookie分爲兩種,Session Cookie(在瀏覽器關閉後,就會失效,保存到內存裏),Third-party Cookie(即只有到了Exprie時間後纔會失效的Cookie,這種Cookie會保存到本地)。
PS:另外若是網站返回HTTP頭包含P3P Header,那麼將容許瀏覽器發送第三方Cookie。
3. 加驗證碼
驗證碼,強制用戶必須與應用進行交互,才能完成最終請求。在一般狀況下,驗證碼能很好遏制CSRF攻擊。可是出於用戶體驗考慮,網站不能給全部的操做都加上驗證碼。所以驗證碼只能做爲一種輔助手段,不能做爲主要解決方案。
4. Referer Check
Referer Check在Web最多見的應用就是「防止圖片盜鏈」。同理,Referer Check也能夠被用於檢查請求是否來自合法的「源」(Referer值是不是指定頁面,或者網站的域),若是都不是,那麼就很可能是CSRF攻擊。
可是由於服務器並非何時都能取到Referer,因此也沒法做爲CSRF防護的主要手段。可是用Referer Check來監控CSRF攻擊的發生,卻是一種可行的方法。
5. Anti CSRF Token
如今業界對CSRF的防護,一致的作法是使用一個Token(Anti CSRF Token)。
例子:
1. 用戶訪問某個表單頁面。
2. 服務端生成一個Token,放在用戶的Session中,或者瀏覽器的Cookie中。
3. 在頁面表單附帶上Token參數。
4. 用戶提交請求後, 服務端驗證表單中的Token是否與用戶Session(或Cookies)中的Token一致,一致爲合法請求,不是則非法請求。
這個Token的值必須是隨機的,不可預測的。因爲Token的存在,攻擊者沒法再構造一個帶有合法Token的請求實施CSRF攻擊。另外使用Token時應注意Token的保密性,儘可能把敏感操做由GET改成POST,以form或AJAX形式提交,避免Token泄露。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------cookie
,sessionStorage
,localStorage
的差別..cookie
: 大小4KB 左右,跟隨請求(請求頭),會佔用帶寬資源,可是如果用來判斷用戶是否在線這些挺方便sessionStorage
和localStorage
大同小異,大小看瀏覽器支持,通常爲5MB,數據只保留在本地,不參與服務端交互.
sessionStorage
的生存週期只限於會話中,關閉了儲存的數據就沒了.localStorage
則保留在本地,沒有人爲清除會一直保留-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
https://www.cnblogs.com/lvdabao/p/es6-promise-1.html
let p = new Promise(function(resolve, reject) { setTimeout(function () { console.log('執行完成'); resolve('hello'); }, 2000); });
我new了一個Promise對象,先無論這裏面的每句話是什麼意思,這裏注意,在new的同時,裏面的函數已經被執行了,所以咱們能夠利用函數,讓Promise延遲執行。
function dosomethingAsync () { let p = new Promise(function(resolve, reject) { setTimeout(function () { console.log('執行完成'); resolve('hello'); }, 2000); }); return p; } dosomethingAsync();
這裏說一個概念,promise的狀態,promise的狀態分爲三種,pending(等待),fulfilled(成功),rejected(失敗)。一個promise只能從pending到另外兩種狀態之一轉變,且這種轉變是單向的,一次性的。也就是說,只能轉變一次,且不可更改結果。
那麼要怎麼轉變呢?就經過resolve(),和reject()。
好比咱們定義,咱們從數據庫取年齡爲100歲的人的信息,若是取到了,就是成功,若是沒取到就是失敗,咱們寫一下僞代碼
1 function getSomeoneInfo () { 2 let p = new Promise(function (resolve, reject) { 3 axios.get('http://獲取年齡的api/&age=100', function (response) { 4 // 接收響應的回調函數 5 if (response.data 不爲空) { 6 // 成功了 7 resolve(response.data); 8 } else { 9 // 失敗了 10 reject('error'); 11 } 12 }) 13 }) 14 return p; 15 } 16 17 getSomeoneInfo ();
能夠看到,Promise在尚未執行的時候狀態爲pending,在經過resolve和reject函數後分別轉爲兩種對應的狀態。
那麼知道狀態改變了之後,要怎麼作呢?經過then
function getSomeoneInfo () { let p = new Promise(function (resolve, reject) { axios.get('http://獲取年齡的api/&age=100', function (response) { // 接收響應的回調函數 if (response.data 不爲空) { // 成功了 resolve(response.data); } else { // 失敗了 reject('error'); } }) }) return p; } getSomeoneInfo().then(function (data) { console.log(data); }, function (data) { console.log(data); });
能夠看到then函數的參數是兩個匿名函數,能夠這麼理解,用then來監聽promise的狀態變化,若是轉向成功,就執行第一個函數,且參數data 和 response.data一致,不然轉向第二個函數,data等於'error'。
promise.all()
同時執行多個異步函數,所有都執行完了,進到then裏
Promise .all([runAsync1(), runAsync2(), runAsync3()]) .then(function(results){ console.log(results); });
result是三個函數執行結果組成的數組。
promise.race()
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
https://segmentfault.com/a/1190000013292562?utm_source=channel-newest
放在一個函數前的async有兩個做用:
promise前面的await關鍵字可以使JavaScript等待,直到promise處理結束。而後:
若是它是一個錯誤,異常就產生了,就像在那個地方調用了throw error同樣。
有了async/await,咱們不多須要寫promise.then/catch,可是咱們仍然不該該忘記它們是基於promise的,由於有些時候(例如在最外面的範圍內)咱們不得不使用這些方法。Promise.all也是一個很是棒的東西,它可以同時等待不少任務。
舉例
一個獲取頭像的需求,若是用promise只能以鏈式這麼寫,若是不以promise寫,甚至會形成回調地獄
loadJson('/article/promise-chaining/user.json') .then(user => loadGithubUser(user.name)) .then(showAvatar) .then(githubUser => alert(`Finished showing ${githubUser.name}`));
若是用async / await
async function showAvatar() { // read our JSON let response = await fetch('/article/promise-chaining/user.json') let user = await response.json() // read github user let githubResponse = await fetch(`https://api.github.com/users/${user.name}`) let githubUser = await githubResponse.json() // 展現頭像 let img = document.createElement('img') img.src = githubUser.avatar_url img.className = 'promise-avatar-example' documenmt.body.append(img) // 等待3s await new Promise((resolve, reject) => { setTimeout(resolve, 3000) }) img.remove() return githubUser } showAvatar()
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
new 操做符新建了一個空對象,這個對象原型指向構造函數的prototype,執行構造函數後返回這個對象。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
clientHeight:表示的是可視區域的高度,不包含border和滾動條
offsetHeight:表示可視區域的高度,包含了border和滾動條
scrollHeight:表示了全部區域的高度,包含了由於滾動被隱藏的部分。
clientTop:表示邊框border的厚度,在未指定的狀況下通常爲0
scrollTop:滾動後被隱藏的高度,獲取對象相對於由offsetParent屬性指定的父座標(css定位的元素或body元素)距離頂端的高度。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
http://www.cnblogs.com/coco1s/p/5499469.html
針對高頻度觸發的事件(例如頁面 scroll ,屏幕 resize,監聽用戶輸入等)應該減小操做,下面介紹兩種經常使用的解決方法,防抖和節流。
函數節流是指必定時間內js方法只跑一次。好比人的眨眼睛,就是必定時間內眨一次。這是函數節流最形象的解釋。
函數防抖是指頻繁觸發的狀況下,只在最終中止的時候,才執行代碼一次。好比生活中的坐公交,就是必定時間內,若是有人陸續刷卡上車,司機就不會開車。只有別人沒刷卡了,司機纔開車。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
前端模塊化就是複雜的文件編程一個一個獨立的模塊,好比js文件等等,分紅獨立的模塊有利於重用(複用性)和維護(版本迭代),這樣會引來模塊之間相互依賴的問題,因此有了commonJS規範,AMD,CMD規範等等,以及用於js打包(編譯等處理)的工具webpack。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一個模塊是能實現特定功能的文件,有了模塊就能夠方便的使用別人的代碼,想要什麼功能就能加載什麼模塊。
requireJS實現了AMD規範,主要用於解決下述兩個問題。
1.多個文件有依賴關係,被依賴的文件須要早於依賴它的文件加載到瀏覽器 2.加載的時候瀏覽器會中止頁面渲染,加載文件越多,頁面失去響應的時間越長。
語法:requireJS定義了一個函數define,它是全局變量,用來定義模塊。
requireJS的例子:
//定義模塊 define(['dependency'], function(){ var name = 'Byron'; function printName(){ console.log(name); } return { printName: printName }; }); //加載模塊 require(['myModule'], function (my){ my.printName(); }
requirejs定義了一個函數define,它是全局變量,用來定義模塊:
define(id?dependencies?,factory)
在頁面上使用模塊加載函數:
require([dependencies],factory);
總結AMD規範:require()函數在加載依賴函數的時候是異步加載的,這樣瀏覽器不會失去響應,它指定的回調函數,只有前面的模塊加載成功,纔會去執行。
由於網頁在加載js的時候會中止渲染,所以咱們能夠經過異步的方式去加載js,而若是須要依賴某些,也是異步去依賴,依賴後再執行某些方法。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function deepClone(obj){ var newObj= obj instanceof Array ? []:{}; for(var item in obj){ var temple= typeof obj[item] == 'object' ? deepClone(obj[item]):obj[item]; newObj[item] = temple; } return newObj; }
ES5的經常使用的對象克隆的一種方式。注意數組是對象,可是跟對象又有必定區別,因此咱們一開始判斷了一些類型,決定newObj是對象仍是數組~
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
var myNewAjax=function(url){ return new Promise(function(resolve,reject){ var xhr = new XMLHttpRequest(); xhr.open('get',url); xhr.send(data); xhr.onreadystatechange=function(){ if(xhr.status==200&&readyState==4){ var json=JSON.parse(xhr.responseText); resolve(json) }else if(xhr.readyState==4&&xhr.status!=200){ reject('error'); } } }) }
http://www.javashuo.com/article/p-qasukviu-dp.html
value:對應的值,默認爲undefined。
writable:是否能夠被重寫。默認爲false。用內部方法也不可被修改
enumeable:此屬性是否能夠被枚舉到(注意這個說法,「被枚舉到」,當你用for in或object.keys()的時候能不能被枚舉出來)。設置爲true能夠被枚舉;設置爲false,不能被枚舉。默認爲false。
configurable:是否能夠刪除目標屬性或是否能夠再次修改屬性的特性(writable, configurable, enumerable)。設置爲true能夠被刪除或能夠從新設置特性;設置爲false,不能被能夠被刪除或不能夠從新設置特性。默認爲false。
咱們假設這裏有一個user對象,
Object.defineProperty(user,'name',{ set:function(key,value){ } })
缺點:若是id不在user對象中,則不能監聽id的變化
var user = new Proxy({},{ set:function(target,key,value,receiver){ } })
這樣即便有屬性在user中不存在,經過user.id來定義也一樣能夠這樣監聽這個屬性的變化哦~
obj={ name:yuxiaoliang, getName:function(){ return this.name } } object.defineProperty(obj,"name",{ //不可枚舉不可配置 });
function product(){ var name='yuxiaoliang'; this.getName=function(){ return name; } } var obj=new product();
==
:等同,比較運算符,兩邊值類型不一樣的時候,先進行類型轉換,再比較;===
:恆等,嚴格比較運算符,不作類型轉換,類型不一樣就是不等;Object.is()
是ES6新增的用來比較兩個值是否嚴格相等的方法,與===
的行爲基本一致。先說= = =
,這個比較簡單,只須要利用下面的規則來判斷兩個值是否恆等就好了:
isNaN()
或Object.is()
來判斷)。再說Object.is()
,其行爲與===
基本一致,不過有兩處不一樣:
舉個栗子☺:
+0 === -0 //true NaN === NaN // false Object.is(+0, -0) // false Object.is(NaN, NaN) // true
這裏有一篇文章講的是requestAnimationFrame:http://www.cnblogs.com/xiaohuochai/p/5777186.html
與setTimeout和setInterval不一樣,requestAnimationFrame不須要設置時間間隔,
大多數電腦顯示器的刷新頻率是60Hz,大概至關於每秒鐘重繪60次。大多數瀏覽器都會對重繪操做加以限制,不超過顯示器的重繪頻率,由於即便超過那個頻率用戶體驗也不會有提高。所以,最平滑動畫的最佳循環間隔是1000ms/60,約等於16.6ms。
RAF採用的是系統時間間隔,不會由於前面的任務,不會影響RAF,可是若是前面的任務多的話,
會響應setTimeout和setInterval真正運行時的時間間隔。
特色:
(1)requestAnimationFrame會把每一幀中的全部DOM操做集中起來,在一次重繪或迴流中就完成,而且重繪或迴流的時間間隔牢牢跟隨瀏覽器的刷新頻率。
(2)在隱藏或不可見的元素中,requestAnimationFrame將不會進行重繪或迴流,這固然就意味着更少的CPU、GPU和內存使用量
(3)requestAnimationFrame是由瀏覽器專門爲動畫提供的API,在運行時瀏覽器會自動優化方法的調用,而且若是頁面不是激活狀態下的話,動畫會自動暫停,有效節省了CPU開銷。