這篇是作為一個有js,jq基礎,主要知識來源于為w3school和日常踩坑,但是不夠全面的前端學習者(已經(jīng)不好意思叫自己初學者了)。筆記作為一些知識點的摘要方便日后翻閱速記。
閉包那部分,面向對象編程那部分沒理解透徹,等后面來補坑
JS部分
1.Map與Set:
Map是一組鍵值對的結構,具有極快的查找速度。具有get、has、delete和set屬性。用法如下:
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]); m.get('Michael'); // 95
Set和Map類似,也是一組key的集合,但不存儲value。由于key不能重復,所以,Set中,沒有重復的key。通過add(key)方法可以添加元素到Set中,可以重復添加,但不會有效果。通過delete(key)方法刪除元素
2.for...of與for...in的區(qū)別:for...of它只循環(huán)集合本身的元素。更好的方式是使用forEach
a.forEach(function (element, index, array) { // element: 指向當前元素的值 // index: 指向當前索引 // array: 指向Array對象本身 alert(element);});
3.let與var相比,可以申明一個塊級作用域的變量。舉例:我們在for
循環(huán)等語句塊中是無法定義具有局部作用域的變量的,聲明的var i=0,在for函數(shù)結束后這個i還是可以使用,此時可以用let i=0.
4.filter:它用于把Array的某些元素過濾掉,然后返回剩下的元素。filter()把傳入的函數(shù)依次作用于每個元素,然后根據(jù)返回值是true還是false決定保留還是丟棄該元素。用法如下:
var arr = [1, 2, 4, 5, 6, 9, 10, 15]; var r = arr.filter(function (x) { return x % 2 !== 0; }); r; // [1, 5, 9, 15]
filter的回調函數(shù):
var r = arr.filter(function (element, index, self) { console.log(element); // 依次打印'A', 'B', 'C' console.log(index); // 依次打印0, 1, 2 console.log(self); // self就是變量arr return true; });
5.map方法:
function pow(x) { return x * x; } var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81] arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']
reduce方法:
[x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
用法:
var arr = [1, 3, 5, 7, 9]; arr.reduce(function (x, y) { return x + y; }); // 25
6.箭頭函數(shù)
相當于匿名函數(shù):x => x * x相當于function (x) { return x * x;}
- 不同的參數(shù)有不同的寫法:
// 兩個參數(shù):(x, y) => x * x + y * y // 無參數(shù):() => 3.14 // 可變參數(shù):(x, y, ...rest) => {} - 返回對象時要用
x => ({ foo: x }) - 箭頭函數(shù)和匿名函數(shù)有個明顯的區(qū)別:箭頭函數(shù)內部的this是詞法作用域,由上下文確定。無需hack:
var that = this;
7.generator
和函數(shù)不同的是,generator由function定義,并且,除了return語句,還可以用yield返回多次。直接調用一個generator和調用函數(shù)不一樣,調用時僅僅是創(chuàng)建了一個generator對象,還沒有去執(zhí)行它。
調用generator對象有兩個方法,一是不斷地調用generator對象的next()方法:next()方法會執(zhí)行generator的代碼,然后,每次遇到y(tǒng)ield ;就返回一個對象{value: x, done: true/false},然后“暫?!?。返回的value就是yield的返回值,done表示這個generator是否已經(jīng)執(zhí)行結束了。如果done為true,則value就是return的返回值。當執(zhí)行到done為true時,這個generator對象就已經(jīng)全部執(zhí)行完畢,不要再繼續(xù)調用next()了。
第二個方法是直接用for ... of循環(huán)迭代generator對象,這種方式不需要我們自己判斷done:
for (var x of fib(5)) { console.log(x); // 依次輸出0, 1, 1, 2, 3 }
generator可以在執(zhí)行過程中多次返回,所以它看上去就像一個可以記住執(zhí)行狀態(tài)的函數(shù)
8.關于標準對象

9.正則表達式:
用
\d可以匹配一個數(shù)字,\w可以匹配一個字母或數(shù)字,.可以匹配任意字符,要匹配變長的字符,\s可以匹配一個空格(也包括Tab等空白符).在正則表達式中,用表示任意個字符(包括0個),用+表示至少一個字符,用?表示0個或1個字符,用{n}表示n個字符,用{n,m}表示n-m個字符。如果正則表達式中定義了組,就可以在RegExp對象上用exec()方法提取出子串來。exec()方法在匹配成功后,會返回一個Array,第一個元素是正則表式匹配到的整個字符串,后面的字符串表示匹配成功的子串。exec()方法在匹配失敗時返回null。
\d+采用貪婪匹配,影響后面的匹配,加個?就可以讓\d+采用非貪婪匹配。正則表達式還可以指定9標志,表示全局匹配,正則表達式本身會更新lastIndex屬性,表示上次匹配到的最后索引。i標志,表示忽略大小寫,m標志,表示執(zhí)行多行匹配。
10.JSON
- 轉為JSON格式:JSON.stringify(對象);
- 要輸出得好看一些,可以加上參數(shù),按縮進輸出:JSON.stringify(對象, null, ' ');
- 輸出指定的屬性:JSON.stringify(對象, ['屬性1', '屬性2'], ' ');
- 還可以傳入一個函數(shù),這樣對象的每個鍵值對都會被函數(shù)先處理:
function 函數(shù)名(key,value){ }; JSON.stringify(對象, 函數(shù), ' '); - 可以給對象里定義一個toJSON()的方法,調用JSON.stringify(對象); 時直接返回JSON應該序列化的數(shù)據(jù)。
- 拿到一個JSON格式的字符串,我們直接用JSON.parse()把它變成一個JavaScript對象。用法:
JSON.parse('字符串',function(){//可選 })
11.面向對象編程部分理解起來比較困難,等后續(xù)回來補坑。
12.要加載一個新頁面,可以調用location.assign('新url')。document
對象還有一個cookie屬性,可以獲取當前頁面的Cookie。調用history對象的back()或forward (),相當于用戶點擊了瀏覽器的“后退”或“前進”按鈕。但體驗感不好,盡量不要使用。
13:DOM操作,此處一些零碎的知識點:
// 獲取節(jié)點test下的所有直屬子節(jié)點: var cs = test.children; // 獲取節(jié)點test下第一個、最后一個子節(jié)點: var first = test.firstElementChild; var last = test.lastElementChild;// 通過querySelector獲取ID為q1的節(jié)點: var q1 = document.querySelector('#q1'); // 通過querySelectorAll獲取q1節(jié)點內的符合條件的所有節(jié)點: var ps = q1.querySelectorAll('div.highlighted > p');設置style: xxx.style.fontSize='13px';xxx.style.paddingTop='5px';(注意駝峰式)
創(chuàng)建節(jié)點,設置id與內容:
var haskell = document.createElement('p'); haskell.id = 'haskell'; haskell.innerText = 'Haskell'; //設置屬性: d.setAttribute('type', 'text/css');把子節(jié)點插入到指定的位置怎么辦?可以用
parentElement.insertBefore(newElement, referenceElement);,子節(jié)點會插入到referenceElement之前。刪除一個DOM節(jié)點:調用父節(jié)點的removeChild把自己刪掉。刪除后的節(jié)點雖然不在文檔樹中了,但其實它還在內存中,可以隨時再次被添加到別的位置。
14.Promise對象:承諾將來會執(zhí)行
-
一種用法:當小于1時,實行resolve,對應then的function,否則,執(zhí)行reject函數(shù),對應catch的function。
- 另一種:有若干個異步任務,需要先做任務1,如果成功后再做任務2,任何任務失敗則不再繼續(xù)并執(zhí)行錯誤處理函數(shù)。
job1.then(job2).then(job3).catch(handleError);
其中,job1、job2和job3都是Promise對象。 - Promise還可以并行執(zhí)行異步任務:
// 同時執(zhí)行p1和p2,并在它們都完成后執(zhí)行then: Promise.all([p1, p2]).then(function (results) { console.log(results); // 獲得一個Array: ['P1', 'P2'] }); - Promise執(zhí)行多個異步任務,只需要獲得先返回的結果:
Promise.all([p1, p2]).then(function (results) { });
JQ部分
1.選擇器
- 按屬性查找:
var email = $('[name=email]'); // 找出<??? name="email"> - 按class名稱查找:
var icons = $('[class^="icon-"]'); // 找出所有class包含至少一個以icon-開頭的DOM - 組合查找:
var emailInput = $('input[name=email]'); // 只找出input類型 var tr = $('tr.red'); // 使用tag+class查找找出<tr class="red ...">...</tr>,注意無空格 - 多項選擇:用逗號分隔,將內容都選出來
- 層級選擇:用空格分隔開,進行層級選擇
- 子選擇器
$('parent>child')類似層級選擇器,但是限定了層級關系必須是父子關系,就是<child>節(jié)點必須是<parent>節(jié)點的直屬子節(jié)點。 - 過濾器:
$('ul.lang li:first-child'); // 僅選出第一個元素 $('ul.lang li:last-child'); // 僅選最后一個元素 $('ul.lang li:nth-child(2)'); // 選出第N個元素,N從1開始 $('ul.lang li:nth-child(even)'); // 選出序號為偶數(shù)的元素 $('ul.lang li:nth-child(odd)'); // 選出序號為奇數(shù)的元素 -
表單相關
- 查找:find(''),parent(''),next(/''),pre(/'')。
- 過濾:filter('')方法可以過濾掉不符合選擇器條件的節(jié)點?;蛘邆魅胍粋€函數(shù),要特別注意函數(shù)內部的this:
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell langs.filter(function () { return this.innerHTML.indexOf('S') === 0; // 返回S開頭的節(jié)點 }); // 拿到Swift, Scheme - 此外,一個jQuery對象如果包含了不止一個DOM節(jié)點,first()、last()
和slice()方法可以返回一個新的jQuery對象,把不需要的DOM節(jié)點去掉.
2.添加節(jié)點:
- 如果要添加的DOM節(jié)點已經(jīng)存在于HTML文檔中,它會首先從文檔移除,然后再添加,也就是說,用append(),你可以移動一個DOM節(jié)點。
- 父節(jié)點對子節(jié)點添加:append()與prepend(),同級元素用before()和after()
3.刪除節(jié)點:獲得節(jié)點后調用remove()
4.change事件:當用戶在文本框中輸入時,就會觸發(fā)change
事件。但是,如果用JavaScript代碼去改動文本框的值,將不會觸發(fā)change
5.window.open()只有在用戶觸發(fā)下才能執(zhí)行
6.off('click', function () {...})無法移除已綁定的第一個匿名函數(shù)
7.動畫效果:
div.animate({ opacity: 0.25, width: '256px', height: '256px' }, 3000, function () { console.log('動畫已結束'); //回調函數(shù) });
jQuery的動畫效果還可以串行執(zhí)行,通過delay()方法還可以實現(xiàn)暫停,例如div.slideDown(2000).delay(1000)
用animate()設置background-color沒有效果,此時請使用css的transition。
8.ajax,一種promise用法:
var jqxhr = $.ajax('/api/categories', { dataType: 'json' }).done(function (data) { ajaxLog('成功, 收到的數(shù)據(jù): ' + JSON.stringify(data)); }).fail(function (xhr, status) { ajaxLog('失敗: ' + xhr.status + ', 原因: ' + status); }).always(function () { ajaxLog('請求完成: 無論成功或失敗都會調用'); });
getJSON方法可以將獲得的data自動轉為JSON格式
9.編寫jq插件,通過擴展$.fn對象實現(xiàn)的:
$.fn.highlight1 = function (可選參數(shù)) { // this已綁定為當前jQuery對象: this.css('backgroundColor', '#fffceb').css('color', '#d85030'); return this;//jQuery對象支持鏈式操作,我們自己寫的擴展方法也要能繼續(xù)鏈式下去 }
當需要可以修改highlight的css屬性的顏色之類的屬性時,可以使用:
$.fn.highlight = function (options) { // 合并默認值和用戶設定值: var opts = $.extend({}, $.fn.highlight.defaults, options); this.css('backgroundColor', opts.backgroundColor).css('color', opts.color); return this; } // 設定默認值: $.fn.highlight.defaults = { color: '#d85030', backgroundColor: '#fff8de' } //用戶使用時設定: $.fn.highlight.defaults.color = '#fff'; $.fn.highlight.defaults.backgroundColor = '#000';
當需要這個插件只能應用與某些DOM時,在插件內return 時使用一個filter+each,注意: each()內部的回調函數(shù)的this綁定為DOM本身!
underscore
1.對collection
- underscore與jq其類似,會把自身綁定到唯一的全局變量上,使用map時用.map,如:
_.map({ a: 1, b: 2, c: 3 }, (v, k) => k + '=' + v); // ['a=1', 'b=2', 'c=3']
產(chǎn)生的結果為數(shù)組,如果想要返回對象則使用mapObjet - 當集合的所有元素都滿足條件時,.every()函數(shù)返回true,當集合的至少一個元素滿足條件時,.some()函數(shù)返回true:
_.every([1, 4, 7, -3, -9], (x) => x > 0); // false _.some([1, 4, 7, -3, -9], (x) => x > 0); // true - max / min這兩個函數(shù)直接返回集合中最大和最小的數(shù)
- groupBy()把集合的元素按照key歸類,key由傳入的函數(shù)返回,用來分組是非常方便
- shuffle()用洗牌算法隨機打亂一個集合,sample()則是隨機選擇一個或多個元素.
2.對array
- first / last顧名思義,這兩個函數(shù)分別取第一個和最后一個元素。
- flatten()接收一個Array,無論這個Array里面嵌套了多少個Array,flatten()最后都把它們變成一個一維數(shù)組。
- zip()把兩個或多個數(shù)組的所有元素按索引對齊,然后按索引合并成新組。例如,你有一個Array保存了名字,另一個Array保存了分數(shù),現(xiàn)在,要把名字和分數(shù)給對上,用zip()輕松實現(xiàn),unzip()則是反過來。
- object()類似zip(),把名字和分數(shù)直接對應成Object。
- range()讓你快速生成一個序列,不再需要用for循環(huán)實現(xiàn)了
_.range(從幾開始, 大于或小于幾, 步長);

