主頁 > 企業開發 > js筆記合集

js筆記合集

2020-09-11 02:31:47 企業開發

基礎篇

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

history:

用來控制網頁前進和后退,根據的是網頁歷史紀錄

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

無重繪更改URL:

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

location:

用來控制頁面跳轉
location.replace("xx"); //跳轉
location.href = 'https://www.cnblogs.com/liedElxa/p/xxxx'; //同上
location.reload(); //重繪頁面

定時器:

  • var id = setInterval(callback,ms); //每隔ms毫秒執行一次函式(回呼函式只寫函式名)
  • var id = setTimeout(callback,ms); //在ms毫秒后執行一次函式
  • clearInterval(timer); //清理掉setInterval定時器
  • clearTimeout(timeout); //讓setTimeout定時器失效
  • window.requestAnimationFrame(callBack); //專門為影片設定的定時器(效果比setInterval流暢,每秒執行60次,大部分瀏覽器中,每秒執行次數和顯示幕重繪率一致)

事件系結的方法:

直接使用元素的onclick屬性:

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

系結一個事件:

 

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

 

事件監聽:

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

注意:事件名稱前不加on

區別:
使用行內onclick屬性似乎只能傳遞自身而不能傳遞事件物件
事件監聽可以在一種事件上系結多個方法

注意:
當元素是動態生成的時候,在元素生成前系結的事件無效,如:

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

 

手動呼叫事件:

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

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

 

事件物件:

事件物件自動傳遞給回呼函式 element.onclick = function(e){}; // e就是事件物件
e的常見屬性:
e.target; //獲取觸發此事件的元素(不一定是系結元素)
e.currentTarget //獲取觸發此事件的元素(一定是系結元素)
e.offsetX ||e.offsetY ; //獲取滑鼠基于target元素內部的偏移x和y
e.clientX ||e.clientY ; //獲取滑鼠基于瀏覽器視窗的偏移x和y
e.keyCode ||e.which; //回傳鍵盤上的字符的代碼
事件回呼中的this:指向事件的觸發元素

----如果事件處理函式的系結在元素生成之前,則此元素不能系結事件處理函式,需重新設定


獲得和設定元素的行內樣式(只針對行內樣式):


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

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

原生方式:

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

jquery 方式:

$(sel).css(styleName); // 注意資料型別以及單位
注:行內樣式一定是起作用的樣式,所以用js設定元素樣式都是設定行內樣式

 

js獲取元素位置及大小:

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

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

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

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

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


滾動動態加載內容:

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

注:document的型別是Document,document.documentElement才是常規的Element型別的DOM元素
注:onscroll事件觸發次數比較頻繁,可以考慮節流(一段時間內只執行一次)

 

js實作拖動:


需要給被拖動元素和window同時添加mousemove事件,因為即使拖動時滑鼠在元素之外,也應該能實作拖動,
具體實作:
1.滑鼠按下目標元素時,存盤clientX,clientY,以及被拖動元素的參考
2.滑鼠移動時,設定被拖動元素的left為當前clientX - 預先存盤的clientX,clientY同理
3.釋放滑鼠時,清除之前存盤的資料

 

獲取body標簽對應的DOM :document.body


獲取html標簽對應的DOM :document.documentElement

 

圖片懶加載:

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

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

 

右鍵點擊事件

oncontextmenu

 

表單系結事件的考慮:

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

實體:

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

 

影片事件:

  事件        描述

  • animationend 該事件在 CSS 影片結束播放時觸發
  • animationiteration 該事件在 CSS 影片重復播放時觸發
  • animationstart 該事件在 CSS 影片開始播放時觸發
  • transitionend 該事件在 CSS 完成過渡后觸發,

  目前,需要根據瀏覽器種類加前綴

 

事件流:


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

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

事件委托:

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

瀏覽器默認事件:
如:點擊a標簽后,瀏覽器會默認跳轉到指定頁面;點擊滑鼠右鍵,會彈出背景關系選單等


阻止默認事件:

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

阻止a標簽的默認事件:

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

 

在事件處理函式中this的用法:

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

 

深入理解事件機制:


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

以點擊事件為例,滑鼠點擊后,會從window物件開始,檢索其子物件的區域是否包含點擊點,html,body...直到某個元素的所有子元素的區域都不包含該點但自身包含該點,則此元素為目標元素,接著,從目標元素開始,依次執行點擊事件回呼,直到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中時間日期是以物件的形式實作的
var time = new Date(); //獲得客戶端當前的時間,回傳一堆字串,還可以用時間戳構造(注意:客戶端的時間可能是不準確的)
var time = new Date(年,月,日,時,分,秒); //創建一個具體的時間
方法:

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

 

抽取字串中的數字:

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

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


定義一個匿名函式,自動執行:

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

或者

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


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

 

