javascript基礎知識分享之類與函數化,javascript基礎知識

來源:互聯網
上載者:User

javascript基礎知識分享之類與函數化,javascript基礎知識

1.對象適合於收集和管理資料,容易形成樹型結構。Javascript包括一個原型鏈特性,允許對象繼承另一對象的屬性。正確的使用它能減少對象的初始化時間和記憶體消耗。2.函數它們是javascript的基礎模組單元,用於代碼複用、資訊隱藏和組合調用。函數用於指定對象的行為。一般來說,編程就是將一組需求分解成一組函數和資料結構的技能。3.模組我們可以使用函數和閉包來構造模組。模組是一個提供介面卻隱藏實現狀態和實現的函數或對象。

1.自訂類型--建構函式模式(偽類模式)

在基於類的系統中,對象是這樣定義的:使用類來描述它是什麼樣的。假如建築是基於類的系統,則建築師會先畫出房子的藍圖,然後房子都按照該藍圖來建造。

在使用自訂類型模式實現繼承的時候,我們只需要將參數傳遞給建構函式,然後將參數掛載在執行個體對象上。其他關於執行個體對象的方法都不用傳遞參數,因為通過 執行個體對象調用的方法內部的this都可以訪問到該參數。掛載在執行個體this對象上的變數稱為執行個體變數。

組合--繼承

