精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
js筆記合集

基礎(chǔ)篇

—————————————————————————————————————————————————

history:

用來控制網(wǎng)頁前進和后退,根據(jù)的是網(wǎng)頁歷史紀錄

history.back(); //后退
history.forward();//前進

無刷新更改URL:

history.pushState(data:json,title:string,url:string);// 會存儲在url歷史中
history.replaceState(data:json,title:string,url:string);// 不會存儲。。。
data是你要存放的數(shù)據(jù),可以使用history.state獲取,title是標題,為空則不改變,url是新url

location:

用來控制頁面跳轉(zhuǎn)
location.replace("xx");//跳轉(zhuǎn)
location.href = 'xxxx';//同上
location.reload();//刷新頁面

定時器:

  • var id = setInterval(callback,ms);//每隔ms毫秒執(zhí)行一次函數(shù)(回調(diào)函數(shù)只寫函數(shù)名)
  • var id = setTimeout(callback,ms);//在ms毫秒后執(zhí)行一次函數(shù)
  • clearInterval(timer);//清理掉setInterval定時器
  • clearTimeout(timeout);//讓setTimeout定時器失效
  • window.requestAnimationFrame(callBack);//專門為動畫設(shè)置的定時器(效果比setInterval流暢,每秒執(zhí)行60次,大部分瀏覽器中,每秒執(zhí)行次數(shù)和顯示器刷新率一致)

事件綁定的方法:

直接使用元素的onclick屬性:

<button onclick="btnhandler(this)"> click me </button>

綁定一個事件:

 

getElementById("xx").onclick = function(e){
    xxxxxxxx;
}

 

事件監(jiān)聽:

document.getElementById("xxx").addEventListener('click',function(e){
    xxxxxx;    
})

注意:事件名稱前不加on

區(qū)別:
使用內(nèi)聯(lián)onclick屬性似乎只能傳遞自身而不能傳遞事件對象
事件監(jiān)聽可以在一種事件上綁定多個方法

注意:
當元素是動態(tài)生成的時候,在元素生成前綁定的事件無效,如:

