JavaScript基礎部分總結(jié)

參考自: 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 ... inArray的循環(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

    SetArray類似蔽莱,但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沒有返回值

SetArray類似盗冷,但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历葛、keymap本身:

var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
    console.log(value);
});

JavaScript的函數(shù)調(diào)用不要求參數(shù)必須一致正塌,因此可以忽略它們。例如恤溶,只需要獲得Arrayelement

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映射

    image-20190529111656949
    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

閉包的定義

  1. 可以訪問外部函數(shù)作用域中變量的函數(shù)
  2. 被內(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

閉包作用

  1. 可以讀取外部函數(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 的引用的值猾普。

  1. 可以避免命名重復全局污染問題, 也就是說命名可以和全局名字一樣, 但是他們互不影響的

  2. 要訪問函數(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對象有innerWidthinnerHeight屬性眷茁,可以獲取瀏覽器窗口的內(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)用算誰的,其它任務中斷.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阶界,一起剝皮案震驚了整個濱河市虹钮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌膘融,老刑警劉巖芙粱,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異托启,居然都是意外死亡宅倒,警方通過查閱死者的電腦和手機霸旗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門逮栅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缔俄,你說我怎么就攤上這事疗绣∠哒伲” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵多矮,是天一觀的道長缓淹。 經(jīng)常有香客問我,道長塔逃,這世上最難降的妖魔是什么讯壶? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮湾盗,結(jié)果婚禮上伏蚊,老公的妹妹穿的比我還像新娘。我一直安慰自己格粪,他們只是感情好躏吊,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著帐萎,像睡著了一般比伏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上疆导,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天赁项,我揣著相機與錄音,去河邊找鬼。 笑死肤舞,一個胖子當著我的面吹牛紫新,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播李剖,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼芒率,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了篙顺?” 一聲冷哼從身側(cè)響起偶芍,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎德玫,沒想到半個月后匪蟀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡宰僧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年材彪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琴儿。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡段化,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出造成,到底是詐尸還是另有隱情显熏,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布晒屎,位于F島的核電站喘蟆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鼓鲁。R本人自食惡果不足惜蕴轨,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望骇吭。 院中可真熱鬧橙弱,春花似錦、人聲如沸绵跷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碾局。三九已至,卻和暖如春奴艾,著一層夾襖步出監(jiān)牢的瞬間净当,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留像啼,地道東北人俘闯。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像忽冻,于是被迫代替她去往敵國和親真朗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345