function Person (name, age, job) {  // 執行個體變數  this.name = name;  this.age = age;  this.job = job;}Person.prototype.sayName = function () {  alert(this.name);}var person1 = new Person('Nicholas', 29, 'Software Engineer');var person2 = new Person('Greg', 27, 'Doctor');function SuperType (name) {  this.name = name;  this.colors = ['red','blue', 'green'];}SuperType.prototype.sayName = function () {  console.log(this.name);}function SubType (name, age) {  // 繼承屬性  SuperType.call(this,name);  this.age = age;}// 繼承方法SubType.prototype = new SuperType();SubType.prototype.sayAge = function () {  console.log(this.age)}var instance1 = new SubType('Nicholas', 29);instance1.colors.push('black')console.log(instance1.colors);instance1.sayName();instance1.sayAge();var instance2 = new SubType('Greg', 27)console.log(instance2.colors);instance2.sayName();instance2.sayAge();

在繼承屬性和繼承方法上,我們一共調用了兩次超類建構函式,當通過new調用超類建構函式建立子類建構函式的原型時,有一個問題,子類建構函式的原型對象現在便是超類建構函式的執行個體,因此也會有在超類建構函式為執行個體對象this添加的屬性,只是值為undefined而已,也就是說通過new調用超類構造器函數來更改子類改造器的原型時,那麼在子類構造器的原型上便會有多餘的屬性。這便造成了浪費。而我們需要的其實只是,子類構造器的原型能夠繼承超類構造器原型的方法而已。因此我們需要的,

1.建立一個子類構造器原型對象。

2.此子類構造器原型繼承自超類構造器的原型。

3.因為我們在1中改寫了子類構造器的原型對象,也就是重新建立了原型對象,因此我們需要在新建立的原型對象上添加constructor屬性並將其賦值為子類構造器函數。

將上面的代碼改寫一些,如下所示。

關於constructor屬性:只在構造器函數的原型上才有的屬性並指向該構造器,改寫了的原型對象預設是沒有constructor屬性的。

寄生組合式--繼承

function inheritPrototype (subType,superType) {  var prototype = Object.creat(superType.prototype);  prototype.constructor = subType;  subType.prototype = prototype;};function SuperType (name) {  this.name = name;  this.colors = ['red', 'blue', 'green'];}SuperType.prototype.sayName = function () {  console.log(this.name);}function SubType(name, age) {  //繼承屬性  SuperType.call(this,name);  this.age = age;}//繼承方法inheritPrototype(SubType,SuperType);SubType.prototype.sayAge = function () {  console.log(this.age);}var instance = new SubType();

通過隱藏那些所謂的prototype操作細節,現在看起來沒那麼怪異了。但是否真的有所發現:
沒有私人環境,所有屬性都是公開的。無法訪問父類的方法。難以調試

2.原型

在一個純粹的原型模式中,我們會擯棄類,轉而專註對象。基於原型的繼承相比基於類的繼承在概念上更簡單:一個新對象可以繼承一箇舊對象的屬性。你通過構造有用的對象開始,接著可以構造更多和那個對象類似的對象。這就可以完全避免把一個應用拆解成一系列嵌套抽象類別的分類過程
在基於原型的系統中,我們建立的對象,看起來要像我們想要的所有這種類型的對象那樣,然後告訴javascript引擎,我們想要更多像這樣的對象。如果建築是基於原型的,建築師會先建一所房子,然後將房子都建成像這種模樣的。

方法Object.creat()作為new操作符的替代方案,使用它來建立javascript對象時,能增添一種更像是基於原型的感覺。

function myMammal = {  name : 'Herb the Mammal',  get_name : function () {    return this.name;  },  says : function () {    return this.saying || '';  }}var myCat = Object.create(myMammal);myCat.name = 'Henrietta';myCat.saying = 'meow';myCat.purr = function (n) {  var i, s = '';  for (i = 0;i < n; i += 1) {    if(s) {      s += '-'    }    s += 'r';  }  return s;}myCat.get_name = function () {  return this.says + ' ' + this.name + this.says;}

這是一種"差異化繼承"。通過定製一個新的對象,我們指明它與所基於的基本對象的區別。
有時候,它對某些資料結構繼承於其他資料結構的情形非常有用。

3.函數化--原廠模式

在偽類模式裡,構造器函數Cat不得不重複構造器Mammal已經完成的工作。在函數化模式中那不再需要了,因為構造器Cat將會調用構造器Mammal,讓Mammal去做對象建立中的大部分工作,所有Cat只關注自身的差異即可。
函數化模式有很大的靈活性。它相比偽類模式不僅帶來的工作更少,還讓我們得到更好的封裝和資訊隱藏,以及訪問父類方法的能力。

如果我們用函數化得樣式去建立對象,並且該對象的所有方法都不用this或that,那麼該對象就是持久性的。一個持久性的對象就是一個簡易功能函數的集合。

私人變數:任何在函數中定義的變數,都可以認為是私人變數,因為不能在函數外部存取這些變數。

閉包

閉包是阻止記憶體回收行程將變數從記憶體中移除的方法,使的在建立變數的執行環境的外面能夠訪問到該變數。
請記住:閉包由函數建立。每次調用函數會建立一個唯一的執行環境對象。函數執行完後,執行對象就會被丟棄,除非調用者引用了它。當然,如果函數返回的是數字,就不能引用函數的執行環境對象。但是如果函數返回的是一個更複雜的結構,像是函數、對象或者數組,將傳回值儲存到一個變數上,就建立了一個對執行環境的引用。

Function.prototype.method = function (name,func) {  this.prototype[name] = func;  return this; }// 工廠mammal函數var mammal = function (spec) {  var that = {};  that.get_name = function () {    return spec.name;  }  that.says = function (spec) {    return spec.saying || '';  }   return that;}// 工廠cat函數(基於mammal的函數)var cat = function (spec) {  spec.saying = spec.saying || 'meow';  var that = mammal(spec);  that.purr = function (n) {    var i, s = '';    for (i = 0; i < n; i += 1) {      if(s) {        s += '-';      }      s += 'r';    }  }  that.get_name = function () {    return that.says() + ' ' + spec.name + ' ' + that.says();  }  return that;}// 建立myCat對象var myCat = cat({name: 'Henrietta'});Object.method('superior',function (name) {  var that = this,    method = that[name];  return function () {    return method.apply(that, arguments)  }})// 工廠coolcat函數(基於cat函數)var coolcat = function (spec) {  var that = cat(spec),    super_get_name = that.superior('get_name');  that.get_name = function (n) {    return 'like ' + super_get_name() + ' baby';  }  return that;}var myCoolCat = coolcat({name : 'Bix'});var name = myCoolCat.get_name();

函數化模組模式有很大的靈活性。它相比建構函式模式不僅帶來的工作更少,還讓我們得到更好的封裝休息和隱藏,以及訪問父類方法的能力。如果對象的所有狀態都是私人的,那麼該對象就成為一個"防偽(tamper-proof)"對象。該對象的屬性是可以被替換或者刪除,當該對象的完整性不會受到損壞。我們用函數式的樣式建立一個對象,並且該對象的所有方法都不使用this或者that,那麼該對象就是持久性對象。一個持久性對象,就是一個簡單的函數功能的集合。
一個持久性的對象不會被入侵。訪問一個持久性的對象時,除非有方法授權,否則攻擊者不會訪問對象的內部狀態。

模組模式

前面的模式是用於 自訂類型建立私人變數和特權方法的。而道格拉斯所說的模組模式則是為 單例建立私人變數和特權方法。所謂單例指的就是只有一個執行個體的對象。(就是用對象字面量標記法建立的對象)

var singleton = function () {  // 私人變數和函數  var privateVariable = 10;  function privateFunction () {    return false;  }  //特權/公有方法和屬性  return {    publicProvperty: true;    publicMethod: function () {      privateVariable++;      return privateFunction();    }  }}

從本質上講,這個對象字面量定義的是單例的公用介面。這種模式在需要對單例進行某些初始化,同時又需要維護其私人變數時非常有用。簡言之,如果必須建立一個對象並以某些資料對其進行初始化,同時還要公開一些能夠訪問這些私人資料的方法。

增強模組模式

這種增強模組模式適合那些單例必須是某種類型的執行個體,同時還必須添加某些屬性和方法對其加以增強例子。

var singleton = function () {  // 私人變數和函數  var privateVariable = 10;  function privateFunction () {    return false  }  // 建立對象  var object = new CustomType();  // 添加特權/公有屬性和方法  object.publicProperty = true;  object.publicMethod = function () {    privateVariable++;    return privateFunction();  }  return object;}()

您可能感興趣的文章:
  • 由淺到深瞭解JavaScript類
  • 收集的幾個不錯的javascript類小例子
  • 一個簡單的javascript類定義例子
  • JavaScript類和繼承 constructor屬性
  • javascript 物件導向的JavaScript類
  • javascript 圖片輪換 函數化繼承
  • jquery下組織javascript代碼(js函數化)
  • JavaScript類和繼承 prototype屬性
  • JavaScript類和繼承 this屬性使用說明

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.