javaScript(小細節)你瞭解嗎?instanceof、面向對象的設計模式...

前言

秉着學習、交流、思考、總結的態度,和你們分享這段時間經過閱讀js高級程序設計,發現的一些小細節,小知識點,一塊兒交流,一塊兒進步!查漏補缺ing...javascript

操做符----instanceof

  • 在 JavaScript 中,咱們判斷一個變量的類型經常會用 typeof 運算符,在使用 typeof 運算符時採用引用類型存儲值會出現一個問題,不管引用的是什麼類型的對象,它都返回 "object";
  • instanceof 與 typeof 方法不一樣的是,instanceof 方法幫助開發者明確地確認對象爲某特定類型。
var obj = new Object("some texrt");
console.log(obj instanceof Number);	//輸出 false
console.log(obj instanceof String);	//輸出 true
複製代碼
  • 原理:instanceof是根據引用數據類型的prototype來判斷真實的數據類型。

變量、做用域和內存問題

  • 複製變量值問題前端

    • var num = 2;
      var num1  = num;   // 此時 num1 = 2 複製了num
      var num1 = 3;    //此時num1 = 3,num依然爲2
      複製代碼
    • var obj1 = new Object()
      var obj2 = obj1;
      obj1.name = "MG";
      alert(obj2.name); //此時obj2.name = MG
      複製代碼

    變量對象的指向: obj1建立了一個對象新實例,而後複製給了obj2。此時他們指向的都是堆內存中的同一個對象;當obj1添加name屬性以後,obj2來訪問這個屬性,此時他們訪問的都是存儲在這個堆內存中的一個對象。java

  • 聲明變量算法

    function add(num1,num2){
          var sum = num1+num2;
          return sum;
      }
      var result = add(10,20);
      alert(sum);	// sum is not defined---(var聲明在了局部環境,全局沒法訪問到)
    複製代碼
    function add(num1,num2){
            sum = num1 + num2;
            return sum
        }
        var result = add(10,20)
        alert(sum);	// 30
    複製代碼

    var: var聲明變量會自動被添加到最接近的環境中;在函數內部最接近的環境就是函數的局部環境;若是初始化變量時(代碼塊2所示),沒有使用var關鍵字,因此sum屬於全局環境,那麼當add()執行完畢以後,sum也能夠被訪問到。設計模式

  • 垃圾收集機制函數

    • javascript內部機制具備自動垃圾收集機制。沒必要關心內存分配和回收問題。
    • 標記清除是主流的垃圾收集算法。另一種是引用計數算法。

建立對象

  • 工廠模式學習

    • 這是一種廣爲人知的設計模式,說白了就是實現同一事情的相同代碼,放到一個函數中,之後若是再想實現這個功能,就不須要從新編寫這些代碼了,只要執行當前的函數便可;
    • 弊端:這種模式沒有解決對象識別的問題(即怎樣知道一個對象的類型)用起來仍是不夠靈活;
    function creatPerson(name,age,job){
         var o = new Object();    // 新建一個函數
         o.name = name;
         o.age = age;
         o.job = job;
         o.sayName = function (){
             alert (this.name);
         };   
         return o;
     }
     var person1 = creatPerson("mangguo",21,"fe");
     var person2 = creatPerson("MG",21,"前端");
    複製代碼
  • 構造函數模式ui

    • 典型用法是:new操做符來建立一個新的對象;注意哦,構造函數模式函數名首字母要使用大寫;
    • 弊端:這種構造函數的方式會致使不一樣的做用域鏈和標識符被解析,可是建立新實例的機制仍然是相同的;
    function Person(name,age,job){
         var o = new Object();    // 新建一個函數
         o.name = name;
         o.age = age;
         o.job = job;
         o.sayName = function (){
             alert (this.name);
         }; 
     }
     var person1 = new creatPerson("mangguo",21,"fe");
     var person2 = new creatPerson("MG",21,"前端");
    複製代碼

小夥伴們能夠根據這些實例,本身總結一下上邊的這兩種模式還有什麼不同的地方,進一步鞏固哦!this

  • 原型模式spa

    • hasOwnProperty()方法,能夠用來檢測一個屬性是存在於實例中,仍是存在於原型中;
    • 只有當實例真正重寫原型裏邊的屬性時, hasOwnProperty()纔會返回true;
    • 使用in操做符時,只要經過對象可以訪問到屬性就會返回true;
    • 要注意區別 hasOwnProperty()和 hasPrototyeProperty();當對象屬性重寫以後,hasPrototyeProperty()會返回false;
    • 實例和原型之間的鏈接是一個指針prototype
    function Person(){}
       Person.prototype = {
            name :"MG",
            adress :"beijing",
            sayName :(()=>{ 
            console.log(this.name);
       	  }) 
        }
        var person1 = new Person();
        var person2 = new Person();
        console.log(person1.hasOwnProperty("name"));	// 輸出 false
    	console.log("name" in person1);	// 輸出 true
        person1.name = "mangguo"
        console.log(person1.hasOwnProperty("name"));	// 輸出 true
    	console.log("name" in person1);	// 輸出 true
    複製代碼
  • 構造函數和原型混成的模式

    • 混成模式集兩種模式之長,是目前使用最普遍,認同度最高的一種建立自定義類型的方法;
    • 這樣會最大程度的節省內存,這樣的實例就會不只有本身的實例屬性,還會共享着原型上的屬性和方法,真正的實現1+1>2;
    function Person(name,age,job){
         var o = new Object();    // 新建一個函數
         o.name = name;
         o.age = age;
         o.job = job;
         this.friends = ["Mar","Court"];
     }
     Person.prototype = { 
          constructor:Person, // 這裏是聲明全部實例的共享屬性,constructor'
          sayName:function(){
              alert(this.name);
          }
      }
     var person1 = new creatPerson("mangguo",21,"fe");
     var person2 = new creatPerson("MG",21,"前端");
     person1.friends.push("Van");
     console.log(person1.friends);    // 輸出 "Mar, Court, Van"
     console.log(person2.friends);    // 輸出 "Mar, Court" ,能夠看出修改person1的修改並不會影響到person2
     console.log(person1.friends === person2.friends); // 輸出 false
     console.log(person1.sayName === person2.sayName); // 輸出 true
    
    複製代碼

除了以上幾種模式還有動態原型模式寄生構造函數模式穩妥構造函數模式,但因爲這些都不太經常使用,因此就不介紹了,有興趣的小夥伴能夠參考js紅寶書第六章,裏邊介紹的很詳細哦!

小結

這些是在閱讀紅寶書的過程當中,發現的一些小細節,或許還不夠深刻,須要小夥伴們一塊兒多積累多練習,你們一塊兒學,一塊兒交流進步纔會更快哦,一塊兒加油!持續更新中~

相關文章
相關標籤/搜索