$('.btn').click(function (e){ ...... });
$('body’).append('<button class="btn">...</button>');    // 單擊事件不能綁定到新的元素上面

 

手動調(diào)用事件:

element.onclick() || element.onclick.call() ;
jquery方式:$(sel).click();

onchange當表單的值改變時觸發(fā)(需鼠標抬起,不是即時的)
oninput當表單控件受到改變時觸發(fā)(即時的)

 

事件對象:

事件對象自動傳遞給回調(diào)函數(shù) element.onclick = function(e){};// e就是事件對象
e的常見屬性:
e.target;//獲取觸發(fā)此事件的元素(不一定是綁定元素)
e.currentTarget//獲取觸發(fā)此事件的元素(一定是綁定元素)
e.offsetX ||e.offsetY ;//獲取鼠標基于target元素內(nèi)部的偏移x和y
e.clientX ||e.clientY ;//獲取鼠標基于瀏覽器視窗的偏移x和y
e.keyCode ||e.which;//返回鍵盤上的字符的代碼
事件回調(diào)中的this:指向事件的觸發(fā)元素

----如果事件處理函數(shù)的綁定在元素生成之前,則此元素不能綁定事件處理函數(shù),需重新設(shè)置


獲得和設(shè)置元素的行內(nèi)樣式(只針對行內(nèi)樣式):


var a = document.getElementById("xxx").style.width;
document.getElementById("xxx").style.width = '500px'//注意加上單位

獲得作用在元素身上的樣式:

原生方式:

element.currentStyle.width || getComputedStyle( element,null).width ;
前者是ie專用,后者是w3c標準,注意:用這種方法只能獲取不能設(shè)置

jquery 方式:

$(sel).css(styleName);// 注意數(shù)據(jù)類型以及單位
注:行內(nèi)樣式一定是起作用的樣式,所以用js設(shè)置元素樣式都是設(shè)置行內(nèi)樣式

 

js獲取元素位置及大小:

  • element.offsetTop;// 獲取元素相對于定位父元素(left,top屬性基于的元素)的頂部的距離
  • element.scrollTop// 元素的滾動距離(該元素需要有滾動條,如果沒有則為0)【可寫】
  • element.clientTop// 不常用

  // 使用變換(transform)不會改變上述屬性的值
  // 它們受left,top,margin等css屬性的影響,但不一定等于它們

  • element.offsetHeight// 元素的高度(包括邊框,滾動條),返回無單位的number值
  • element.clientHeight// 不包括邊框滾動條的高度,如果邊框無滾動條,則同上
  • element.scrollHeight// 如果有滾動條,則獲取滾動內(nèi)容的高度,沒有滾動條則同上【可寫】

  // 建議使用offsetHeight,因為其他元素排列位置時是會考慮邊框和滾動條的

  offsetParent// 用于定位的基元素(默認為最近的設(shè)置過position的父元素)


滾動動態(tài)加載內(nèi)容:

window.onscroll = function(e){    // 頁面滾動事件(一般加給window)
    // 頁面被卷起來的高度距離頂部或底部的距離
    var juan = document.documentElement.scrollTop;    // 獲取頁面被卷起來的高度,documentElement相當于html標簽
    var total = document.documentElement.scrollHeight;    // 獲取頁面總高度
    var visul = window.innerHeight;    // 獲取可見區(qū)的高度(即瀏覽器顯示出來的高度)
    var bot = total - juan - visul;    // bot就是可見區(qū)下面的高度(這是我們需要的)
    ........    // 當bot小于某值時,加載新元素
}

注:document的類型是Document,document.documentElement才是常規(guī)的Element類型的DOM元素
注:onscroll事件觸發(fā)次數(shù)比較頻繁,可以考慮節(jié)流(一段時間內(nèi)只執(zhí)行一次)

 

js實現(xiàn)拖動:


需要給被拖動元素和window同時添加mousemove事件,因為即使拖動時鼠標在元素之外,也應(yīng)該能實現(xiàn)拖動。
具體實現(xiàn):
1.鼠標按下目標元素時,存儲clientX,clientY,以及被拖動元素的引用
2.鼠標移動時,設(shè)置被拖動元素的left為當前clientX - 預(yù)先存儲的clientX,clientY同理
3.釋放鼠標時,清除之前存儲的數(shù)據(jù)

 

獲取body標簽對應(yīng)的DOM :document.body


獲取html標簽對應(yīng)的DOM :document.documentElement

 

圖片懶加載:

就是先不設(shè)置src,而是將路徑放到其他屬性中(如data-src),等到圖片處于顯示區(qū)或接近顯示區(qū)時,再設(shè)置src

HTML DOM事件在:http://www.runoob.com/jsref/dom-obj-event.html

 

右鍵點擊事件

oncontextmenu

 

表單綁定事件的考慮:

  • onkeydown// 按下按鍵時立即觸發(fā),該事件一般綁定在document/window上,因為即使被綁定的表單沒有獲得焦點,該事件也會執(zhí)行
  • onkeypress// 按下按鍵時立即觸發(fā),只有被綁定的元素獲得焦點了,才會執(zhí)行事件(適用于動態(tài)search)
  • onchange// 表單值改變時執(zhí)行,按下按鍵時不是立即觸發(fā),而是等到輸入完畢時才會觸發(fā)(輸入完畢指的是按下回車或表單失去焦點)
  • oninput// 表單值改變時立即觸發(fā)

實例:

window.keydown = function(e){    //鍵盤事件一般和窗口綁定
    var ev = window.event || e;    //獲得事件對象(IE和其他瀏覽器均可用)
    var word = String.fromCharCode(ev.keyCode);    //將ascii碼轉(zhuǎn)換成字符
    alert(word);
}

 

動畫事件:

  事件        描述

  • animationend 該事件在 CSS 動畫結(jié)束播放時觸發(fā)
  • animationiteration 該事件在 CSS 動畫重復(fù)播放時觸發(fā)
  • animationstart 該事件在 CSS 動畫開始播放時觸發(fā)
  • transitionend 該事件在 CSS 完成過渡后觸發(fā)。

  目前,需要根據(jù)瀏覽器種類加前綴

 

事件流:


當元素位置重疊的時候,點擊重疊的位置,每個元素的事件會按照一定的順序觸發(fā)。
若只想讓第一個事件觸發(fā),則可在那個事件的方法體中加入以下代碼:
e.stopPropagation();//中斷此次事件的后續(xù)操作
若顯示層級位于表層的元素沒有事件而里層元素有綁定事件,那么事件不會觸發(fā),因為事件流不是一個通路。這在給父元素加鼠標事件時很常用

事件相互影響的問題:
例如:如按空格讓視頻暫停,在文本框中輸入空格也可能會讓視頻暫停,這是因為事件冒泡到上級,只需要在文本框上的鍵盤事件上中斷事件流即可

事件委托:

例如,在一個ul中為要每個li設(shè)置點擊事件,只需給ul設(shè)置點擊事件即可,li的事件會冒泡至ul上,通過this|e.target獲取li的DOM對象

瀏覽器默認事件:
如:點擊a標簽后,瀏覽器會默認跳轉(zhuǎn)到指定頁面;點擊鼠標右鍵,會彈出上下文菜單等


阻止默認事件:

建立onclick事件方法,加入var ev=window.event; ev.preventDefault();

阻止a標簽的默認事件:

<a href="javascript:void(0)">鏈接</a>

 

在事件處理函數(shù)中this的用法:

this在事件處理函數(shù)中指向事件源對象(觸發(fā)事件的元素對象)
當元素被批量選中時,this指針對這些元素的事件處理非常有用
使用e.target也能獲取事件源對象// e表示事件對象
e.currentTarget表示最原始的觸發(fā)這個事件的對象(根據(jù)冒泡機制,只要條件符合,子元素也會觸發(fā)父元素身上的事件)

 

深入理解事件機制:


事件的傳遞分成三個階段:
PHASE1.捕獲:事件從祖先元素開始(從window開始)向內(nèi)傳遞
PHASE2.目標:事件已經(jīng)到達目標(最內(nèi)層的命中事件的元素)
PHASE3.冒泡:事件向外(祖先)冒泡至window
默認的偵聽器是偵聽冒泡階段的事件。

以點擊事件為例,鼠標點擊后,會從window對象開始,檢索其子對象的區(qū)域是否包含點擊點,html,body...直到某個元素的所有子元素的區(qū)域都不包含該點但自身包含該點,則此元素為目標元素,接著,從目標元素開始,依次執(zhí)行點擊事件回調(diào),直到window對象。

ClickHandler(window,new MouseEvent(x,y));

bool ClickHandler(DOM * dom, MouseEvent * e){

    List<DOM*> children = dom->children;
    bool hit = false;
    
    for(int i=0;i<children.length();i++){
        hit = ClickHandler(children[i],e) ;
        if(hit){
            e->phase = 3;
            e->currentTarget = children[i];
            dom->eventListener('click').call(e);
            return true;
        }
    }
    
    if(dom.area.include(e->x,e->y)){
        e->target = e->currentTarget = dom;
        e->phase = 2;
        dom->eventListener('click').call(e);
        return true;
    } else {
        return false;
    }
}

 

 

日期對象:

js中時間日期是以對象的形式實現(xiàn)的
var time = new Date();//獲得客戶端當前的時間,返回一堆字符串,還可以用時間戳構(gòu)造(注意:客戶端的時間可能是不準確的)
var time = new Date(年,月,日,時,分,秒);//創(chuàng)建一個具體的時間
方法:

  • getTime();//獲得從1970年1月1日到對象時間的毫秒數(shù)(時間戳)
  • get年月日時分秒的英文();//獲得對應(yīng)的時間橙分,如getDate()獲得日數(shù)
  • Date.now()返回毫秒級時間戳
  • toLocalDateTimeString()// 返回本地化的日期時間字符串(對于北京時間,會變成12小時制)

 

抽取字符串中的數(shù)字:

parseInt(str);// 會提取字符串中的整數(shù)部分,遇到非整數(shù)會立即停止提取;適合去掉css中的單位
parseFloat(str)// 同上,可以提取小數(shù)

Number.toFixed(n)// 保留n位小數(shù),為0則只保留整數(shù)
Number.round()// 返回最接近的整數(shù)(相當于四舍五入)
Number.floor()// 向小取整


定義一個匿名函數(shù),自動執(zhí)行:

(function (){
    //代碼塊
}());

或者

(function (){
    // 代碼塊
})();


可以在前面加上 ; 提升可靠性

 

常用DOM操作:

  • appendChild(e)// 尾插
  • insertBefore(e,ch)// 在子節(jié)點ch前插入e
  • removeChild(e)// 刪除子節(jié)點
  • replaceChild(new,old)// 替換子節(jié)點
  • ------------------------------------------------------
  • parentNode// 父節(jié)點
  • children// 子節(jié)點集合
  • childNodes// 子節(jié)點集合
  • firstChild// 第一個子節(jié)點
  • lastChild// 最后一個子節(jié)點
  • previousSibling// 前一個兄弟節(jié)點
  • nextSibling// 下一個兄弟節(jié)點
  • -------------------------------------------------------
  • setAttribute(name,value)// 設(shè)置元素的屬性
  • getAttribute(name)// 獲取屬性
  • hasAttribute(name)// 屬性是否存在
  • -------------------------------------------------------
  • dataset// 獲取以data-開頭的屬性(返回對象,只讀)
  • classList// 獲取類名(類數(shù)組對象,只讀)

 

jquery篇

—————————————————————————————————————————————————

獲取元素:

兄弟:$(sel).siblings(sel);
父級:$(sel).parent(sel);// 只能抓上一級
前輩:$(sel).parents(sel);// 可能是多個
第一個:$(sel).first();
第n個:$(sel).eq(n);
孩子:$(sel).chlidren(sel);// 注意只能抓下一級

取序號:$(sel).index();

 

迭代器:

$(sel).each(function (i,e)){    // i是序號,e是元素,只有一個參數(shù)時,表示序號
// 代碼
}

$.each(obj,function (i,e)){    // i是序號,e是元素,只有一個參數(shù)時,表示序號
// 代碼
}

 

注:js中數(shù)組API的回調(diào)函數(shù)通常是function(e,i){},即序號在后

 

DOM節(jié)點操作:

  • append('xxxx'); // 在節(jié)點文本后添加內(nèi)容,返回原來的jQuery對象,而不是添加的
  • appendTo(jQuery) // 將元素節(jié)點添加至指定jQuery對象的尾部
  • prepend('xxxx'); // 在節(jié)點文本前添加內(nèi)容,返回原來的jQuery對象,而不是添加的
  • before('xxxx'); // 在節(jié)點之前添加內(nèi)容(一般是新節(jié)點)
  • after('xxxx'); // 在節(jié)點之后添加內(nèi)容(一般是新節(jié)點)

關(guān)于表單元素:注意table標簽內(nèi)會自動加一個tbody標簽,獲取<tr>元素:$('table tbody tr');

 

jquery動畫:

hide(time,callback) show(...) fadeIn(...) fadeOut(...)
toggle動畫:toggle() toggleFade() toggleSlide() 指根據(jù)display來判斷做什么動畫

animate(json,timer,[timeFunc,callback]);
obj:格式是{attrName:styleValue, ...},表示元素要達到的樣式
timer:int類型,表示動畫的毫秒數(shù)
timeFunc:速度函數(shù),有ease,linear等
callback: 回調(diào)函數(shù)

 

獲取內(nèi)容:

html()// 獲取或設(shè)置innerHTML
text()// 獲取或設(shè)置innerTEXT,會自動轉(zhuǎn)義
val();// 獲取或設(shè)置value(只能用于表單)

 

獲取寬高和位置:

position();//獲取匹配元素相對父元素的偏移,返回的對象包含兩個整型屬性:top 和 left
height();
width();

返回數(shù)字,單位為px

 

jquery對象轉(zhuǎn)化為DOM元素對象:

jquery對象不能使用DOM對象的屬性和方法,jquery是對dom對象的封裝,使用jquery的0號元素即可獲得原來的DOM對象
$(sel)[0].setEventListener(....);

定義一個在頁面加載完成后立即執(zhí)行的函數(shù):

$(function (){
    // 函數(shù)體
});

 

 

高級篇

—————————————————————————————————————————————————

函數(shù)中的this:

指向主調(diào)對象,或者window,其值是在運行時可知的

 

函數(shù)對象和實例對象:

函數(shù)對象:即Function類型的對象
實例對象:new 函數(shù)名()后生成的對象

 

為函數(shù)對象添加方法:

function Foo(){
    this.func = function (){    // 這是為實例添加方法:var obj = new Foo(); obj.func()
      ...
    }

    function func(){    // 沒有為任何對象添加方法,該函數(shù)僅在foo內(nèi)部可用,這是錯的:foo.func() (×)
      ...
    }
}

Foo.func = function (){    // 這是為函數(shù)添加方法:foo.func()
  ...
}

 

js原型:

·所有函數(shù)都有prototype對象
·prototype對象是一個Object類型的對象
·該object對象中有一個constructor對象,指向該函數(shù)對象
·可以為prototype對象設(shè)置屬性,這些屬性實際是給實例對象訪問的

 

示例:

var func = function (){

}

var f = new func();

func.prototype.print = function (){
    console.log("print...");
}

f.print();    // 控制臺輸出print...

console.log(func.prototype.constructor === func)    // true

 

所有實例對象都有一個__proto__屬性,也是object類型的,該屬性和其函數(shù)原型(構(gòu)造函數(shù))的prototype屬性是一樣的,它們共享一份Object對象,即函數(shù)對象.prototype = 實例對象.__proto__,在上述例子中就是func.prototype === f.__proto__

使用對象屬性(或方法)時,先測試對象本身有無此方法,若沒有,則在__proto__中查找,直到找到,或不存在。這種查找鏈就是原型鏈(原型鏈使用的是__proto__而不是prototype)。

實例(接上例):
f.toString();
// func中無toString方法,其原型中也無,于是通過__proto__到Object的原型中找,在Object中找到了toString方法,。

 

Function和Object的原型:

·Function和Object是系統(tǒng)內(nèi)置的函數(shù)。
·所有函數(shù)對象都是Function類型的實例(通過new Function()得到)
·Object是內(nèi)置的函數(shù)對象,也是Function類型的實例對象
·Function也是函數(shù)對象,它也是Function類型的實例對象
由以上三點可知:
·所有的函數(shù)對象都有prototype和__proto__兩個屬性,有prototype是因為所有函數(shù)都有prototype對象,有__proto__是因為它是Function類型的實例
·所有函數(shù)對象的__proto__都等于Function對象的prototype,因為所有函數(shù)對象都是Function對象的實例
·Function對象的prototype和__proto__是相等的
·prototype和__proto__的類型是Object,而Object本身也有prototype和__proto__屬性,Object的__proto__屬性等于Function對象的prototype(前面說過),Object對象的prototype屬性中有很多內(nèi)置的方法:

  • constructor: Object()
  • hasOwnProperty: hasOwnProperty()
  • isPrototypeOf: isPrototypeOf()
  • toString: toString()
  • valueOf: valueOf()

Object對象的prototype屬性不是Object類型的,而且該屬性的__proto__屬性為null,它是原型鏈的終點。


恒成立(假設(shè)用戶定義了一個函數(shù)函數(shù),名為Func):

Func instanceof Function    // 因為Func.__proto__ == Function.prototype
Func instanceof Object    // 因為Func.__proto__.__proto__ == Object.prototype
Function instanceof Function    // 因為Function.__proto__ == Function.prototype
Object instanceof Function    // 因為Object.__proto__ == Function.prototype
Function instanceof Object    // 因為Function.__proto__.__proto__ == Object.prototype
Object instanceof Object // 因為Object.__proto__.__proto__ == Object.prototype

 

instanceof探幽:

L instanceof R當且僅當

L.__proto__......__proto__ === R.prototype

至少有一個__proto__

 

函數(shù)執(zhí)行上下文:

函數(shù)(或全局代碼)執(zhí)行前,會初始化上下文,包括:

  • 確定this
  • 變量提升:var定義的變量會在同級代碼執(zhí)行前先初始化為undefined
  • 函數(shù)提升:函數(shù)定義會在同級代碼執(zhí)行前先初始化
  • 變量提升先于函數(shù)提升

例:

function foo(){
    console.log(c)    // undefined
    var c = 1;
}

 

注:如果沒有定義變量,就直接使用,會在作用域鏈上查找,而不是在自身作用域上創(chuàng)建。
例1(以下是全局代碼):

function foo(){
    username = 'zhangshan';    
}

會設(shè)置window.username為'zhangshan',與函數(shù)中的this是誰無任何關(guān)系

 

例2:

function foo(){
    this.username = 'zhangshan';    
}

直接調(diào)用foo()時,效果同上(直接調(diào)用某個函數(shù)時,調(diào)用者一定是windows)


閉包:

js支持函數(shù)的嵌套定義,內(nèi)部的函數(shù)叫子函數(shù),外部的函數(shù)叫父函數(shù)。
當子函數(shù)引用了父函數(shù)中的變量,就會在子函數(shù)中產(chǎn)生一個閉包,包含了被引用的變量。
來看這個例子:

function foo(){
    var msg="hello";
    return function(){
        return msg + " world";
    }
}

var a = foo();
console.log(a());    // a能否正確使用msg?

foo()執(zhí)行完后,變量msg應(yīng)該被釋放,但是子函數(shù)引用了msg,產(chǎn)生了閉包,所以msg的生命周期變長,不會被釋放,所以執(zhí)行a()可以正確輸出msg的值。
產(chǎn)生閉包需要同時滿足:
1.存在函數(shù)嵌套
2.子函數(shù)中使用了父函數(shù)的變量
3.調(diào)用父函數(shù)


事件輪詢:

js是單線程的。
定時器回調(diào),DOM事件回調(diào),Ajax回調(diào)都會放在回調(diào)隊列中,待程序順序執(zhí)行完畢時,才會執(zhí)行。
注:并不是回調(diào)都是異步任務(wù),比如Promise()的參數(shù)function會同步執(zhí)行

 

Object對象:

Object.create(obj,[property])
//使用指定對象作為__proto__產(chǎn)生一個新對象。


Object.defineProperty(obj,propname,conf)
// 給obj定義屬性propname,conf為配置項。
// 該函數(shù)可以監(jiān)視某個對象的改變,這是很多MVVM框架實現(xiàn)數(shù)據(jù)綁定的原理


Object.assign(target,source);
// 復(fù)制source的所有屬性到target并返回


詳詢:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object

 

Function對象:

Function.property.call(obj,param);
Function.property.apply(obj,[params]);
Function.property.bind(obj,param);

//均是 給函數(shù)指定this,其中bind不會執(zhí)行,而是返回該函數(shù)。

 

new探幽:

使用某個構(gòu)造函數(shù)new一個對象A實際上就是設(shè)置對象A的__proto__為構(gòu)造函數(shù)的prototype,然后將this設(shè)置為A來執(zhí)行構(gòu)造函數(shù)。
手動實現(xiàn)new的方式:

function NEW(f){    // f為構(gòu)造函數(shù)

    var obj = Object.create(f.prototype);
    f.call(obj);

    return obj;
}

 

函數(shù)對象賦值注意:

var $ = document.querySelector;
$(...)    // Illegal invocation

原因: document.querySelector()的this是document而$()的this是不確定的.
解決:var $ = document.querySelector.bind(document);

 

與或運算符、相等性:

如果某個變量(或表達式的結(jié)果)的值為undefined,null,'',0,false,則為假值,非上述值則為真值
即js的假值有多種,但!假值都是true,同理真值有無數(shù)種,但!真值都是false
空對象{}和空數(shù)組[]為真值

js的與或運算(&&,||)并不產(chǎn)生true或false,而是:
在處理或運算時,返回第一個為真的值,若全為假,則返回最后一個假值
在處理與運算時,返回第一個為假的值,若全為真,則返回最后一個真值
在處理非運算時,一定返回true或false

關(guān)于相等性的研究請參考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Equality_comparisons_and_sameness

例:
var obj = createSomething() || {};// 若createSomething()返回假值,則將obj初始化為{}

例(將雙等==改成全等===的結(jié)果也是一樣的):

[undefined] == [undefined]    // false,實際上無論數(shù)組里面是什么,該表達式始終返回false
undefined == false    // false
undefined || false    // false
!undefined == true    // true
undefined && false    // undefined
false && undefined    // false
undefined || null    // null
'11.000' == 11    // true

 

ES6:

let關(guān)鍵字:

和var一樣,定義變量,區(qū)別是:
1.支持塊級作用域
2.不能變量提升

 

const關(guān)鍵字:

定義常量,不能修改

 

解構(gòu)賦值:(假定obj為 {name:'zhangshan',age:20})

例1:

let {name,age} = {'zhangshan',15}    // 創(chuàng)建name,age兩個對象并依次賦值
let {name,age} = obj    // 創(chuàng)建name,age兩個變量,并按obj中的字段名賦值
let [a,b,c] = [1,2,3]    // 創(chuàng)建a,b,c三個變量,按索引號賦值

 

例2:

function foo({name,age}){....}    // 同第二個,按字段名賦值
foo(obj)

 

字串模板:

使用``包含,并使用${name}標記變量,自動拼接。

var str = `我叫${obj.name},今年${obj.age}歲`;

 

對象內(nèi)的屬性和方法可以簡略:

let obj = {
    name,    // 直接將外部作用于的name賦給它,下同
    age,
    setName(name){    // 相當于function setName(name){}
        this.name = name
    }
}

 

數(shù)組/對象の賦值(使用...):

let a1 = ['a','b','c'];
let a2 = [...a1];
let a3 = [...a2,...a1];
let o1 = {a:123,b:456};
let o2 = {...o1}

 

可變參數(shù)(rest):

function foo(...value);    // value會變成參數(shù)數(shù)組
function foo(arg1,...value);    // value會變成除arg外的參數(shù)數(shù)組

 

...運算符:

...expression  // 如果...后接一個可迭代對象,則此語句的作用是將該對象的所有可迭代屬性變成當前對象內(nèi)的屬性

例:

var obj = {

  ...func();

}

 

如果func()函數(shù)返回一個可迭代對象,則上述語句表示將func()返回的對象中的所有屬性變成obj的

 

默認參數(shù):

function point(x = 0,y = 0){

};

 

箭頭函數(shù)(lambda):

let foo = (params)=>{
  statment;
}

foo(123);
注:lambda表達式中的this為它所在作用域中的this,且不能用call()更改,而一般函數(shù)的this需要在運行時確定.
當只有一個參數(shù)和一行語句時可簡略:param => expression;

 

雙箭頭:

let bar = param1 =>param2 => { statment;}

表示外層的箭頭函數(shù)的返回值是一個函數(shù)對象,也就是內(nèi)層的箭頭函數(shù)
即執(zhí)行bar()會得到內(nèi)層的函數(shù)對象

 

iterator和for...of:

for...of語句可以遍歷實現(xiàn)了Iterator接口的對象(可迭代對象)。
例:

let arr = [2,3,4,5,5,6];
for(let e of arr){
// using e;
}

數(shù)組,偽數(shù)組(類數(shù)組),set,map實現(xiàn)了Iterator接口,Object沒有實現(xiàn)該接口,但可以手動實現(xiàn)。
手動實現(xiàn)Iterator的方式:需要實現(xiàn)next方法,該方法返回此格式的對象{value:dataType,done:boolean},value是元素的值,done表示是否是最后一個元素

let it = Symbol.iterator;
Object.prototype[it] = function (){
    let next = ()=>{
        return {value:....,done:....}
    }
    return {next};
}

 

注:使用for...in也可以迭代Object對象,使用Object.keys(obj)可獲取對象的key數(shù)組

promise:

是一種異步操作的解決方案,假設(shè)op1()和op2()是異步操作(回調(diào)函數(shù)),op2()需要依賴op1()先執(zhí)行。則op1和op2不能順序執(zhí)行,op2應(yīng)該位于op1的函數(shù)體中,如下例:

setTimeout(function op1(){
    // do something...
    setTimeout(function op2(){
        // do something...
    },2000);

},2000);

 

如果回調(diào)層數(shù)過多,則會給編程帶來很大麻煩。使用promise解決方法如下:


// 定時器1的業(yè)務(wù)代碼

function func1(){
    console.log('func1 do something');
}

 


// 定時器2的業(yè)務(wù)代碼

function func2(){
    console.log('func2 do something');
}

 

function timeoutTask(timeoutFunc,delay){
// 返回一個Promise對象,其初始化參數(shù)為一執(zhí)行體(函數(shù)),倆參數(shù)分別表示執(zhí)行成功和失敗
    return new Promise((success,error)=>{

        setTimeout(function (){
            timeoutFunc();
            success();    // 執(zhí)行成功
        },delay);

    })
}

 

// then方法接收兩個執(zhí)行體,分別對應(yīng)上一步執(zhí)行成功和失敗的回調(diào),then方法可以鏈式調(diào)用

timeoutTask(func1,2000).then(()=>timeoutTask(func2,2000),null);

 

async和await關(guān)鍵字:

是最常用異步操作的解決方案, async是配合promise使用的。
await后可以跟一個promise對象,只有promise對象resolve了,此表達式才會向下執(zhí)行
實例:Ajax異步獲取用戶個人信息,和用戶的文件列表,而且獲取文件列表的前提是已獲取用戶信息。

(async function (){    // 使用async修飾函數(shù)
    let user = await getUser(123);    // 只有await關(guān)鍵字后的Promise對象為resolve狀態(tài),才會向下執(zhí)行,await表達式會返回resolve()的參數(shù)(即promiseValue)
    let files = await getFiles(user);
    // use files data...

})();    // 若不手動返回promise對象,async函數(shù)會強制返回一個promise對象,原本的返回值會作為promiseValue

await只能用在async塊中。

 

class關(guān)鍵字:

定義類

class Foo{
    static msg = "Foo class";    // 靜態(tài)屬性
    static getMsg = () => msg;    // 靜態(tài)方法
    constructor(){    // 構(gòu)造函數(shù)
        this.name = 'foo';
    }
    setName(name){    // 普通函數(shù)
        this.name = name
    }
}

 

在類定義中的普通函數(shù)會自動原型化,再也不用手動操作原型了;靜態(tài)屬性相當于直接在類對象(非實例對象)本身添加

const foo = new Foo();
foo.setName('bar');    // ok
Foo.setName('bar'); // Foo.setName is not a function
Foo.msg = 'abc class';    // ok
foo.getMsg();    // foo.getMsg is not a function

 

extends繼承:

class Bar extends Foo {

}

 

機制幾乎和Java一模一樣;
支持super();

 

淺復(fù)制和深復(fù)制:

淺復(fù)制:一層復(fù)制,復(fù)制單層元素的值
深復(fù)制:多層遞歸復(fù)制


注:只有進行了成員復(fù)制才能算拷貝,一般的對象間賦值只是指針的傳遞,根本不算拷貝。
例:

let a = [1,{name:"zhangshan"}];
let b = a.concat();    // concat是淺復(fù)制
b[0] = 2;
b[1].name:"lishi";
console.log(a);    // [1, {name: "lishi"}]


注:concat是淺復(fù)制,分別復(fù)制每一個元素的值,對于值類型的元素,復(fù)制其值,對于對象,復(fù)制其地址。
深復(fù)制的實現(xiàn):

function deepCopy(data){
   let ret;

    if(data instanceof Array){
        ret = [];
    } else if(data instanceof Object){
        ret = {};
    } else {
        return data;
    }

    for(let i in data){    // i為key或索引,如果是for...of,則i為值
        ret[i] = deepCopy(data[i]);

    }

    return ret;
}

 

使用JSON也可實現(xiàn)深復(fù)制

 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JS事件之自建函數(shù)bind()與兼容性問題解決
Python中的內(nèi)置函數(shù)大全
深入理解javascript原型和閉包(4)
37道WEB前端開發(fā)面試題之JavaScript篇章!
javascript快速入門17
this解讀 js javascript
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服

主站蜘蛛池模板: 云阳县| 铁岭市| 临安市| 将乐县| 腾冲县| 辉县市| 军事| 濮阳县| 沧州市| 潮州市| 怀来县| 和田市| 韩城市| 洮南市| 高尔夫| 福安市| 拜城县| 通辽市| 信阳市| 吉隆县| 锡林郭勒盟| 林芝县| 绍兴县| 成都市| 信阳市| 邓州市| 卢氏县| 虞城县| 含山县| 淅川县| 宾川县| 芦溪县| 永州市| 临桂县| 松潘县| 察隅县| 柳州市| 宜兴市| 大丰市| 闵行区| 休宁县|