前端基礎總結之JS(上)

數據類型:
基本數據類型:Number、String 、Boolean、Null和Undefined
按值訪問,可以操作保存在變量中實際的值,存放在棧(stack)內存中的簡單數據段,數據大小確定,內存空間大小可以分配。
引用數據類型:對象,包括函數,數組,日期等
存放在堆(heap)內存中的對象,變量實際保存的是一個指針,這個指針指向另一個位置。
創建一個引用數據了類型時,會在堆內存創建一個對象,並且在棧內存中創建一個對對象的引用(即引用類型在棧內存中存放的只是該對象的訪問地址,而在堆內存中爲這個值分配空間存儲)
當我們需要訪問引用類型(如對象,數組,函數等)的值時,首先從棧中獲得該對象的地址指針,然後再從堆內存中取得所需的數據。

關於堆和棧:
堆:用於引用類型分配空間,運行時動態分配內存,存取速度慢
棧:存放一些基本類型的引用,棧內數據可共享,但棧中的數據大小和生存期必須確定。

深拷貝和淺拷貝
淺拷貝(父元素與子元素關聯):
當我們使用對象拷貝時,如果屬性是對象或數組時,這時候我們傳遞的也只是一個地址。因此子對象在訪問該屬性時,會根據地址回溯到父對象指向的堆內存中,即父子對象發生了關聯,兩者的屬性值會指向同一內存空間。對象中的基本數據類型不會關聯父元素。
深度拷貝(無關聯):
既然屬性值類型是數組和或象時只會傳址,那麼我們就用遞歸來解決這個問題,把父對象中所有屬於對象的屬性類型都遍歷賦給子對象即可。


null和undefined
null表示"沒有對象",即該處不應該有值。典型用法是:
(1) 作爲函數的參數,表示該函數的參數不是對象。
(2) 作爲對象原型鏈的終點。
undefined表示"缺少值",就是此處應該有一個值,但是還沒有定義。典型用法是:
(1)變量被聲明瞭,但沒有賦值時,就等於undefined。
(2) 調用函數時,應該提供的參數沒有提供,該參數等於undefined。
(3)對象沒有賦值的屬性,該屬性的值爲undefined。
(4)函數沒有返回值時,默認返回undefined。
undefined是訪問一個未初始化的變量時返回的值,而null是訪問一個尚未存在的對象時所返回的值。因此,可以把undefined看作是空的變量,而null看作是空的對象。

基本包裝類型(Wrappers)
Number, String, Boolean,它們是特殊的引用類型,既與其他的引用類型相似,同時又具有與各自的原始類型相應的特殊行爲。
Number(1)是對1執行Number類包裝,會對傳入的參數去兩側空格,去掉引號,如果是純數字,則返回純數字,否則返回NaN,(1=== Number(1))

包裝類型和引用類型的區別
引用類型和包裝類型的主要區別是對象的生存期。
使用new操作符創建的引用類型的實例,在執行流離開當前作用域之前都一直保存在內存中。而自動創建的基本包裝類型的對象,則只存在於一行代碼的執行期間,然後立即被銷燬,這也意味着我們不能在運行時爲基本類型添加屬性和方法。

prototype和原型鏈:
Prototype是原型屬性,是一個指針指向一個對象,該對象包含可以由特定類型的所有實例共享的屬性和方法。通過構造函數生成對象實例時,會將對象實例的原型指向構造函數的prototype屬性。每一個構造函數都有一個prototype屬性,這個屬性就是對象實例的原型對象。

__proto__屬性
對象具有屬性__proto__,可稱爲隱式原型,一個對象的隱式原型指向構造該對象的構造函數的原型,這也保證了實例能夠訪問在構造函數原型中定義的屬性和方法。所有對象的__proto__都指向其構造器的prototype。
__proto__ 與 prototype
顯式原型的作用:用來實現基於原型的繼承與屬性的共享。
隱式原型的作用:構成原型鏈,同樣用於實現基於原型的繼承。舉個例子,當我們訪問obj這
個對象中的x屬性時,如果在obj中找不到,那麼就會沿着__proto__依次查找。

constructor屬性:
prototype對象有一個constructor屬性,默認指向prototype對象所在的構造函數。
由於constructor屬性是定義在原型(prototype)對象上面,意味着可以被所有實例對象繼承。
constructor屬性的作用
a:分辨原型對象到底屬於哪個構造函數
b:從實例新建另一個實例
c:調用自身的構造函數成爲可能
d:提供了一種從構造函數繼承另外一種構造函數的模式
e:由於constructor屬性是一種原型對象和構造函數的關係,所以在修改原型對象的時候,一定要注意constructor的指向問題。
    解決方法有兩種,要麼將constructor屬性指向原來的構造函數,要麼只在原型對象上添加屬性和方法,避免instanceof失真。

