前言
平時的項目中,很少再去寫原生的js代碼,自己也很少再去思考某些代碼在原生情況的書寫方法,導致自己忽略了很多原生js中重要的內容。學習其他框架的時候也是只會使用,而對實現原理了解的較少。最近因為某些契機,燃起了鞏固js知識的欲望,故分享下最近學習的一些心得體會。
1、數據類型
- 基本數據類型:number,string,boolean,undefined,null
- 復雜數據類型:object
一些相關的內容:- n/a not applicable
- 加法無法進行類型轉換,減法可以,+/-0相加減,同號得正,異號得負。
- NaN not a number
- undefined表示一個特殊的值undefined
- null表示一個空指針
- 前置遞增或遞減會在求值以前執行,稱為副效應
- 禁止給undefined、NaN、Infinity賦值
5+"5"="55" string
5-"5"=0 number
-0-(+0)=-0
// true
typeof(null);//object
null==null;
null===null
null==undefined;
undefined==undefined;
undefined===undefined;
// false
NaN==NaN;
2、數組
數組的一些常用方法:
- 棧方法(LIFO): pop、push
- 隊列方法(FIFO): shift、unshift
- 排序 sort、reverse
要使數組元素按大小排序可在排序方法中加入函數,如從小到大排序:
var arr=[5,2,8];
arr.sort(function(a,b){
return a-b;
});
- 數組相加: concat
- 迭代方法:
數組的迭代方法不會修改數組。- every() 數組中的每一項都運行給定函數 全為true就是true 否則為false
- filter() 數組中的每一項都運行給定函數 返回結果為true的函數
- forEach() 數組中的每一項都運行給定函數 (IE9+)
- some()對數組中的每一項運行給定函數,如果該函數對任一項返回 true,則返回 true。
- map()對數組中的每一項運行給定函數,返回每次函數調用的結果組成的數組。
具體的實例代碼如下:
var numbers=[1,2,3,4,5,5,6,7,8,2,43];
var every=numbers.every(function(item,index,array){
return item>2;
});
console.log(every); //false
var filter =numbers.filter(function(item,index){
return item==index;
});
console.log(filter); //[5,6,7,8]
var foreach=numbers.forEach(function(item,index){
item+=1;
});
console.log(foreach); //undefined
var some=numbers.some(function(item,index){
return item>index+50;
});
console.log('some='+some); //some=false
var map=numbers.map(function(item,index){
return item*2;
});
console.log(map); //[2, 4, 6, 8, 10, 10, 12, 14, 16, 4, 86]
var sum=numbers.reduce(function(prev,next,index){
return prev+next;
});
console.log(sum); //86
3、DOM
文檔對象模型(document object model),這是一個api,描繪了一個層次化的節點樹,用於增加,刪除,修改頁面的某一部分。DOM有level1,level2,level3三級,DOM事件有0級,2級,以及三級事件。
- 獲取子節點:childNodes
- 獲取父節點:parentNode
- 兄弟節點:previousSibiling(前面)、nextSibling(后面)
- 獲取當前URL:URL
- 獲取來源URL:referrer
獲取元素的一些方法:
- 文檔元素表示
<html>
也是頁面的根元素 - 通過ID獲取,標簽名獲取
- anchors 返回對文檔中所有anchor對象的引用,如
<a href="#" onclick="change()" id="test" name="test">test</a>
<script>
console.log(document.anchors);
//[a#test, test: a#test]
//length:1
</script>
- 獲取頁面所有表單元素: forms
- 獲取頁面所有圖片元素:images
- 獲取頁面所有鏈接元素:links
- 獲取元素的標簽名:tagName
- 元素的屬性:getAttribute,setAttribute,removeAttribute、createAttribute (不支持IE6)
- 創建元素:createElement
- nodeType,nodeName,nodeValue
節點類型 | nodeType | nodeName | nodeValue |
---|---|---|---|
element | 1 | 元素名 | null |
attr | 2 | 屬性名 | 屬性值 |
text | 3 | #text | 節點內容 |
comment | 8 | #comment | 注釋文本 |
document | 9 | #document | null |
DOM的擴展
- querySelector()/querySelectorAll()
- html5新增dom方法
- getElementsByClassName
- htmlDocument:readyState有兩種狀態 loading以及complete
- 自定義數據屬性 data-
- 獲取內容 innerHTML,outerHTML
- IE8以下不支持事件流(事件冒泡,事件捕獲)。javascirpt與HTML之間的交互是通過事件實現的。IE的事件流叫做事件冒泡,即事件開始時由最具體的元素逐級向上傳播至不具體的元素。如下:
<body onclick="bodyClick()">
test1
<a href="#" onclick="change()" id="test" name="test">test</a>
</body>
<script>
function bodyClick(){
alert(1);
}
function change(){
alert(0);
}
</script>
點擊a鏈接的結果是,先彈出0,再彈出1。
事件捕獲則是不太具體的節點應該更早接收到事件,而最具體的節點應該最后接收到事件。
4、BOM
瀏覽器對象模型(browser object model),提供了很多對象,用於訪問瀏覽器的功能,核心是window,它是瀏覽器的一個實例。
- 打開關閉窗口: open/close
- 系統對話框:alert/confirm/prompt
- 打印:print
- 獲取窗口位置: window.screenLeft/Top 表示窗口相對於屏幕的位置
- 窗口移動:moveTo/moveBy
- 窗口大小:resizeTo/resizeBy
- 打開原始窗口對象:openr
- 前進后退:history.go()/back()/forward()
5、創建對象
對象的定義:無序屬性的集合,函數也是對象。
a. 工廠模式,用函數來封裝以特定接口創建對象的細節。如下:
function factory(name,number,score){
var o=new Object();
o.name=name;
o.number=number;
o.score=score;
return o;
}
var obj = new factory('leo',1,60);
b.構造函數。創建一個新對象,將構造函數的作用域賦給新對象(this),執行構造函數中的代碼,最后返回新對象。如下:
function Student(name,number,score){
this.name=name;
this.number=number;
this.score=score;
this.outPut=function(){
console.log('name:'+this.name+'\nnumber:'+this.number+'\nscore:'+score);
}
}
var yu=new Student('monkey',1001,99);
構造函數始終都應該以大寫字母開頭.
c.原型模式。所有的函數都有一個原型(prototype)屬性,通過將信息添加到原型對象中去,讓所有新建的對象實例共享這些信息。
function Person(){
}
Person.prototype.name='300kuai';
Person.prototype.number=38;
Person.prototype.score=59;
Person.prototype.outPut=function(){
console.log('name:'+this.name+'\nnumber:'+this.number+'\nscore:'+this.score);
}
var person1=new Person();
d.自定義類型。組合使用構造函數模式和原型模式。構造函數用於定義實例屬性,原型用於定義方法和共享屬性。這也是使用最多的一種方法。
- 對象的遍歷:
1.for-in。
var obj={'first':'leo','second':'monkey'};
for (var prop in obj) {
console.log(
obj[prop]
);
}
6、函數
- 函數聲明提升,即執行代碼之前會先讀取函數聲明。如以下代碼是正確的。
console.log(sumFunc(10,10));
function sumFunc(){
var sum=0;
for( var i in arguments){
sum+=arguments[i];
}
return sum;
}
但是,如果將函數賦給變量,函數沒有函數名,是匿名函數,必須先賦值。如下面代碼就是錯誤的:
console.log(sumFunc(10,10));
var sumFunc=function(){
var sum=0;
for( var i in arguments){
sum+=arguments[i];
}
return sum;
}
總結
從事前端工作越久,使用的框架,方案越多,越發現,其實最基礎的還是最重要的。不管框架多么酷炫,實現的功能多么強大,始終只是我們編程的一種工具。當然,雖然這些工具不是不可或缺的,但是,掌握這些框架知識對我們項目模塊化的開發,軟件性能的提高確實起到了重要的作用。
又看了一遍最基礎的javascirpt,對於原型,閉包,繼承的理解還是不是非常深刻,接下去的幾天也打算重點看下這些內容,下一篇文章也應該是這幾個內容。