1. 程式人生 > >106_js筆記9_js類和建構函式

106_js筆記9_js類和建構函式

一,類的定義

  1. 通過建構函式來定義
  2. 大駝峰命名法
  3. 通過new來呼叫
  4. 對比工廠法,不用手動建立物件和返回值
  5. function Person(name, age) {
            this.name = name;
            this.age = age;
            this.say = function () {
                console.log(this.name, this.age);
            }
        }
    
    

     

二,建構函式

  1. 程式碼簡潔,識別物件的具體型別
  2. 每個物件都可以訪問一個名稱叫做constructor的屬性, 屬性指向建立該例項的建構函式, 
  3. 通過constructor判斷一個物件是否屬於某個類(p instanceof Person或者p.constructor === Person)
  4. 防止記憶體浪費和函式方法重名,可以把需要共享的函式定義到建構函式外部
    1. // 將共享函式封裝到一個物件中, 與外界隔絕, 這樣就不會汙染全域性名稱空間了
          var fns = {
              say: function () {
                  console.log(this.name, this.age, this.type);
              },
              setName: function (name) {
                  this.name = name;
              },
              setAge: function (age) {
                  this.age = age;
              }
          }
          function Person(name, age) {
              this.name = name;
              this.age = age;
              this.type = "人";
              this.say = fns.say;
              this.setName = fns.setName;
              this.setAge = fns.setAge;
          }
          var p1 = new Person("jj", 33);
          var p2 = new Person("zs", 33);
          console.log(p1.say === p2.say); // true
      
      

       

  5. 建構函式的優化方法
    1. 建構函式、例項、原型三者之間的關係()
    2. 當呼叫物件的屬性或者方法的時候,先去找物件本身的屬性/方法
    3. 如果物件沒有該屬性或者方法。此時去原型中查詢對應的屬性/方法
    4. 如果物件本身沒有該屬性/方法,原型中也沒有該屬性或者方法,此時會報錯
    5. function Person(name, age) {
              this.name = name;
              this.age = age;
          }
          // 給原型物件新增新的屬性和方法
          Person.prototype.say = function () {
              console.log(this.name, this.age, this.type);
          };
          Person.prototype.type = "人";
      
          var p1 = new Person("jj", 33);
          var p2 = new Person("zs", 33);
          console.log(p1.say === p2.say); // true
          console.log(p1.type === p2.type); // true
      
          // 當呼叫物件的屬性或者方法的時候,先去找物件本身的屬性/方法
          // 如果物件沒有該屬性或者方法。此時去原型中查詢對應的屬性/方法
          // 如果物件本身沒有該屬性/方法,原型中也沒有該屬性或者方法,此時會報錯
          p1.say();
          console.log(p1.type);
      
      

       

  6. 原型鏈上方法呼叫
    1. 先查詢當前物件, 當前物件有就使用當前物件的方法
    2. 當前物件沒有再逐層在原型鏈上查詢, 最先找到那個就使用哪個
    3. 如果找到null都沒找到就報錯
    4. 	function Person(name, age) {
      			this.name = name;
      			this.age = age;
      			 this.say = function () {
      			     console.log("自己的", this.name, this.age);
      			 };
      		}
      		// 給原型物件新增新方法
      		 Person.prototype.say = function () {
      		     console.log("原型鏈上的", this.name, this.age);
      		 };
      		var p = new Person("jj", 33);
      		// 自己有嗎? 有, 使用自己的
      		// 自己有嗎? 沒有, 去原型鏈查詢
      		// 都沒有嗎? 報錯
      		p.say();
      結果:
      自己的 jj 33

       

  7. 原型鏈上屬性設定
    1. 先查詢當前物件, 當前物件有就使用當前物件的方法
    2. 當前物件沒有再逐層在原型鏈上查詢, 最先找到那個就使用哪個
    3. 如果找到null都沒找到就輸出undefined
      1. 		function Person(name, age) {
        				this.name = name;
        				this.age = age;
        				this.type = "超人";
        			}
        			// 給原型物件新增新的屬性和方法
        			 Person.prototype.type = "人";
        			var p = new Person("kk", 33);
        			// 自己有嗎? 有, 使用自己的
        			// 自己有嗎? 沒有, 去原型鏈查詢
        			// 都沒有嗎? undefined
        			console.log(p.type);
        
        結果:
        超人
    4. 原型鏈上的屬性:_ _proto_ _(下劃線沒有空格)
      1. 原型鏈上的屬性不會改變,改變的只是物件的屬性
      2. function Person(name, age) {
        		this.name = name;
        		this.age = age;
        	}
        	// 給原型物件新增新的屬性和方法
        	Person.prototype.type = "人";
        	
        	var p = new Person("kk", 33);
        	console.log(p.__proto__.type);
        	// p.__proto__.type = "超人";
        	// 自己有這個屬性嗎? 沒有, 新增
        	p.type = "超人";
        	
        	console.log(p.__proto__.type);
        	console.log(p.type);
        
        結果:
        人
        人
        超人

         

  8. 自定義原型物件
    1. 原型物件是建構函式的一個屬性, 所以我們可以通過修改屬性值的方式來自定義原型物件
    2. function Person(name, age) {
      		this.name = name;
      		this.age = age;
      //		this.say = function () {
      //			console.log('haha');
      //		}
      	}
      	Person.prototype = {
      		constructor: Person, // 手動還原constructor屬性, 保持三角戀關係
      		type: "人",
      		say: function () {
      			console.log(this.name, this.age, this.type);
      		}
      	}
      	var p = new Person("lnj", 33);
      	p.say();
      
      結果:
      lnj 33 人
  9. 原型物件使用建議
    1. 私有成員(一般就是非函式成員)放到建構函式中
    2. 共享成員(一般就是函式)放到原型物件中
    3. 如果重置了 prototype 記得修正 constructor 的指向
      1.  

    4.