原型鏈(prototype chain)的特點:
    a:讀取對象的某個屬性時,JavaScript引擎先尋找對象本身的屬性,如果找不到,就到它的原型去找,如果還是找不到,就到原型的原型去找。如果直到最頂層的Object.prototype還是找不到,則返回undefined。
    b:如果對象自身和它的原型,都定義了一個同名屬性,那麼優先讀取對象自身的屬性,這叫做“覆蓋”(overiding)。
    c:一級級向上在原型鏈尋找某個屬性,對性能是有影響的。所尋找的屬性在越上層的原型對象,對性能的影響越大。如果尋找某個不存在的屬性,將會遍歷整個原型鏈。

作用域和this:
this代表函數運行時,自動生成的一個內部對象,只能在函數內部使用。this指的是,調用函數的那個對象。

this的值取決於調用的模式,有四種調用模式:方法調用模式、函數調用模式、構造器調用模式和apply調用模式
1)構造函數的調用--this引用的是所生成的對象
2)方法調用--this引用的是接收方對象
3)apply或call調用--this引用的是有apply或call的參數指定的對象
4)其他方式的調用--this引用的是全局對象

this的指向:
 情況1:如果一個函數中有this,但是它沒有被上一級的對象所調用,那麼this指向的就是window。在嚴格版中的默認的this不再是window,而是undefined。
 情況2:如果一個函數中有this,這個函數有被上一級的對象所調用,那麼this指向的就是上一級的對象。
 情況3:如果一個函數中有this,這個函數中包含多個對象,儘管這個函數是被最外層的對象所調用,this指向的也只是它上一級的對象
情況4:new關鍵字會創建一個空的對象,然後會自動調用一個函數apply方法,將this指向這個空對象,這樣的話函數內部的this就會被這個空的對象替代。

當this碰到return時
如果返回值是一個對象,那麼this指向的就是那個返回的對象,如果返回值不是一個對象那麼this還是指向函數的實例。
雖然null也是對象,但是在這裏this還是指向那個函數的實例

閉包
閉包可以解決函數外部無法訪問函數內部變量的問題。
閉包的特點不只是讓函數外部訪問函數內部變量這麼簡單,還有一個大的特點就是通過閉包我們可以讓函數中的變量持久保持。
閉包的理解:
  所謂的閉包就是可以創建一個獨立的環境,每個閉包裏面的環境都是獨立的,互不干擾。
閉包的創建:
  一個函數中嵌套另外一個函數,並且將這個函數return出去,然後將這個return出來的函數保存到了一個變量中,那麼就創建了一個閉包。
示例:
var lis = document.getElementsByTagName("li");
for(var i=0;i<lis.length;i++){
(function(i){
lis[i].onclick = function(){
console.log(i);
}
})(i)
}

閉包的特點:
使用閉包主要是爲了設計私有的方法和變量。閉包的優點是可以避免全局變量的污染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易造成內存泄露。
f2可以讀取f1中的局部變量,那麼只要把f2作爲返回值,就可以在f1外部讀取它的內部變量。f1是f2的父函數,而f2被賦給了一個全局變量,這導致f2始終在內存中,而f2的存在依賴於f1,因此f1也始終在內存中,不會在調用結束後,被垃圾回收機制(garbage collection)回收。
閉包就是能夠讀取其他函數內部變量的函數,可以簡單理解成“定義在一個函數內部的函數“。在本質上,閉包是將函數內部和函數外部連接起來的橋樑。
閉包有三個特性:
1.函數嵌套函數
2.函數內部可以引用外部的參數和變量
3.參數和變量不會被垃圾回收機制回收
(1)由於閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。
(2)閉包會在父函數外部,改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。

apply和call
apply和call都可以用來代替另一個對象調用一個方法,將一個函數的對象上下文從初始的上下文改變爲由thisObj指定的新對象。call/apply方法最大的作用就是能改變this關鍵字的指向
apply:最多只能有兩個參數——新this對象和一個數組argArray
call:它可以接受多個參數,第一個參數與apply一樣,後面則是一串參數列表。

Javascript垃圾回收方法
標記清除(mark and sweep)
這是JavaScript最常見的垃圾回收方式,當變量進入執行環境的時候,比如函數中聲明一個變量,垃圾回收器將其標記爲“進入環境”,當變量離開環境的時候(函數執行結束)將其標記爲“離開環境”。
垃圾回收器會在運行的時候給存儲在內存中的所有變量加上標記,然後去掉環境中的變量以及被環境中變量所引用的變量(閉包),在這些完成之後仍存在標記的就是要刪除的變量了

