javascript中基礎但是很容易忽略的點

引言: 本篇文章主要總結了一些javascript中特別基礎的內容,主要涉及到DOM0級和DOM2級事件,事件流事件委託判斷變量的類型每次被問到,總是能想起一點,但是也總記不全,所以遇到這種情況的時候,就簡單的記錄一下.

DOM0級事件和DOM2級事件的區別

DOM0事件

  • 在標籤內寫onclick事件
  • 在js中寫onclick=function(){}函數
 
    
1
 
    
<input id= "myButton" type= "button" value= "Press Me" onclick= "console.log('thanks');" >
 
    
1
2
3
 
    
document.getElementById( "myButton").onclick = function () {
console.log( 'thanks');
}

刪除事件的方法是

 
    
1
 
    
btn.onclick = null;

DOM2級事件

監聽方法: 兩個方法用來添加和移除事件處理程序: addEventListener()和removeEventLister()
他們都有三個參數:

  • 事件名(如click);
  • 事件處理程序函數
  • true表示在捕獲階段調用,false在冒泡階段調用

addEventListener()可以爲元素添加多個處理程序函數,觸發時按照添加順序依次調用;removeEventLister()不能移除匿名添加的函數

DOM0級事件和DOM2級事件的區別

在一個標籤上綁定多個事件處理程序,DOM0級只能覆蓋,不會連續觸發,但是DOM2級事件就不會出現這樣的情況,它不會被覆蓋,而且會連續觸發

事件流

  • 事件冒泡: 事件開始時是從最具體的元素接受,然後逐級向上傳播: 比如點擊了div, div->body->html->Document
  • 事件捕獲: 和事件冒泡相反,從最外面的元素向下傳播: 比如同樣點擊了div: Document->html->body->div

事件流包括三個階段:事件捕獲階段、處於目標階段和事件冒泡階段。首先是事件捕獲階段;然後是實際的目標接收到事件。最後一個階段是冒泡階段,可以在這個階段對事件作出相應。
事件流
所有的瀏覽器都支持冒泡,我們通常使用事件冒泡,很少使用事件捕獲

事件委託(事件代理)及使用場景

事件委託原理:

事件冒泡

使用場景:

DOM需要事件處理程序,一般都是直接給她這種事件處理程序;但是有很多個DOM需要添加相同的事件處理程序呢,比如,每個li都有相同的click事件,如果按照之前的做法,用for循環,給每個元素添加事件,可想而知,會出現什麼樣的問題;

javascript中,添加到頁面上的事件程序直接影響到頁面整體運行性能,因爲需要不斷的與DOM節點進行及哦啊胡,訪問DOM次數越多,引起瀏覽器重繪與重排的次數也就越多,就會延長整個頁面的交互準備時間,這就是爲什麼性能優化的重要思想之一就是減少DOM操作的原因;
每個函數都是一個對象,是對象就會佔用內存,對象越多,內存佔用率就越大,自然性能就越差;

這下子知道爲什麼使用事件委託,只對它的父級這一對象進行操作會大大節省內存和優化性能了吧;

事件委託的核心代碼如下:

 
    
1
2
3
4
5
6
7
8
9
10
11
 
    
window.onload = function() {  
const ul = document.getElementById( "ul");
ul.onclick = function(ev) {    
const ev = ev || window.event;    
const target = ev.target || ev.srcElement;    
if (target.nodeName === 'li') {    
console.log( 123);     
console.log(target.innerHTML); 
}  
}
}

Event對象提供了一個屬性target,表示事件的目標節點,即觸發該事件的節點(想具體瞭解一些這個事件的可以執行下面代碼看瀏覽器的console內容)

 
    
1
2
3
 
    
document.onclick = function(e) {
console.log(e);
}

適合及不適合使用事件委託的事件

適合: click, mousedown, mouseup, keydown, keyup, keypress;
不適合:mouseover和mouseout雖然也有事件冒泡,但是需要經常計算他們的位置,處理起來有點麻煩;mousemove,每次都要計算它的位置,不好控制;還有一些本身沒有冒泡的特性,如focus,blur等

mouseenter事件類似於mouseover事件。唯一的區別是 mouseente事件不支持冒泡。

判斷變量類型

javaSctipt數據類型7種: Number, String, Boolean, Null, Undefined, Object, Symbol

typeof操作符

可能返回的值如下

  • undefined
  • boolean
  • string
  • number
  • object
  • function
    注意: typeof 的能力有限,其對於null, Date、RegExp類型返回的都是」object」
     
          
    1
    2
    3
    4
     
          
    typeof null // 'object'
    typeof {}; // "object"
    typeof []; // "object"
    typeof new Date(); // "object"

使用場景:區分對象和原始類型,要區分一種對象類型和另一種對象類型,可以使用: instanceof運算符或對象contructor屬性

instanceof運算符

用法: 左邊的運算數是一個object,右邊運算數是對象類的名字或者構造函數;返回true或false

 
    
1
2
3
4
 
    
[] instanceof Array; // true
[] instanceof Object; // true
[] instanceof RegExp; // false
new Date instanceof Date; // true

如果object是class或者構造函數的實例,則返回true,如果不是或者是null也返回false
instanceof運算符判斷是否爲數組類型

 
    
1
2
3
 
    
function isArray(arr){
return arr instanceof Array;
}

contructor屬性

所有的對象都有一個constructor屬性,指向該對象的基本對啊性構造函數類型的屬性

 
    
1
2
3
4
5
 
    
var a = new Array;
a.constructor === Array // true
var n = new Number( 3);
n.constructor === Number; // true

判斷爲數組還可以這樣

 
    
1
2
3
 
    
function isArray(arr){
return typeof arr === "object" && arr.constructor === Array;
}

Object.ProtoType.toString()

每個對象都有一個toString()方法,返回」[object type]」,其中type是對象的類型
當執行該方法時,執行以下步驟
1,獲取對象的class屬性
2,連接字符串 「[object 「+結果1+」]」 ;

所以可以通過toString()來獲取每個對象的類型,爲了每個對象都可以通過Object.protoType.toString()來檢測,需要以Funciton.prototype.call()或Function.prototype.apply()的形式來調用,傳遞要檢查的對象作爲第一個參數,稱爲thisArg

 
    
1
2
3
 
    
Object.prototype.toString.call( new Date); // "[object Date]"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call( /reg/ig); // "[object RegExp]"

參考

JavaScript中判斷對象類型的幾種方法總結
js中的事件委託或是事件代理詳解


轉載http://wangyaxing.top/categories/javascript/