參考自: https://www.liaoxuefeng.com/wiki/1022910821149312/1023024358748480
個人簡單總結(jié), 加入自己理解
基礎語法
字符串
常用方法
toUpperCase()
toLowerCase()
indexOf()
-
substring()
返回指定區(qū)間字符串,
一個參數(shù)表示結(jié)束位置, 兩個參數(shù)第一個表示開始第二個表示結(jié)束
var s = 'hello, world' s.substring(0, 5); // 從索引0開始到5(不包括5)邻眷,返回'hello' s.substring(7); // 從索引7開始到結(jié)束惩坑,返回'world'
數(shù)組
常用的方法
indexOf() 查找元素指定位置
-
slice() 它截取
Array
的部分元素,然后返回一個新的Array
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G']; arr.slice(0, 3); // 從索引0開始,到索引3結(jié)束动雹,但不包括索引3: ['A', 'B', 'C'] arr.slice(3); // 從索引3開始到結(jié)束: ['D', 'E', 'F', 'G']
-
sort排序 遞增, 可以自定義
arrInt = arrInt.sort(function (a, b) { return b - a; // 后面比前面大的時候就要交換, 也就是從 大 ==> 小 })
reverse反轉(zhuǎn)數(shù)組
-
splice()
刪除添加函數(shù),最厲害的
, 三個參數(shù)(開始位置, 刪除個數(shù), 添加的值)其中添加的值可以有很多個
-
concat 數(shù)組拼接
注意,
concat()
方法并沒有修改當前Array
案疲,而是返回了一個新的Array
扛拨。返回的數(shù)組是一維的
-
join 把當前
Array
的每個元素都用指定的字符串連接起來,然后返回連接后的字符串返回的是連接后的字符串
pop和push
-
unshift和shift 是隊列用的
- unshift 隊頭添加
- shift 隊尾巴添加
對象
的常用方法
-
循環(huán)查看對象, 用for…in...
var o = { name: 'Jack', age: 20, city: 'Beijing' }; for (var key in o) { console.log(key); // 'name', 'age', 'city' }
要過濾掉對象繼承的屬性葱弟,用
hasOwnProperty()
來實現(xiàn):if (o.hasOwnProperty(key)) {}
注意壹店,
for ... in
對Array
的循環(huán)得到的是String
而不是Number
。var a = ['A', 'B', 'C']; for (var i in a) { console.log(i); // '0', '1', '2' console.log(a[i]); // 'A', 'B', 'C' }
也即是下標是字符串
-
map
: JavaScript的對象中, 鍵必須是字符串芝加。但實際上Number或者其他數(shù)據(jù)類型作為鍵也是非常合理的硅卢。為了解決這個問題,最新的ES6規(guī)范引入了新的數(shù)據(jù)類型Map,鍵可以是任意類型
var m = new Map(); // 空Map m.set('Adam', 67); // 添加新的key-value m.set('Bob', 59); m.has('Adam'); // 是否存在key 'Adam': true m.get('Adam'); // 67 m.delete('Adam'); // 刪除key 'Adam' m.get('Adam'); // undefined
-
set
: Set和Map類似藏杖,也是一組key的集合将塑,但不存儲value
。由于key不能重復
蝌麸,所以点寥,在Set中,沒有重復的key来吩。需要提供一個Array
作為輸入敢辩,或者直接創(chuàng)建一個空Set
Set
與Array
類似蔽莱,但Set
沒有索引var s1 = new Set(); // 空Set var s2 = new Set([1, 2, 3]); // 含1, 2, 3 s.add(4);// Set {1, 2, 3, 4} s.add(4); // 仍然是 Set {1, 2, 3, 4} var s = new Set([1, 2, 3]);// Set {1, 2, 3} s.delete(3); // Set {1, 2}
iterable
循環(huán)遍歷數(shù)組, map和set
使用for ... of
循環(huán)來遍歷。for ... of
循環(huán)是ES6引入的新的語法
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍歷Array
console.log(x);
}
for (var x of s) { // 遍歷Set
console.log(x);
}
for (var x of m) { // 遍歷Map
console.log(x[0] + '=' + x[1]); // 第一個是鍵, 第二個是值
}
for ... in
循環(huán)遍歷的實際上是對象的屬性名稱var a = ['A', 'B', 'C']; a.name = 'Hello'; for (var x in a) { console.log(x); // '0', '1', '2', 'name' }
for ... of
循環(huán)則完全修復了這些問題戚长,它只循環(huán)集合本身的元素:var a = ['A', 'B', 'C']; a.name = 'Hello'; for (var x of a) { console.log(x); // 'A', 'B', 'C' }
forEach
foEach沒有返回值
Set
與Array
類似盗冷,但Set
沒有索引,因此回調(diào)函數(shù)的前兩個參數(shù)都是元素本身:
var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
console.log(element);
});
Map
的回調(diào)函數(shù)參數(shù)依次為value
历葛、key
和map
本身:
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
console.log(value);
});
JavaScript的函數(shù)調(diào)用不要求參數(shù)必須一致正塌,因此可以忽略它們。例如恤溶,只需要獲得Array
的element
var a = ['A', 'B', 'C'];
a.forEach(function (element) {
console.log(element);
});
函數(shù)
函數(shù)參數(shù)arguments
代表實際傳入的參數(shù), 可以當做一個數(shù)組來取用, 但是它不是數(shù)組
function abs() {
if (arguments.length === 0) {
return 0;
}
var x = arguments[0];
return x >= 0 ? x : -x;
}
函數(shù)參數(shù)rest
代表, 比如我寫了兩個參數(shù), 但是傳入進來了5個, 那么多出來的三個就是rest, 寫法如下:
function foo(a, b, ...rest) {
console.log(rest);
}
JavaScript的作用域是函數(shù)作用域, 也即是函數(shù)內(nèi)部的變量不影響外部, 隔離開了
但是內(nèi)部可以訪問上級的變量. 冒泡向上找
變量提升
定義在函數(shù)內(nèi)部的變量, 會被先提前聲明到最頂部, 執(zhí)行函數(shù)前會先掃描一遍函數(shù)內(nèi)部
如果不寫變量聲明就會被綁定到全局作用域, 綁定到window下
foo = 'A`; // 沒有寫var或let就被當做是全局作用域下的屬性
解構(gòu)賦值
var x=1, y=2;
[x, y] = [y, x]
es6內(nèi)部可以用解構(gòu)賦值
, 來進行多變量賦值
var person = {
name: '小明',
age: 20,
address: {
city: 'Beijing',
street: 'No.1 Road',
zip: '100001'
}
};
var {name, address: {city, zip}} = person;
let [, , z] = ['hello', 'JavaScript', 'ES6']; // 忽略前兩個元素乓诽,只對z賦值第三個元素
有些時候,如果變量已經(jīng)被聲明了咒程,再次賦值的時候鸠天,正確的寫法也會報語法錯誤:
// 聲明變量:
var x, y;
// 解構(gòu)賦值:
{x, y} = { name: '小明', x: 100, y: 200};
// 語法錯誤: Uncaught SyntaxError: Unexpected token =
這是因為JavaScript引擎把{
開頭的語句當作了塊處理,于是=
不再合法帐姻。解決方法是用小括號括起來:
({x, y} = { name: '小明', x: 100, y: 200});
apply和call
Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5
-
apply
第二個參數(shù)是數(shù)組把參數(shù)打包成
Array
再傳入對普通函數(shù)調(diào)用我們通常把
this
綁定為null
稠集。JavaScript的所有對象都是動態(tài)的,即使內(nèi)置的函數(shù)饥瓷,我們也可以重新指向新的函數(shù)剥纷。
現(xiàn)在假定我們想統(tǒng)計一下代碼一共調(diào)用了多少次
parseInt()
,可以把所有的調(diào)用都找出來呢铆,然后手動加上count += 1
晦鞋,不過這樣做太傻了。最佳方案是用我們自己的函數(shù)替換掉默認的parseInt()
var count = 0; var oldParseInt = parseInt; // 保存原函數(shù) window.parseInt = function () { count += 1; return oldParseInt.apply(null, arguments); // 調(diào)用原函數(shù) };
// 測試: parseInt('10'); parseInt('20'); parseInt('30'); console.log('count = ' + count); // 3
call()
把參數(shù)按順序傳入
高階函數(shù)
map/reduce
-
map映射
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9'] arr.map((item)=>{ return parseInt(item) });
-
reduce
reduce()
把結(jié)果繼續(xù)和序列的下一個元素做累積計算var arr = [1, 3, 5, 7, 9]; arr.reduce(function (x, y) { return x + y; }); // 25
filter
filter是用于過濾
var arr = ['A', '', 'B', null, undefined, 'C', ' '];
var r = arr.filter(function (s) {
return s && s.trim(); // 注意:IE9以下的版本沒有trim()方法,
// trim()刪除頭尾空白字符, 這里刪了就變空了就返回false
});
r; // ['A', 'B', 'C']
filter()
接收的回調(diào)函數(shù)棺克,其實可以有多個參數(shù)悠垛。通常我們僅使用第一個參數(shù),表示Array
的某個元素娜谊。
也可以接受另外兩個參數(shù), 表示元素的位置和數(shù)組本身:
var arr = ['A', 'B', 'C'];
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;
});
sort
var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
if (x < y) {
return -1; // 表示x排在y左邊
}
if (x > y) {
return 1; // 表示x排在y右邊
}
return 0; // 表示順序不變
});
console.log(arr); // [1, 2, 10, 20]
Array本身有很多高階函數(shù)
-
every() 判斷所有元素是否符合測試條件, 接受一個參數(shù), 是就返回true
var arr = ['Apple', 'pear', 'orange']; console.log(arr.every(function (s) { return s.toLowerCase() === s; })); // false, 因為不是每個元素都全部是小寫
-
find() 查找符合條件的第一個元素确买,如果找到了,返回這個元素纱皆,否則湾趾,返回
undefined
var arr = ['Apple', 'pear', 'orange']; console.log(arr.find(function (s) { return s.toLowerCase() === s; })); // 'pear', 因為pear全部是小寫
findIndex() 和find類似, 不過返回的是索引罷了
forEach()和map()類似, 但是不會返回數(shù)組, 常用于遍歷數(shù)組
參數(shù)為
(值, 下標, 數(shù)組)
閉包
因為JavaScript是函數(shù)內(nèi)作用域
利用這一點可以在函數(shù)內(nèi)建立函數(shù)來進行
并且他的作用域是冒泡形式向上的
參考: https://segmentfault.com/a/1190000002778015
閉包的定義
- 可以訪問外部函數(shù)作用域中變量的
函數(shù)
-
被內(nèi)部函數(shù)訪問的外部函數(shù)的變量可以保存在外部函數(shù)作用域內(nèi)而不被回收---這是核心
,后面我們遇到閉包都要想到派草,我們要重點關注被閉包引用的這個變量撑帖。
閉包例子:
var person= function(){
//變量作用域為函數(shù)內(nèi)部,外部無法訪問
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}();
console.log(person.name);//直接訪問澳眷,結(jié)果為undefined
console.log(person.getName()); //default
person.setName("jozo");
console.log(person.getName()); //jozo
閉包作用
- 可以讀取外部函數(shù)的變量, 并且讓這些
變量保持在內(nèi)存中
例如給每個li添加點擊事件
var oli = document.getElementsByTagName('li');
var i;
for(i = 0;i < 5;i++){
oli[i].onclick = function(){
alert(i);
}
}
console.log(i); // 5
//執(zhí)行匿名函數(shù)
(function(){
alert(i); //5
}());
上面是一個經(jīng)典的例子胡嘿,是沒有用到閉包
, 我們都知道點擊執(zhí)行結(jié)果是都彈出5, 可以用閉包解決這個問題
a. 先來分析沒用閉包前
的情況:for循環(huán)中,我們給每個li點擊事件綁定了一個匿名函數(shù)
,匿名函數(shù)中返回了變量i的值钳踊,當循環(huán)結(jié)束后衷敌,變量i的值變?yōu)?勿侯,此時我們再去點擊每個li,也就是執(zhí)行相應的匿名函數(shù)
(看上面的代碼)缴罗,這是變量i已經(jīng)是5了助琐,所以每個點擊彈出5. 因為這里返回的每個匿名函數(shù)都是引用了同一個變量i,如果我們新建一個變量保存循環(huán)執(zhí)行時當前的i的值面氓,然后再讓匿名函數(shù)應用這個變量兵钮,最后再返回這個匿名函數(shù),這樣就可以達到我們的目的了舌界,這就是運用閉包來實現(xiàn)的掘譬!
b. 再來分析下運用閉包時的情況:
var oli = document.getElementsByTagName('li');
var i;
for(i = 0;i < 5;i++){
oli[i].onclick = (function(num){
var a = num; // 為了說明問題
return function(){
alert(a);
}
})(i)
}
console.log(i); // 5
這里for循環(huán)執(zhí)行時,給點擊事件綁定的匿名函數(shù)傳遞i后立即執(zhí)行返回一個內(nèi)部的匿名函數(shù)呻拌,因為參數(shù)是按值傳遞的葱轩,所以此時形參num保存的就是當前i的值
,然后賦值給局部變量 a,然后這個內(nèi)部的匿名函數(shù)一直保存著a的引用
藐握,也就是一直保存著當前i的值靴拱。 所以循環(huán)執(zhí)行完畢后點擊每個li,返回的匿名函數(shù)執(zhí)行彈出各自保存的 a 的引用的值
猾普。
可以避免命名重復全局污染問題, 也就是說命名可以和全局名字一樣, 但是他們互不影響的
-
要訪問函數(shù)內(nèi)部變量就可以用閉包來實現(xiàn)
function f1(){ var n=999; function f2(){ alert(n); // 999 } return f2; }
缺點
閉包會常駐內(nèi)存, 會增大內(nèi)存使用, 使用不當就會有內(nèi)存泄漏
generator
生成器
就是使用yield可以類似中斷一樣, 通過調(diào)用下一步來運行
function* fib(max) {
var
t,
a = 0,
b = 1,
n = 0;
while (n < max) {
yield a;
[a, b] = [b, a + b];
n ++;
}
return;
}
var f = fib(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: false}
f.next(); // {value: undefined, done: true}
標準對象
data
對象
JavaScript的Date對象月份值從0開始袜炕,牢記0=1月,1=2月初家,2=3月偎窘,……,11=12月
獲取系統(tǒng)當前時間
var now = new Date();
now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
now.getFullYear(); // 2015, 年份
now.getMonth(); // 5, 月份笤成,注意月份范圍是0~11,5表示六月
now.getDate(); // 24, 表示24號
now.getDay(); // 3, 表示星期三
now.getHours(); // 19, 24小時制
now.getMinutes(); // 49, 分鐘
now.getSeconds(); // 22, 秒
now.getMilliseconds(); // 875, 毫秒數(shù)
now.getTime(); // 1435146562875, 以number形式表示的時間戳
RegExp
正則匹配, 可以用new RegExp()創(chuàng)建正則
var re = /ABC\-001/;
var re = new RegExp('ABC\\-001');
re.test(字符);
切分字符串
'a,b;; c d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']
分組, 可以用exec()
方法提取出子串
var re = /^(\d{3})-(\d{3,8})$/;
re.exec('010-12345'); // ['010-12345', '010', '12345']
JSON
json字符串轉(zhuǎn)為json對象
var obj = eval('('+str+')');
var obj = str.parseJSON();
var obj = JSON.parse(str);
json對象轉(zhuǎn)為json字符串
var str = obj.toJSONString();
var str = JSON.stringify(obj);
面向?qū)ο缶幊?/h2>
關于JavaScript繼承可以看我的文章:
http://www.reibang.com/p/70e86e2d2636
瀏覽器對象
window
window
對象有innerWidth
和innerHeight
屬性眷茁,可以獲取瀏覽器窗口的內(nèi)部寬度和高度炕泳。內(nèi)部寬高是指除去菜單欄、工具欄上祈、邊框等占位元素后培遵,用于顯示網(wǎng)頁的凈寬高。
navigator
- navigator.appName:瀏覽器名稱登刺;
- navigator.appVersion:瀏覽器版本籽腕;
- navigator.language:瀏覽器設置的語言;
- navigator.platform:操作系統(tǒng)類型纸俭;
- navigator.userAgent:瀏覽器設定的
User-Agent
字符串皇耗。
screen
- screen.width:屏幕寬度,以像素為單位揍很;
- screen.height:屏幕高度郎楼,以像素為單位万伤;
- screen.colorDepth:返回顏色位數(shù),如8呜袁、16敌买、24。
location
location.protocol; // 'http'
location.host; // 'www.example.com'
location.port; // '8080'
location.pathname; // '/path/index.html'
location.search; // '?a=1&b=2'
location.hash; // 'TOP'
DOM操作
常見的dom操作
添加節(jié)點
document.creatElement()
div.appendChild()
獲取父元素
div.appendChild()
獲取子元素
div.childNodes()
刪除節(jié)點
div.removeChild()
promise
Promise().then().then....catch() 多任務串行執(zhí)行.
Promise.all([p1,p2,...]) 多任務并行執(zhí)行
都要成功才進入then,返回結(jié)果數(shù)組.
Promise.race([p1,p2,...]) 多任務賽跑.
then()和catch(),誰先調(diào)用算誰的,其它任務中斷.