es5 面向對象簡易總結
1.js的預處理階段,將聲明方式的函數(指向函數的引用)和var定義的變量(undefined)放置在詞法環境(全局環境指的是window)中;
2.命名沖突時,函數優先級更高。(不會被同名變量覆蓋);
3.函數的參數(帶傳入的值)和argumengts對象優先添加入函數的詞法環境;
4.創建函數時會創建自己的詞法環境,與父函數形成作用域鏈,即child的詞法環境[[scop]]指向parent的詞法環境[[scope]]最終指向window;
5.在閉包中可以通過window.xx=xx將內部變量或方法導出;
6.閉包中的子函數在return出父函數後依然可以使用父函數的變量及參數;
7.若子函數沒有引用任何父函數的變量或參數,則未形成閉包。靜態作用域(閉包)的本質是嵌套函數與作用域鏈的結合;
8.閉包簡單示例
function f(){ var a=0; return function(){ a++; console.log(a); } } var res=f(); res() ; //1 res(); //2
閉包不僅可以減少全局變量,也有利於封裝,也可以減少傳遞給函數參數的數量,例如:
function calc(base) { return function (max) { let total=0; for(let i=1;i<=max;i++){ total+=i; } return total+base; } } let res=calc(2); console.log(res(3)); //基數為base 加上1到max的值的運算示例。
9.閉包捕獲的變量是引用不是復制;父函數每調用一次就產生一個新的閉包(詞法環境);
10.var res=p && p.address && p.address.home 是if(p)....的簡寫方法,若一個為空則都為空。若home有值則未home。
對象的set get方法示例:
let obj={ _age:18, get age(){ return this._age; }, set age(val){ if(val<0||val>150){throw new Error(‘是人不?‘) }else{ this._age=val; } } }; obj.age=55; console.log(obj.age)
11.使用Object.defineProperty(p,‘newprop‘,{
value:99,writable:false,
}若不指定特性,則特性都為false,Object.defineProperties為對象的多個屬性同時賦值和特性。(configurable writable enumerable value get set)
12.Object.keys(p) 返回一個數組,包含p對象的所有鍵值(不包括不可枚舉的)(不包括繼承的)。
p.hasOwnProperty(‘someprop‘)返回布爾值。Object.getOwnPropertyDescriptor(p,‘name‘)返回描述信息對象。
13.Function構造器的構造器指向它本身。(頂級),typeof() instanceof ;
14.工廠函數創建對象相對獨立,占用內存較多;
15.公有的屬性方法放入對象的原型屬性(prototype)中;
16.Person.prototype.constructor===Person;
17.實例與構造器原型對象的連接方式為__proto__ 並非.constructor.prototype。偽類的本質是:實例創建出來後,構造函數和實例並沒有什麽關系了,
即使將構造函數的prototype對象修改掉,也不影響已經new過的實例(因為實例用__proto__和構造函數的原型對象保持引用關系),只能影響到以後new的實例。
18.this的指向問題:this是運行時指向;this在函數運行時誰調用就指向誰;用apply,call.bind改變this指向(apply和 call的區別只是apply的參數是數組。).bind()方法返回一個函數,並沒有直接調用函數,apply和call直接調用了函數;bind()適合綁定事件等。
19.模擬new操作符:
function New(f) { //f是構造器函數 return function () { let o={‘__proto__‘:f.prototype}; f.apply(o,arguments); return o; } } let p=New(Person)(‘jiu‘,66);
20.Function的__proto__.__proto__指向Object,Object的__proto__最終指向Null。
21.構造函數即是方法也是對象,__proto__指向Function;
22.用for...in淺拷貝對象實現繼承時,如果父對象內部嵌套對象,則拷貝的是嵌套對象的引用,修改子對象會影響到父對象。
23.[1,3,2]的tpyeof 是object,使用遞歸實現深拷貝:(使用遞歸的理由是處理對象中嵌套的對象或者數組,一直處理下去,解除引用關系。)
function extendDeeply(p,c={}) { for(let prop in p){ if(typeof p[prop]===‘object‘){ c[prop]=(p[prop].construct===Array)?[]:{}; extendDeeply(p[prop],c[prop]); }else{ c[prop]=p[prop]; } } }
24.由於F.prototype.constructor===F;所以:
let f = new F(); f.__proto__===f.constructor.prototype; //true; F.prototype.__proto__===F.prototype.constrctor.prototype //false
F.protoType.__proto__===Object.prototype; Function.prototype.__proto__===Object.prototype;
25.Object.create()的模擬實現:
function myCreate(p){ function F(){}; F.prototype=p; let ins=new F(); return ins; }
頂級對象是Object.prototype,頂級構造器是Function,以下是說明圖:
26.(對象) instanceof (函數);
27.對象間建立繼承關系可以使用C.prototype=Object.create(P.prototype); (相當於C.prototype=new P()的進化版);
28.繼承四部:1 創建父類--->2 創建子類--->3 C.prototype=Object.create(P.prototype);C.prototype.constrctor=C;--->4 為子類的原型屬性對象添加方法等。
29.子類的實例屬性可以在構造函數中寫P.apply(this,arguments);
30.p1.hasOwnProperty(‘name‘); P.prototype.isPrototypeOf(f); Object.getPropertyOf(f);
31.多態:利用arguments對象實現方法的重載(模擬參數的數目等決定函數的執行情況length,或者判斷參數類型決定函數的執行情況typeof等)
32.重寫:直接在子類中重新定義和父類同名的方法/屬性。在子類中若要調用父類的方法可以創建C.super=P.prototype 然後在子類原型方法中調用,比如C.super.run();
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
33.回顧jQuery:$.extend({staticMethod:function(){console.log(‘1111‘)}})(添加靜態方法); $.fn.extend({})(添加實例方法,相當於$.prototype.extend);
34.Jquery框架簡易說明:在自調用立即執行函數中:用window.$和window.jQuery暴露$和jQuery給外部,jQuery.extend添加靜態方法;jQuery.fn.extend添加實例方法
(function () { //暴露外部使用的借口 let jQuery=window.jQuery=window.$=function () {}; //處理原型對象 jQuery.fn=jQuery.prototype={} //靜態和實例實現繼承 jQuery.extend=jQuery.fn.extend=function () {}; //添加靜態方法 jQuery.extend({}); //實現實例方法 jQuery.fn.extend({}); })();
35.用for循環或者Array.prototype.push.apply(o,divs)來創建簡易的數組型對象;(並不是變成真正的數組,只是添加屬性)
36.仿Jquery實現簡單的選擇器:
(function () { //暴露外部使用的借口 let jQuery=window.jQuery=window.$=function (selector) { return new jQuery.fn.init(selector); }; //處理原型對象 jQuery.fn=jQuery.prototype={ init:function(selector){ let ele=documents.getElementsByTagName(selector); Array.prototype.push.apply(this,ele); return this; }, jQuery:‘1.1.1‘, length:0; size:function(){ return this.length; } } //靜態和實例實現繼承 jQuery.extend=jQuery.fn.extend=function () {}; //添加靜態方法 jQuery.extend({}); //實現實例方法 jQuery.fn.extend({}); })();
37.仿Jquery繼承的簡易實現:只有一個參數時可以用for..in this[p]=o[p];
38.仿Jquery添加靜態方法:比如trim() noconflict()(通過用臨時變量比如_$保存$ 然後恢復);
39.仿Jquery添加實例方法:比如get set each css
40.仿Jquery鏈式操作的簡易實現:在函數最後一步return this即可。
es5 面向對象簡易總結