Function: 匿名函數,做用域,做用域鏈和閉包html
函數的重載: 什麼是:函數名相同,參數列表不一樣.根據傳入函數的參數的不一樣,整形不一樣的邏輯. 數組
什麼時候用:若是一項任務,根據不一樣的參數,不執行不用的邏輯. 瀏覽器
優勢:減輕調用者的負擔. 問題:js語法不知函數的重載.閉包
解決辦法:在函數中都有arguments的屬性,專門用於接收傳入函數的全部參數值的類數組對象.app
匿名函數: 什麼是:在函數定義時,不給函數名,即不被任何變量引用. 函數
什麼時候用:肯定函數只使用一次. 優勢:節約內存. this
如何用:1.自調()--定義完當即執行.;2回調()--定之後,傳給其餘函數使用;prototype
做用域: 什麼是:變量的有效範圍.htm
函數的生命週期(四個部分):對象
1.程序開始執行 執行環境棧-Execution Context Stack:專門按順序保存每一個函數的執行環境的集合. 全局EC:開始執行程序時,首先將全局EC壓入ECS中. 建立window對象,保存全部全局函數和變量.window其實就是全局做用域.
2.函數聲明時 建立函數對象,封裝函數定義. 用函數名建立一個變量,引用函數對象. 在函數中添加scope屬性,用來引用函數來自的做用域對象.
3.函數調用時 建立活動對象:Active Object.專門用來保存調用函數時的中局部變量. AO其實就是函數做用域對象; AO中的parent屬性會引用函數來自的父級做用域對象.由此便造成了做用域鏈. 做用域鏈控制着變量的使用順序,局部優先,而後是全局變量. 在再ECS中壓入函數的執行環境.而且有屬性scope chain 引用了AO
4.函數調用後 函數的執行環境彈棧,則AO伴隨着引用消失而消失,則局部變量也跟着消失. 閉包 什麼是:能保證局部變量的重用,又能保護其不受污染.
什麼時候用:但願一個變量.......
怎麼用:3步
1.使用外層函數將局部變量和內層函數包裹起來. 2.外層函數將內層函數對象返回. 3.調用外層函數得到返回的內層函數對象. 筆試時,通常先找出受保護的局部變量並計算出其最後的值.而後找到引用這個變量的函數.要注意函數只有被調用時,纔會執行.
判斷是不是自有屬性:obj.hasOwnProperty("屬性名");
回顧:面向對象 三大特色:
封裝:將一個事物的屬性和功能集中定義在一個對象中.
繼承:父對象的成員,子對象無需建立,就可以使用; 即重用了代碼,又節省了內存.
多態-重寫:同一種方法在不一樣的狀況下表現出不一樣的狀態.
1.建立對象--封裝(3種方法--前兩種用於建立單獨的對象) var obj={屬性名:屬性值,...,方法名:function(){}}; var obj={};(new和()都能省略,但不能同時省略)obj[屬性名]="屬性值"; 定義構造函數;var obj=new 構造函數(屬性值,...);
js底層,一切對象都是hash數組. 訪問本身的屬性:this.屬性名;
new作了4件事
1.建立了一個空的對象;
2.設置新對象的_porto_屬性繼承構造函數的原型對象.
3.用新對象調用構造函數對象,將構造函數的this臨時替換成新對象.
4.將生成的新對象的地址返回給變量. 2.調用對象的方法,操做對象的屬性
原型對象:prototype 是集中保存父級對象的共有成員的對象.
如何得到:構造函數.prototype 子對象._proto_; 其中,子對象的_proto_屬性是內部屬性,沒法直接得到. Object.getPrototypeOf(obj); 獲取obj對象的父級原型對象. 判斷自有屬性和共有屬性: 自有屬性是指保存在子對象本地的成員,保存在父級原型對象中的是共有屬性. obj.hasOwnPrototype("屬性名");
判斷obj是否包含自有屬性.(false並不能表示這個屬性就是共有屬性,還多是沒有) 共有屬性:在以前的基礎上,obj.屬性名!=undefined;此時表示爲共有屬性. 內置對象的API瀏覽器兼容性問題: 內置對象的API都存儲在其原型對象中,若是不支持該方法就能夠直接在其原型對象中添加該方法便可,重要的是該方法的實現原理. 判斷繼承關係: 根據原型對象判斷: father.isPrototypeOf(child); 判斷father是不是child的父級對象,同時也表示child是不是father的子對象. 根據構造函數判斷: child instancof 構造函數 判斷child是不是構造函數創造出來的對象.
筆試題:判斷一個對象是不是數組類型,有幾種方法.(4種)
1.Array.prototype.isPrototypeOf(xxx);//根據原型判斷
2.xxx instanceof Array;//根據構造函數判斷
3.根據對象的class屬性判斷. 其中,只有Object的直接子類對象能夠直接調用xxx.toString();方法來獲取class的值.其餘的子類對象的toString()方法都被重寫了.如何解決呢?--call
call強行調用函數,而且臨時替換爲this對象.(強行借用一個本沒法調用到的函數.) Object.prototype.toString.call(obj)--返回"[object Array]" 因此在判斷一個對象是否爲數組時, 判斷Object.prototype.toString.call(obj)==="[object Array]"
4.ES5之後支持Array.isArray(obj);--其底層所示用的原理仍是使用的第三種方法. 做用域鏈和原型鏈: 做用域鏈是js默認執行的路線,同時也是控制變量的執行順序. 而原型鏈則是控制js中對象的屬性的執行循序.
面向對象中多個類型間若是有相同結構的屬性和方法,則須要抽象到父類型中. 例如:都有name屬性和fly方法.那麼就能夠抽象到父類中. 那麼此時,在子類對象的建立過程當中碰見問題. 首先是子類對象在建立時怎麼調用父類的構造方法?(這裏使有call和apply方法,做用都是強行調用一個函數.並將this改成當前正在建立的新對象.不一樣的是,call須要單獨將參數寫出,而apply只用使用arguments就能夠,注意參數的先後順序.) 而後是子類對象怎麼得到父類對象的的方法?繼承.經過方法 Object.setPrototypeOf(子類對象.prototype,父類對象.prototype);
修改繼承: 修改繼承只有3種方法
1.修改一個對象的父對象.--就是改變__proto__屬性 child.__proto__=father=>Object.setPrototypeOf(child,father);
2.批量修改全部子對象的父對象--就是修改構造函數的prototype. 構造函數.prototype=father(強調必須在開始建立對象前修改)
3.兩種類型間的繼承 若是多個對象,擁有相同的屬性結構和功能,那麼就能夠抽象出一個公共的父對象中
怎麼作: 3.1 定義公共父類型,來集中定義共有的屬性和功能.
3.2 讓子類的原型對象繼承父類的原型對象(目的是讓子類可使用父類中的共有方法)--inherits(繼承):直接使用父對象中的成員--必須繼承才能使用公共方法. Object.setPrototypeOf(子類型構造函數.prototype,父類型構造函數.prototype);
3.3 在子類構造函數中借用父類型構造函數--(extends)擴展:爲子對象擴展父類沒有的屬性. 父類型構造函數.call(this,屬性參數); 父類型構造函數.apply(this,arguments); call與apply的區別--同:都是強行調用一個函數,將this改成當前正在調用的對象 異:call每一個參數必須獨立傳入,apply全部參數放在一個集合中集中傳入(argument)
ES5新特性: 對象的屬性:兩大類-命名屬性和內部屬性(不可直接修改)
命名屬性(自定義屬性): 數據屬性:實際存儲屬性值的屬性(就是一般咱們所寫的.) 四大特性: value,wirtable,enumerable,configurable.(默認值都爲true) 如何產看四大特性: Object.getOwnpropertyDescriptor(obj,"屬性名") 如何設置四大特性: Object.defineProperty(obj,屬性名,{//一次修改一個 特性:值,... }); Object.defineProperties(obj,{//一次修改多個. 屬性名:{ 特性:值,... } }) 訪問器屬性(爲了保護屬性-一般須要定義的):--爲了自定義保護的邏輯. 四大特性: get:function(){ return 受保護的屬性值; } set:function(val){ //驗證經過 受保護屬性值=val; } enumerable,configurable. 什麼時候使用:對一個屬性自定義保護邏輯時. 如何使用:Object.defineProperty( obj,"屬性名",{ get:function(){return 屬性值},//js自動調用 set:function(val){//驗證 賦值}//js自動調用 } ) 筆試題:在js中定義一個類型,包含共有屬性和私有屬性. js中的私有屬性其實就是一個受閉包保護的一個局部變量.(注意,兩者必須相互配合使用才能造成私有屬性) ***注意:爲一個已定義好的對象添加私有屬性,使用添加外層函數的閉包結構(匿名函數的自調) 爲多個子類對象添加相同的私有屬性.則對構造函數設置一個受閉包保護的一個局部變量.(其中,構造函數就一個外部函數,因此不用再定義.)
防篡改:防止對已經建立好的對象的屬性進行增減. 三個級別:
1.防擴展:禁止向對象中添加新屬性\ 每一個對象中都有一個extensible屬性,控制可否向變量中添加新屬性,默認爲true. Object.preventExtension(obj);//設置對象中的extensible屬性爲false 問題,不妨刪除.
2.密封:即防擴展,又防刪除(是經過設置每一個屬性的configurable爲false實現的). Object.seal(obj);
3.凍結:全部屬性禁止增減,同時也禁止修改.
Object.freeze(obj); Object.create(): 什麼時候:經過一個(父)對象建立一個子對象時使用. 筆試題:寫一個函數,模擬create方法的實現過程
3步:1.基於現有父對象建立一個新的子對象;
2.繼承父對象
3.同時擴展子對象的自有屬性. --用Object,defineProperties(obj, 屬性:{} );
注意: 原型方法/實例方法: 必須用具體對象才能調用 構造函數方法: 不須要任何具體對象便可直接調用
ES5-數組API 判斷數組中全部元素,是否符合要求: every:判斷每一個元素是否都符合要求. arr.every(function(val,idx,arr){ //回調函數用於檢測每一個函數 //val;自動得到當前元素值 //idx:自動得到當前元素的位置 //arr:自動得到當前正在遍歷的數組 }) some:判斷是否包含知足要求的元素. 遍歷: forEach:對原數組中的每一個元素執行相同的操做. arr.forEach(function(val,idx,arr){ //對arr[idx]的值作出修改 }) map:將原數組中的每一個元素加工後,生成新數組. arr.map(function(...){ //根據條件 return 新值; }) 過濾和彙總 filter:複製出原數組中符合要求的元素,組成新元素. var newarr=arr.filter(function(...){...}) reduce:將數組中每一個元素的值彙總出一個結果.
bind:基於現有函數,建立一個新函數,提早永久綁定函數中的this爲指定對象.
筆試題----模擬實現bind方法 call與apply與bind: call,apply:強行借用一個函數,並臨時替換函數中的this爲指定對象. call與apply是執行一個函數. bind:建立一個新函數,並永久綁定this和部分屬性. bind不是執行函數,而是建立一個函數
將類數組對象轉爲純數組: var new=[](或者Array.prototype).slice.call(arguments);
須要手寫的函數:forEach,map,create,bind(請看下面的連接)