這篇是作為一個有js,jq基礎,主要知識來源于為w3school和日常踩坑,但是不夠全面的前端學習者(已經不好意思叫自己初學者了)。筆記作為一些知識點的摘要方便日后翻閱速記。
閉包那部分,面向對象編程那部分沒理解透徹,等后面來補坑
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的區別:for...of它只循環集合本身的元素。更好的方式是使用forEach
a.forEach(function (element, index, array) { // element: 指向當前元素的值 // index: 指向當前索引 // array: 指向Array對象本身 alert(element);});
3.let與var相比,可以申明一個塊級作用域的變量。舉例:我們在for
循環等語句塊中是無法定義具有局部作用域的變量的,聲明的var i=0,在for函數結束后這個i還是可以使用,此時可以用let i=0.
4.filter:它用于把Array的某些元素過濾掉,然后返回剩下的元素。filter()把傳入的函數依次作用于每個元素,然后根據返回值是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的回調函數:
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.箭頭函數
相當于匿名函數:x => x * x
相當于function (x) { return x * x;}
- 不同的參數有不同的寫法:
// 兩個參數:(x, y) => x * x + y * y // 無參數:() => 3.14 // 可變參數:(x, y, ...rest) => {}
- 返回對象時要用
x => ({ foo: x })
- 箭頭函數和匿名函數有個明顯的區別:箭頭函數內部的this是詞法作用域,由上下文確定。無需hack:
var that = this;
7.generator
和函數不同的是,generator由function定義,并且,除了return語句,還可以用yield返回多次。直接調用一個generator和調用函數不一樣,調用時僅僅是創建了一個generator對象,還沒有去執行它。
調用generator對象有兩個方法,一是不斷地調用generator對象的next()方法:next()方法會執行generator的代碼,然后,每次遇到yield ;就返回一個對象{value: x, done: true/false},然后“暫停”。返回的value就是yield的返回值,done表示這個generator是否已經執行結束了。如果done為true,則value就是return的返回值。當執行到done為true時,這個generator對象就已經全部執行完畢,不要再繼續調用next()了。
第二個方法是直接用for ... of循環迭代generator對象,這種方式不需要我們自己判斷done:
for (var x of fib(5)) { console.log(x); // 依次輸出0, 1, 1, 2, 3 }
generator可以在執行過程中多次返回,所以它看上去就像一個可以記住執行狀態的函數
8.關于標準對象
9.正則表達式:
用
\d
可以匹配一個數字,\w
可以匹配一個字母或數字,.
可以匹配任意字符,要匹配變長的字符,\s
可以匹配一個空格(也包括Tab等空白符).在正則表達式中,用表示任意個字符(包括0個),用+
表示至少一個字符,用?表示0個或1個字符,用{n}
表示n個字符,用{n,m}
表示n-m個字符。如果正則表達式中定義了組,就可以在RegExp對象上用exec()方法提取出子串來。exec()方法在匹配成功后,會返回一個Array,第一個元素是正則表式匹配到的整個字符串,后面的字符串表示匹配成功的子串。exec()方法在匹配失敗時返回null。
\d+
采用貪婪匹配,影響后面的匹配,加個?
就可以讓\d+
采用非貪婪匹配。正則表達式還可以指定9標志,表示全局匹配,正則表達式本身會更新lastIndex屬性,表示上次匹配到的最后索引。i標志,表示忽略大小寫,m標志,表示執行多行匹配。
10.JSON
- 轉為JSON格式:JSON.stringify(對象);
- 要輸出得好看一些,可以加上參數,按縮進輸出:JSON.stringify(對象, null, ' ');
- 輸出指定的屬性:JSON.stringify(對象, ['屬性1', '屬性2'], ' ');
- 還可以傳入一個函數,這樣對象的每個鍵值對都會被函數先處理:
function 函數名(key,value){ }; JSON.stringify(對象, 函數, ' ');
- 可以給對象里定義一個toJSON()的方法,調用JSON.stringify(對象); 時直接返回JSON應該序列化的數據。
- 拿到一個JSON格式的字符串,我們直接用JSON.parse()把它變成一個JavaScript對象。用法:
JSON.parse('字符串',function(){//可選 })
11.面向對象編程部分理解起來比較困難,等后續回來補坑。
12.要加載一個新頁面,可以調用location.assign('新url')。document
對象還有一個cookie屬性,可以獲取當前頁面的Cookie。調用history對象的back()或forward (),相當于用戶點擊了瀏覽器的“后退”或“前進”按鈕。但體驗感不好,盡量不要使用。
13:DOM操作,此處一些零碎的知識點:
// 獲取節點test下的所有直屬子節點: var cs = test.children; // 獲取節點test下第一個、最后一個子節點: var first = test.firstElementChild; var last = test.lastElementChild;
// 通過querySelector獲取ID為q1的節點: var q1 = document.querySelector('#q1'); // 通過querySelectorAll獲取q1節點內的符合條件的所有節點: var ps = q1.querySelectorAll('div.highlighted > p');
設置style: xxx.style.fontSize='13px';xxx.style.paddingTop='5px';(注意駝峰式)
創建節點,設置id與內容:
var haskell = document.createElement('p'); haskell.id = 'haskell'; haskell.innerText = 'Haskell'; //設置屬性: d.setAttribute('type', 'text/css');
把子節點插入到指定的位置怎么辦?可以用
parentElement.insertBefore(newElement, referenceElement);
,子節點會插入到referenceElement之前。刪除一個DOM節點:調用父節點的removeChild把自己刪掉。刪除后的節點雖然不在文檔樹中了,但其實它還在內存中,可以隨時再次被添加到別的位置。
14.Promise對象:承諾將來會執行
-
一種用法:當小于1時,實行resolve,對應then的function,否則,執行reject函數,對應catch的function。
- 另一種:有若干個異步任務,需要先做任務1,如果成功后再做任務2,任何任務失敗則不再繼續并執行錯誤處理函數。
job1.then(job2).then(job3).catch(handleError);
其中,job1、job2和job3都是Promise對象。 - Promise還可以并行執行異步任務:
// 同時執行p1和p2,并在它們都完成后執行then: Promise.all([p1, p2]).then(function (results) { console.log(results); // 獲得一個Array: ['P1', 'P2'] });
- Promise執行多個異步任務,只需要獲得先返回的結果:
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>節點必須是<parent>節點的直屬子節點。 - 過濾器:
$('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)'); // 選出序號為偶數的元素 $('ul.lang li:nth-child(odd)'); // 選出序號為奇數的元素
-
表單相關
- 查找:find(''),parent(''),next(/''),pre(/'')。
- 過濾:filter('')方法可以過濾掉不符合選擇器條件的節點。或者傳入一個函數,要特別注意函數內部的this:
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell langs.filter(function () { return this.innerHTML.indexOf('S') === 0; // 返回S開頭的節點 }); // 拿到Swift, Scheme
- 此外,一個jQuery對象如果包含了不止一個DOM節點,first()、last()
和slice()方法可以返回一個新的jQuery對象,把不需要的DOM節點去掉.
2.添加節點:
- 如果要添加的DOM節點已經存在于HTML文檔中,它會首先從文檔移除,然后再添加,也就是說,用append(),你可以移動一個DOM節點。
- 父節點對子節點添加:append()與prepend(),同級元素用before()和after()
3.刪除節點:獲得節點后調用remove()
4.change事件:當用戶在文本框中輸入時,就會觸發change
事件。但是,如果用JavaScript代碼去改動文本框的值,將不會觸發change
5.window.open()只有在用戶觸發下才能執行
6.off('click', function () {...})無法移除已綁定的第一個匿名函數
7.動畫效果:
div.animate({ opacity: 0.25, width: '256px', height: '256px' }, 3000, function () { console.log('動畫已結束'); //回調函數 });
jQuery的動畫效果還可以串行執行,通過delay()方法還可以實現暫停,例如div.slideDown(2000).delay(1000)
用animate()設置background-color沒有效果,此時請使用css的transition。
8.ajax,一種promise用法:
var jqxhr = $.ajax('/api/categories', { dataType: 'json' }).done(function (data) { ajaxLog('成功, 收到的數據: ' + JSON.stringify(data)); }).fail(function (xhr, status) { ajaxLog('失敗: ' + xhr.status + ', 原因: ' + status); }).always(function () { ajaxLog('請求完成: 無論成功或失敗都會調用'); });
getJSON方法可以將獲得的data自動轉為JSON格式
9.編寫jq插件,通過擴展$.fn對象實現的:
$.fn.highlight1 = function (可選參數) { // this已綁定為當前jQuery對象: this.css('backgroundColor', '#fffceb').css('color', '#d85030'); return this;//jQuery對象支持鏈式操作,我們自己寫的擴展方法也要能繼續鏈式下去 }
當需要可以修改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()內部的回調函數的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']
產生的結果為數組,如果想要返回對象則使用mapObjet - 當集合的所有元素都滿足條件時,.every()函數返回true,當集合的至少一個元素滿足條件時,.some()函數返回true:
_.every([1, 4, 7, -3, -9], (x) => x > 0); // false _.some([1, 4, 7, -3, -9], (x) => x > 0); // true
- max / min這兩個函數直接返回集合中最大和最小的數
- groupBy()把集合的元素按照key歸類,key由傳入的函數返回,用來分組是非常方便
- shuffle()用洗牌算法隨機打亂一個集合,sample()則是隨機選擇一個或多個元素.
2.對array
- first / last顧名思義,這兩個函數分別取第一個和最后一個元素。
- flatten()接收一個Array,無論這個Array里面嵌套了多少個Array,flatten()最后都把它們變成一個一維數組。
- zip()把兩個或多個數組的所有元素按索引對齊,然后按索引合并成新組。例如,你有一個Array保存了名字,另一個Array保存了分數,現在,要把名字和分數給對上,用zip()輕松實現,unzip()則是反過來。
- object()類似zip(),把名字和分數直接對應成Object。
- range()讓你快速生成一個序列,不再需要用for循環實現了
_.range(從幾開始, 大于或小于幾, 步長);