引用計數(reference counting)
在低版本IE中經常會出現內存泄露,很多時候就是因爲其採用引用計數方式進行垃圾回收。引用計數的策略是跟蹤記錄每個值被使用的次數,當聲明瞭一個 變量並將一個引用類型賦值給該變量的時候這個值的引用次數就加1,如果該變量的值變成了另外一個,則這個值得引用次數減1,當這個值的引用次數變爲0的時 候,說明沒有變量在使用,這個值沒法被訪問了,因此可以將其佔用的空間回收,這樣垃圾回收器會在運行的時候清理掉引用次數爲0的值佔用的空間。
在IE中雖然JavaScript對象通過標記清除的方式進行垃圾回收,但BOM與DOM對象卻是通過引用計數回收垃圾的,也就是說只要涉及BOM及DOM就會出現循環引用問題。

內存泄漏的產生:指一塊被分配的內存既不能使用,又不能回收,直到瀏覽器進程結束
1)意外的全局變量引起的內存泄露
2)閉包引起的內存泄露,閉包可以維持函數內局部變量,使其得不到釋放。
將事件處理函數定義在外部,解除閉包,或者在定義事件處理函數的外部函數中,刪除對dom的引用。
3)沒有清理的DOM元素引用,DOM清空或刪除時,事件未清除導致的內存泄漏
4)被遺忘的定時器或者回調
5)子元素存在引起的內存泄露
6)IE7/8引用計數使用循環引用產生的問題
function fn(){
var a={};
var b={};
a.pro=b;
b.pro=a;
}
fn()執行完畢後,兩個對象都已經離開環境,在標記清除方式下是沒有問題的,但是在引用計數策略下,因爲a和b的引用次數不爲0,所以不會被垃圾回收器回收內存,如果fn函數被大量調用,就會造成內存泄漏。

數組和對象的原生方法
pop,pushshift,unshift,sort,slice,splice,join,split,reverse,concat,indexOf ,lastIndexOf
動態事件綁定
DOM2級事件規定的事件流的三個階段:捕獲,目標,冒泡
1,DOM0級事件處理程序
使用DOM0級方法指定的事件處理程序被認爲是元素的方法,處理程序是在元素的作用域進行的,程序中this是引用的是當前元素。
首先獲取操作元素的引用,然後指定on事件。
2,DOM2級事件處理程序
事件是在冒泡階段被觸發,與DOM0級方法一樣,這裏添加的事件處理程序也是在其依附的元素作用域中運行,使用DOM2級添加事件處理程序的好處是可以添加多個事件處理程序
addEventListener(type,function(e){ },false);
3,IE事件處理的程序(作用域是全局的)
attachEvent('on'+type,handler);
attachEvent('on'+type,function(){handler.apply(el);} //保持作用域一致
detachEvent()
添加多個事件處理程序後執行順序相反,先執行後添加的事件。this===window

事件代理
事件代理(Event Delegation),又稱之爲事件委託。是 JavaScript 中常用綁定事件的常用技巧。顧名思義,“事件代理”即是把原本需要綁定的事件委託給父元素,讓父元素擔當事件監聽的職務。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好處是可以提高性能。

XML和JSON
主要差異:
XML 被設計爲結構化、傳輸和存儲數據,其焦點是數據的內容。XML 是不作爲的。
HTML 被設計用來顯示數據,其焦點是數據的外觀。

XML:擴展標記語言 (Extensible Markup Language, XML),可以用來標記數據、定義數據類型,是一種允許用戶對自己的標記語言進行定義的源語言。
<1>.XML的優點  
A.格式統一,符合標準;  
B.容易與其他系統進行遠程交互,數據共享比較方便。
<2>.XML的缺點  
A.XML文件龐大,文件格式複雜,傳輸佔帶寬;  
B.服務器端和客戶端都需要花費大量代碼來解析XML,導致服務器端和客戶端代碼變得異常複雜且不易維護;  
C.客戶端不同瀏覽器之間解析XML的方式不一致,需要重複編寫很多代碼;  
D.服務器端和客戶端解析XML花費較多的資源和時間。

JSON定義JSON(JavaScript Object Notation)一種輕量級的數據交換格式,具有良好的可讀和便於快速編寫的特性。可在不同平臺之間進行數據交換。
<1>.JSON的優點:  
A.數據格式比較簡單,易於讀寫,格式都是壓縮的,佔用帶寬小;  
B.易於解析
C.支持多種語言    
D.因爲JSON格式能直接爲服務器端代碼使用,大大簡化了服務器端和客戶端的代碼開發量,且完成任務不變,並且易於維護。
<2>.JSON的缺點  
A.沒有XML格式這麼推廣的深入人心和喜用廣泛,沒有XML那麼通用性;  
B.JSON格式目前在Web Service中推廣還屬於初級階段。

1、XML 存儲數據,存儲配置文件等需要結構化存儲的地方使用;
2、數據傳輸、數據交互使用JSON

發佈了27 篇原創文章 · 獲贊 6 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章