<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      深入理解JavaScript系列(26):設計模式之構造函數模式

      2012-02-21 08:59  湯姆大叔  閱讀(28058)  評論(14)    收藏  舉報

      介紹

      構造函數大家都很熟悉了,不過如果你是新手,還是有必要來了解一下什么叫構造函數的。構造函數用于創建特定類型的對象——不僅聲明了使用的對象,構造函數還可以接受參數以便第一次創建對象的時候設置對象的成員值。你可以自定義自己的構造函數,然后在里面聲明自定義類型對象的屬性或方法。

      基本用法

      在JavaScript里,構造函數通常是認為用來實現實例的,JavaScript沒有類的概念,但是有特殊的構造函數。通過new關鍵字來調用定義的否早函數,你可以告訴JavaScript你要創建一個新對象并且新對象的成員聲明都是構造函數里定義的。在構造函數內部,this關鍵字引用的是新創建的對象。基本用法如下:

      function Car(model, year, miles) {
      this.model = model;
      this.year = year;
      this.miles = miles;
      this.output= function () {
      return this.model + "走了" + this.miles + "公里";
      };
      }

      var tom= new Car("大叔", 2009, 20000);
      var dudu= new Car("Dudu", 2010, 5000);

      console.log(tom.output());
      console.log(dudu.output());

      上面的例子是個非常簡單的構造函數模式,但是有點小問題。首先是使用繼承很麻煩了,其次output()在每次創建對象的時候都重新定義了,最好的方法是讓所有Car類型的實例都共享這個output()方法,這樣如果有大批量的實例的話,就會節約很多內存。

      解決這個問題,我們可以使用如下方式:

      function Car(model, year, miles) {
      this.model = model;
      this.year = year;
      this.miles = miles;
      this.output= formatCar;
      }

      function formatCar() {
      return this.model + "走了" + this.miles + "公里";
      }

      這個方式雖然可用,但是我們有如下更好的方式。

      構造函數與原型

      JavaScript里函數有個原型屬性叫prototype,當調用構造函數創建對象的時候,所有該構造函數原型的屬性在新創建對象上都可用。按照這樣,多個Car對象實例可以共享同一個原型,我們再擴展一下上例的代碼:

      function Car(model, year, miles) {
      this.model = model;
      this.year = year;
      this.miles = miles;
      }

      /*
      注意:這里我們使用了Object.prototype.方法名,而不是Object.prototype
      主要是用來避免重寫定義原型prototype對象
      */
      Car.prototype.output= function () {
      return this.model + "走了" + this.miles + "公里";
      };

      var tom = new Car("大叔", 2009, 20000);
      var dudu = new Car("Dudu", 2010, 5000);

      console.log(tom.output());
      console.log(dudu.output());

      這里,output()單實例可以在所有Car對象實例里共享使用。

      另外:我們推薦構造函數以大寫字母開頭,以便區分普通的函數。

      只能用new嗎?

      上面的例子對函數car都是用new來創建對象的,只有這一種方式么?其實還有別的方式,我們列舉兩種:

      function Car(model, year, miles) {
      this.model = model;
      this.year = year;
      this.miles = miles;
      // 自定義一個output輸出內容
      this.output = function () {
      return this.model + "走了" + this.miles + "公里";
      }
      }

      //方法1:作為函數調用
      Car("大叔", 2009, 20000); //添加到window對象上
      console.log(window.output());

      //方法2:在另外一個對象的作用域內調用
      var o = new Object();
      Car.call(o, "Dudu", 2010, 5000);
      console.log(o.output());

      該代碼的方法1有點特殊,如果不適用new直接調用函數的話,this指向的是全局對象window,我們來驗證一下:

      //作為函數調用
      var tom = Car("大叔", 2009, 20000);
      console.log(typeof tom); // "undefined"
      console.log(window.output()); // "大叔走了20000公里"

      這時候對象tom是undefined,而window.output()會正確輸出結果,而如果使用new關鍵字則沒有這個問題,驗證如下:

      //使用new 關鍵字
      var tom = new Car("大叔", 2009, 20000);
      console.log(typeof tom); // "object"
      console.log(tom.output()); // "大叔走了20000公里"

      強制使用new

      上述的例子展示了不使用new的問題,那么我們有沒有辦法讓構造函數強制使用new關鍵字呢,答案是肯定的,上代碼:

      function Car(model, year, miles) {
      if (!(this instanceof Car)) {
      return new Car(model, year, miles);
      }
      this.model = model;
      this.year = year;
      this.miles = miles;
      this.output = function () {
      return this.model + "走了" + this.miles + "公里";
      }
      }

      var tom = new Car("大叔", 2009, 20000);
      var dudu = Car("Dudu", 2010, 5000);

      console.log(typeof tom); // "object"
      console.log(tom.output()); // "大叔走了20000公里"
      console.log(typeof dudu); // "object"
      console.log(dudu.output()); // "Dudu走了5000公里"

      通過判斷this的instanceof是不是Car來決定返回new Car還是繼續執行代碼,如果使用的是new關鍵字,則(this instanceof Car)為真,會繼續執行下面的參數賦值,如果沒有用new,(this instanceof Car)就為假,就會重新new一個實例返回。

      原始包裝函數

      JavaScript里有3中原始包裝函數:number, string, boolean,有時候兩種都用:

      // 使用原始包裝函數
      var s = new String("my string");
      var n = new Number(101);
      var b = new Boolean(true);


      // 推薦這種
      var s = "my string";
      var n = 101;
      var b = true;

      推薦,只有在想保留數值狀態的時候使用這些包裝函數,關于區別可以參考下面的代碼:

      // 原始string
      var greet = "Hello there";
      // 使用split()方法分割
      greet.split(' ')[0]; // "Hello"
      //
      給原始類型添加新屬性不會報錯
      greet.smile = true;
      // 單沒法獲取這個值(18章ECMAScript實現里我們講了為什么)
      console.log(typeof greet.smile); // "undefined"

      // 原始string
      var greet = new String("Hello there");
      // 使用split()方法分割
      greet.split(' ')[0]; // "Hello"
      //
      給包裝函數類型添加新屬性不會報錯
      greet.smile = true;
      // 可以正常訪問新屬性
      console.log(typeof greet.smile); // "boolean"

      總結

      本章主要講解了構造函數模式的使用方法、調用方法以及new關鍵字的區別,希望大家在使用的時候有所注意。

      參考:http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#constructorpatternjavascript

      同步與推薦

      本文已同步至目錄索引:深入理解JavaScript系列

      深入理解JavaScript系列文章,包括了原創,翻譯,轉載等各類型的文章,如果對你有用,請推薦支持一把,給大叔寫作的動力。

      主站蜘蛛池模板: av色蜜桃一区二区三区| 亚洲欧美综合中文| 久久天天躁夜夜躁狠狠| 午夜欧美精品久久久久久久 | 亚洲跨种族黑人xxxxx| 国产91久久精品成人看| 国产a在亚洲线播放| 日韩激情一区二区三区| 国产不卡的一区二区三区| 亚洲av永久无码精品漫画| 精品人妻无码一区二区三区性| 蜜芽久久人人超碰爱香蕉| 国产成人综合久久亚洲精品| 午夜欧美日韩在线视频播放 | 国产午夜美女福利短视频| 久久蜜臀av一区三区| 免费人妻无码不卡中文字幕18禁 | 亚洲熟妇色xxxxx欧美老妇| 久久精品国产久精国产| 久久中文字幕一区二区| 欧美人与动zozo在线播放| 1000部拍拍拍18勿入免费视频| 临西县| 久久97超碰色中文字幕蜜芽| 四虎永久播放地址免费| 一本一本久久a久久综合精品 | 国产一区二区三区小说| 波多野结衣在线精品视频| 日本午夜精品一区二区三区电影| 国内精品大秀视频日韩精品| 亚洲AV永久无码精品秋霞电影影院 | 国产做爰xxxⅹ久久久精华液 | 年日韩激情国产自偷亚洲| 国产国产乱老熟女视频网站97| 熟女系列丰满熟妇AV| 国产精品麻豆成人av网| 一区二区三区四区在线不卡高清| 免费吃奶摸下激烈视频| 蜜桃亚洲一区二区三区四| 精品在免费线中文字幕久久| 国产精品夜夜春夜夜爽久久小说 |