Ecmascript
-
大括號的位置
function f() { return { h:'Hello World' } } console.log(f()) //undefined
Javascript自動在return語句后面添加了分號結束該行,所以該函數(shù)返回的是undefined
相當于執(zhí)行了下面的語句function f() { return ; { h:'Hello World' } } console.log(f()) //undefined
-
語句合并造成的坑
function g() { var a = b = 0; } g() console.log(a) //Type Error: a is not defined console.log(b) // 0
上面的語var a = b = 0, 你以為的解析為 var a = 0; var b = a; 實際上解析為
b = 0; var a = b; 所以b是一個全局變量, 掛載到全局對象上, a是一個局部對象,在函數(shù)外部無法訪問. -
變量提升
- 局部變量提升, 只提升聲明
if (!o) { var o = {a:1}; console.log(o); }// 變量的聲明被提升 // 實際上解析成這樣 var o; if (!o) { o = {a:1}; console.log(o) }
- 下面的代碼會報 f is not a function
if (false) { function f() { console.log("Hello World") } } f() // 報錯
- 變量提升和函數(shù)提升
var myname = ""; console.log(typeof myname) // string function myname() {} console.log(typeof myname) //string
- 不會被條件判斷所控制
foo(); // TypeError: foo is not a function() var a = true; if (a) { function foo() {console.log("a")} } else { function foo() {console.log("b")} } // 這種情況下打印出 undefined console.log(typeof foo) var a = true; if (a) { function foo() {console.log("a")} } else { function foo() {console.log("b")} }
-
分號坑
var a = 1 (function() { console.log(a) })()
以為會安全的打印a的值,實際上報錯,如果下一行的第一個字元(token)是下面這五個字符之一传藏,Javascript將不對上一行句尾添加分號:"("、"["、"/"、"+"和"-"。
-
內存泄漏的識別方法
怎樣可以觀察到內存泄漏呢柳譬?經驗法則是,如果連續(xù)五次垃圾回收之后,內存占用一次比一次大济榨,就有內存泄漏。這就要求實時查看內存占用绿映。
-
setTimeout與this
//setTimeout中的函數(shù)所處在于全局作用域中擒滑,所以函數(shù)中使用this關鍵字時,這個this關鍵字指向的是全局對象(Window): var Value1 = 200; var Value2 = 20; var myObj = { Value1 : 10, Value2 : 1, caleculatedIt: function(){ setTimeout(function(){ console.log(this.Value1 * this.Value2); }, 1000); } } myObj.caleculatedIt(); //4000
-
typeof的坑
- typeof 查看變量的類型
typeof null //"object" typeof NaN // "number" typeof eval // "function" // 判斷Class的類型: ({}).toString.call(classA);
- instanceof
- 適合自定義對象
- 也可以檢測原生對象, 但在iframe和window檢測失效
-
NaN判斷
parseInt("abc") === NaN // NaN與任何值比較都為false, 即使NaN==NaN也是false
-
正確的判斷方式
var b = isNaN(parseInt(abc))
-
類型轉換
-
parseInt和Number
var num = parseInt(str); //會提取其中的數(shù)字 //str="abc" //NaN(not a number) //str = "abc 12 bc" //NaN //str = "123px" //123 從最左邊提取 var num = Number("123"); var num = Number("123abc"); //NaN, 比Number嚴格轉換
-
隱式轉換 隱式轉換坑
var a = 12, b = "12"; alert(a==b) //返回true b字符串轉成數(shù)字, 但是typeof b仍然是string alert('12' - '7') // 5 兩邊都轉成數(shù)字后計算 alert('12' + '7') // '127' 字符串串聯(lián) alert(12 + '7') // '127' 數(shù)字轉字符串 // 總結: 減法,乘法,除,取余,大于小于等操作都轉成Number類型
-
-
構造器中的this
function c() { this.a = 37; return {a:38}; } o= new c(); console.log(o.a); //38 o為返回的對象 如果返回的是基本類型 那么就返回this function d() { this.e = 37; return {f:38}; } o1 = new d() console.log(o1.e) // undefined o1對象中只有f屬性 沒有e屬性
-
嚴格模式下, arguments跟蹤問題
// 兩次都是1 (function fn(a) { 'use strict'; console.log(arguments[0]); a = 2; console.log(arguments[0]); })(1); // 兩次打印的都是1, 如果實在非嚴格模式下, 打印的是1,2
-
實參和形參
var add = function (a,b) { console.log(arguments.length);//3,表示實參長度 console.log(arguments.callee.length);//2叉弦,表示形參長度 }; add(1,2,3);
JavaScript操作DOM的坑
- 獲取鼠標點擊的位置 (即鼠標點擊的位置距離document左上角的位置)
Firefox丐一,Chrome、Safari和IE9都是通過非標準事件的pageX和pageY屬性來獲取web頁面的鼠標位置的淹冰。
function mouseClick(event) {
event = event || window.event;
var x = 0, y = 0;
if (event.pageX) {
x = event.pageX;
y = event.pageY;
} else if(event.clientX){
var scrollLeft, scrollTop
if (document.documentElement.scrollLeft) {
scrollLeft = document.documentElement.scrollLeft
scrollTop = document.documentElement.scrollTop
} else if (document.body.scrollLeft) {
scrollLeft = document.body.scrollLeft
scrollTop = document.body.scrollTop
}
x = event.clientX + scrollLeft
y = event.clientY + scrollTop
}
return {
x,
y
}
}
- scrollLeft, scrollTop 為滾動軸卷起的左側距離和頂部距離, 即滑動軸滾動的距離
-
clientX, clientY 為鼠標點擊的位置距離瀏覽器可視區(qū)域左上邊角的距離, 與有無滾動軸無關
-
offsetLeft和style.left區(qū)別
- style.left返回的是字符串库车,比如10px。而offsetLeft返回的是數(shù)值樱拴,比如數(shù)值10
- style.left是可讀寫的柠衍,offsetLeft是只讀的
- style.left的值需要事先定義(在樣式表中定義無效洋满,只能取到在html中定義的值),否則取到的值是空的
-
getComputedStyle 和 elment.currentStyle
- getComputedStyle(obj, false) 是支持w3c(FF12珍坊、chrome14牺勾、safari):在FF新版本中只需要第一個參數(shù),即操作對象阵漏,第二個參數(shù)寫“false”也是大家通用的寫法驻民,目的是為了兼容老版本的火狐瀏覽器。缺點:在標準瀏覽器中正常履怯,但在IE6/7/8中不支持
- 在IE6,7,8中回还,并不支持getComputedStyle,IE提供了currentStyle屬性
var oDiv=document.getElementById('div1'); if(oDiv.currentStyle){ // IE6,7,8 alert(oDiv.currentStyle.width); }else{// IE9+ FF Chrome Opera alert(getComputedStyle(oDiv).width); }
-
事件監(jiān)聽和默認時間, 冒泡處理
- addListener|removeListener, preventDefault(), stopBubble(): IE9+ FF Chrome Opera w3c
- attachEvent|detachEvent, returnValue=true, cancelBubblue=true, cancel: IE6,7,8
function listenEvent(target,type,handler){ if(target.addEventListener){//w3c target.addEventListener(type,handler,false); }else if(target.attachEvent){//IE type = "on" + type; target.attachEvent(type,handler);//IE }else{ target["on" + type] = handler; } } //取消事件 function cancelEvent(e){ if(e.preventDefault){ e.preventDefault();//w3c }else{ e.returnValue = false;//IE } } //取消傳遞 function cancelPropagation(e){ if(e.stopPropagation){ e.stopPropagation();//w3c }else{ e.cancelBubble = true;//IE } }
-
獲取瀏覽器窗口尺寸
function size(){ var w = 0, h=0; // IE6, 7, 8 if(!window.innerWidth){ w = (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth); h = (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight); } // IE9+ FF Chrome Opera W3C else{ w = window.innerWidth; h = window.innerHeight; } return {width:w,height:h}; } //實用的 JavaScript 方案(涵蓋所有瀏覽器): var w=window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; var h=window.innerHeight || document.documentElement.clientHeight|| document.body.clientHeight;
Document對象的body屬性對應HTML文檔的<body>標簽叹洲。
Document對象的documentElement屬性則表示 HTML文檔的根節(jié)點柠硕。 -
attributes屬性
attributes 屬性返回該節(jié)點的屬性節(jié)點集合。
document.getElementById('box').attributes//NamedNodeMap document.getElementById('box').attributes.length;//返回屬性節(jié)點個數(shù) document.getElementById('box').attributes[0]; //Attr运提,返回第一個屬性節(jié)點 document.getElementById('box').attributes[0].nodeType; //2蝗柔,節(jié)點類型 document.getElementById('box').attributes[0].nodeValue; //屬性值 document.getElementById('box').attributes['id']; //Attr,返回屬性為 id 的節(jié)點 document.getElementById('box').attributes.getNamedItem('id'); //Attr
- setAttribute(attrName, value) 不建議使用設置class和style
- setAttribute('class', 'container') for FF
- setAttribute('className', 'conatainer') forIE, IE不認識class
- getAtribute(attrName) 統(tǒng)一獲取自定義屬性
- removeAttrite(attrName)
- setAttribute(attrName, value) 不建議使用設置class和style
-
獲取目標對象
//跨瀏覽器獲取目標對象 function getTarget(ev){ var ev = ev || window.event if(ev.target){ //w3c IE9+ return ev.target; }else if(window.event.srcElement){//IE6, 7, 8 return window.event.srcElement; } } target = event.target ? event.target: event.srcElement;
-
Node接口
特性/方法 類型/返回類型 說明 nodeName String 節(jié)點的名稱, 節(jié)點類型而定義 nodeValue String 節(jié)點的值 文本節(jié)點返回文本 nodeType Number 節(jié)點類型常量值 元素0 屬性1 文本2 childNodes NodeList 所有子節(jié)點列表(包括元素節(jié)點和文本節(jié)點) firstNode Node childNodes列表中的第一個節(jié)點 lastNode Node childNodes列表中的最后一個節(jié)點 children NodeList 子節(jié)點列表中只返回元素節(jié)點 previouSibling Node 上一同級節(jié)點 nextSibling Node 下一同級節(jié)點 hasChildNodes() Boolean 是否擁有子節(jié)點 attributes NamedNodeMap 返回屬性NamedNodeMap appendChild(Node) Node 節(jié)點添加到childNodes末尾 removeChild(Node) Node 從childNodes中刪除node replaceNode(new, old) Node 將childNodes中的old替換成new insertBefore Node 在已有子節(jié)點之前插入新子節(jié)點 - 返回父節(jié)點: node.parentNode || node.parentElement (IE)
- 返回子文本節(jié)點集合:node.textNodes
- 節(jié)點信息
- 是否包含某節(jié)點:node.contains()
- 是否有子節(jié)點node.hasChildNodes()
- 創(chuàng)建新節(jié)點
- createDocumentFragment() -創(chuàng)建文檔碎片節(jié)點
- createElement(tagname) -創(chuàng)建標簽名為tagname的元素
- createTextNode(text) -創(chuàng)建包含文本text的文本節(jié)點