常用DOM操作:

  • appendChild(e) // 尾插
  • insertBefore(e,ch) // 在子節點ch前插入e
  • removeChild(e) // 洗掉子節點
  • replaceChild(new,old) // 替換子節點
  • ------------------------------------------------------
  • parentNode // 父節點
  • children // 子節點集合
  • childNodes // 子節點集合
  • firstChild // 第一個子節點
  • lastChild // 最后一個子節點
  • previousSibling // 前一個兄弟節點
  • nextSibling // 下一個兄弟節點
  • -------------------------------------------------------
  • setAttribute(name,value) // 設定元素的屬性
  • getAttribute(name) // 獲取屬性
  • hasAttribute(name) // 屬性是否存在
  • -------------------------------------------------------
  • dataset // 獲取以data-開頭的屬性(回傳物件,只讀)
  • classList // 獲取類名(類陣列物件,只讀)

 

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是元素,只有一個引數時,表示序號
// 代碼
}

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

 

注:js中陣列API的回呼函式通常是function(e,i){},即序號在后

 

DOM節點操作:

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

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

 

jquery影片:

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

animate(json,timer,[timeFunc,callback]);
obj:格式是{attrName:styleValue, ...},表示元素要達到的樣式
timer:int型別,表示影片的毫秒數
timeFunc:速度函式,有ease,linear等
callback: 回呼函式

 

獲取內容:

html() // 獲取或設定innerHTML
text() // 獲取或設定innerTEXT,會自動轉義
val(); // 獲取或設定value(只能用于表單)

 

獲取寬高和位置:

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

回傳數字,單位為px

 

jquery物件轉化為DOM元素物件:

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

定義一個在頁面加載完成后立即執行的函式:

$(function (){
    // 函式體
});

 

 

高級篇

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

函式中的this:

指向主調物件,或者window,其值是在運行時可知的

 

函式物件和實體物件:

函式物件:即Function型別的物件
實體物件:new 函式名()后生成的物件

 

為函式物件添加方法:

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

    function func(){    // 沒有為任何物件添加方法,該函式僅在foo內部可用,這是錯的:foo.func() (×)
      ...
    }
}

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

 

js原型:

·所有函式都有prototype物件
·prototype物件是一個Object型別的物件
·該object物件中有一個constructor物件,指向該函式物件
·可以為prototype物件設定屬性,這些屬性實際是給實體物件訪問的

 

示例:

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型別的,該屬性和其函式原型(建構式)的prototype屬性是一樣的,它們共享一份Object物件,即函式物件.prototype = 實體物件.__proto__,在上述例子中就是func.prototype === f.__proto__

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

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

 

Function和Object的原型:

·Function和Object是系統內置的函式,
·所有函式物件都是Function型別的實體(通過new Function()得到)
·Object是內置的函式物件,也是Function型別的實體物件
·Function也是函式物件,它也是Function型別的實體物件
由以上三點可知:
·所有的函式物件都有prototype和__proto__兩個屬性,有prototype是因為所有函式都有prototype物件,有__proto__是因為它是Function型別的實體
·所有函式物件的__proto__都等于Function物件的prototype,因為所有函式物件都是Function物件的實體
·Function物件的prototype和__proto__是相等的
·prototype和__proto__的型別是Object,而Object本身也有prototype和__proto__屬性,Object的__proto__屬性等于Function物件的prototype(前面說過),Object物件的prototype屬性中有很多內置的方法:

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

Object物件的prototype屬性不是Object型別的,而且該屬性的__proto__屬性為null,它是原型鏈的終點,


