1. 程式人生 > >es5 面向對象簡易總結

es5 面向對象簡易總結

優先 預處理 deep 操作符 extend return () blog scrip

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 面向對象簡易總結