恒成立(假設用戶定義了一個函數函式,名為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__

 

函式執行背景關系:

函式(或全域代碼)執行前,會初始化背景關系,包括:

  • 確定this
  • 變數提升:var定義的變數會在同級代碼執行前先初始化為undefined
  • 函式提升:函式定義會在同級代碼執行前先初始化
  • 變數提升先于函式提升

例:

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

 

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

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

會設定window.username為'zhangshan',與函式中的this是誰無任何關系

 

例2:

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

直接呼叫foo()時,效果同上(直接呼叫某個函式時,呼叫者一定是windows)


閉包:

js支持函式的嵌套定義,內部的函式叫子函式,外部的函式叫父函式,
當子函式參考了父函式中的變數,就會在子函式中產生一個閉包,包含了被參考的變數,
來看這個例子:

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

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

foo()執行完后,變數msg應該被釋放,但是子函式參考了msg,產生了閉包,所以msg的生命周期變長,不會被釋放,所以執行a()可以正確輸出msg的值,
產生閉包需要同時滿足:
1.存在函式嵌套
2.子函式中使用了父函式的變數
3.呼叫父函式


事件輪詢:

js是單執行緒的,
定時器回呼,DOM事件回呼,Ajax回呼都會放在回呼佇列中,待程式順序執行完畢時,才會執行,
注:并不是回呼都是異步任務,比如Promise()的引數function會同步執行

 

Object物件:

Object.create(obj,[property])
//使用指定物件作為__proto__產生一個新物件,


Object.defineProperty(obj,propname,conf)
// 給obj定義屬性propname,conf為配置項,
// 該函式可以監視某個物件的改變,這是很多MVVM框架實作資料系結的原理


Object.assign(target,source);
// 復制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);

//均是 給函式指定this,其中bind不會執行,而是回傳該函式,

 

new探幽:

使用某個建構式new一個物件A實際上就是設定物件A的__proto__為建構式的prototype,然后將this設定為A來執行建構式,
手動實作new的方式:

function NEW(f){    // f為建構式

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

    return obj;
}

 

函式物件賦值注意:

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

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

 

與或運算子、相等性:

如果某個變數(或運算式的結果)的值為undefined,null,'',0,false,則為假值,非上述值則為真值
即js的假值有多種,但!假值都是true,同理真值有無數種,但!真值都是false
空物件{}和空陣列[]為真值

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

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

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

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

[undefined] == [undefined]    // false,實際上無論陣列里面是什么,該運算式始侄訓傳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關鍵字:

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

 

const關鍵字:

定義常量,不能修改

 

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

例1:

let {name,age} = {'zhangshan',15}    // 創建name,age兩個物件并依次賦值
let {name,age} = obj    // 創建name,age兩個變數,并按obj中的欄位名賦值
let [a,b,c] = [1,2,3]    // 創建a,b,c三個變數,按索引號賦值

 

例2:

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

 

字串模板:

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

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

 

物件內的屬性和方法可以簡略:

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

 

陣列/物件の賦值(使用...):

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

 

可變引數(rest):

function foo(...value);    // value會變成引數陣列
function foo(arg1,...value);    // value會變成除arg外的引數陣列

 

...運算子:

...expression  // 如果...后接一個可迭代物件,則此陳述句的作用是將該物件的所有可迭代屬性變成當前物件內的屬性

例:

var obj = {

  ...func();

}

 

如果func()函式回傳一個可迭代物件,則上述陳述句表示將func()回傳的物件中的所有屬性變成obj的

 

默認引數:

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

};

 

箭頭函式(lambda):

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

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

 

雙箭頭:

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

表示外層的箭頭函式的回傳值是一個函式物件,也就是內層的箭頭函式
即執行bar()會得到內層的函式物件

 

iterator和for...of:

for...of陳述句可以遍歷實作了Iterator介面的物件(可迭代物件),
例:

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

陣列,偽陣列(類陣列),set,map實作了Iterator介面,Object沒有實作該介面,但可以手動實作,
手動實作Iterator的方式:需要實作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陣列

promise:

是一種異步操作的解決方案,假設op1()和op2()是異步操作(回呼函式),op2()需要依賴op1()先執行,則op1和op2不能順序執行,op2應該位于op1的函式體中,如下例:

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

},2000);

 

如果回呼層數過多,則會給編程帶來很大麻煩,使用promise解決方法如下:


// 定時器1的業務代碼

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

 


// 定時器2的業務代碼

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

 

function timeoutTask(timeoutFunc,delay){
// 回傳一個Promise物件,其初始化引數為一執行體(函式),倆引數分別表示執行成功和失敗
    return new Promise((success,error)=>{

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

    })
}

 

// then方法接收兩個執行體,分別對應上一步執行成功和失敗的回呼,then方法可以鏈式呼叫

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

 

async和await關鍵字:

是最常用異步操作的解決方案, async是配合promise使用的,
await后可以跟一個promise物件,只有promise物件resolve了,此運算式才會向下執行
實體:Ajax異步獲取用戶個人資訊,和用戶的檔案串列,而且獲取檔案串列的前提是已獲取用戶資訊,

(async function (){    // 使用async修飾函式
    let user = await getUser(123);    // 只有await關鍵字后的Promise物件為resolve狀態,才會向下執行,await運算式會回傳resolve()的引數(即promiseValue)
    let files = await getFiles(user);
    // use files data...

})();    // 若不手動回傳promise物件,async函式會強制回傳一個promise物件,原本的回傳值會作為promiseValue

await只能用在async塊中,

 

class關鍵字:

定義類

class Foo{
    static msg = "Foo class";    // 靜態屬性
    static getMsg = () => msg;    // 靜態方法
    constructor(){    // 建構式
        this.name = 'foo';
    }
    setName(name){    // 普通函式
        this.name = name
    }
}

 

在類定義中的普通函式會自動原型化,再也不用手動操作原型了;靜態屬性相當于直接在類物件(非實體物件)本身添加

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();

 

淺復制和深復制:

淺復制:一層復制,復制單層元素的值
深復制:多層遞回復制


注:只有進行了成員復制才能算拷貝,一般的物件間賦值只是指標的傳遞,根本不算拷貝,
例:

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


注:concat是淺復制,分別復制每一個元素的值,對于值型別的元素,復制其值,對于物件,復制其地址,
深復制的實作:

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也可實作深復制

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/4036.html

標籤:JavaScript

上一篇:layui彈窗點擊右上角關閉按鈕二次確認

下一篇:vue 首屏優化

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more