亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

javascript基礎(chǔ)知識分享之類與函數(shù)化

 更新時(shí)間:2016年02月13日 09:36:50   投稿:hebedich  
在C++中是以class來聲明一個(gè)類的,JavaScript與C++不同,它使用了與函數(shù)一樣的function來聲明,這就讓許多學(xué)Jscript的朋友把類與函數(shù)混在一起了,在Jscript中函數(shù)與類確實(shí)有些混,但使用久了自然會(huì)理解,這篇文章是針對想進(jìn)攻面向?qū)ο缶幊痰呐笥讯鴮?就不打算討論得太深了
1.對象適合于收集和管理數(shù)據(jù),容易形成樹型結(jié)構(gòu)。
Javascript包括一個(gè)原型鏈特性,允許對象繼承另一對象的屬性。正確的使用它能減少對象的初始化時(shí)間和內(nèi)存消耗。
2.函數(shù)它們是javascript的基礎(chǔ)模塊單元,用于代碼復(fù)用、信息隱藏和組合調(diào)用。函數(shù)用于指定對象的行為。一般來說,編程就是將一組需求分解成一組函數(shù)和數(shù)據(jù)結(jié)構(gòu)的技能。
3.模塊我們可以使用函數(shù)和閉包來構(gòu)造模塊。模塊是一個(gè)提供接口卻隱藏實(shí)現(xiàn)狀態(tài)和實(shí)現(xiàn)的函數(shù)或?qū)ο蟆?

1.自定義類型--構(gòu)造函數(shù)模式(偽類模式)

在基于類的系統(tǒng)中,對象是這樣定義的:使用類來描述它是什么樣的。假如建筑是基于類的系統(tǒng),則建筑師會(huì)先畫出房子的藍(lán)圖,然后房子都按照該藍(lán)圖來建造。

在使用自定義類型模式實(shí)現(xiàn)繼承的時(shí)候,我們只需要將參數(shù)傳遞給構(gòu)造函數(shù),然后將參數(shù)掛載在實(shí)例對象上。其他關(guān)于實(shí)例對象的方法都不用傳遞參數(shù),因?yàn)橥ㄟ^ 實(shí)例對象調(diào)用的方法內(nèi)部的this都可以訪問到該參數(shù)。掛載在實(shí)例this對象上的變量稱為實(shí)例變量。

組合--繼承

function Person (name, age, job) {
  // 實(shí)例變量
  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();

在繼承屬性和繼承方法上,我們一共調(diào)用了兩次超類構(gòu)造函數(shù),當(dāng)通過new調(diào)用超類構(gòu)造函數(shù)創(chuàng)建子類構(gòu)造函數(shù)的原型時(shí),有一個(gè)問題,子類構(gòu)造函數(shù)的原型對象現(xiàn)在便是超類構(gòu)造函數(shù)的實(shí)例,因此也會(huì)有在超類構(gòu)造函數(shù)為實(shí)例對象this添加的屬性,只是值為undefined而已,也就是說通過new調(diào)用超類構(gòu)造器函數(shù)來更改子類改造器的原型時(shí),那么在子類構(gòu)造器的原型上便會(huì)有多余的屬性。這便造成了浪費(fèi)。而我們需要的其實(shí)只是,子類構(gòu)造器的原型能夠繼承超類構(gòu)造器原型的方法而已。因此我們需要的,

1.創(chuàng)建一個(gè)子類構(gòu)造器原型對象。

2.此子類構(gòu)造器原型繼承自超類構(gòu)造器的原型。

3.因?yàn)槲覀冊?中改寫了子類構(gòu)造器的原型對象,也就是重新創(chuàng)建了原型對象,因此我們需要在新創(chuàng)建的原型對象上添加constructor屬性并將其賦值為子類構(gòu)造器函數(shù)。

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

關(guān)于constructor屬性:只在構(gòu)造器函數(shù)的原型上才有的屬性并指向該構(gòu)造器,改寫了的原型對象默認(rèn)是沒有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操作細(xì)節(jié),現(xiàn)在看起來沒那么怪異了。但是否真的有所發(fā)現(xiàn):
沒有私有環(huán)境,所有屬性都是公開的。無法訪問父類的方法。難以調(diào)試

2.原型

在一個(gè)純粹的原型模式中,我們會(huì)擯棄類,轉(zhuǎn)而專注對象?;谠偷睦^承相比基于類的繼承在概念上更簡單:一個(gè)新對象可以繼承一個(gè)舊對象的屬性。你通過構(gòu)造有用的對象開始,接著可以構(gòu)造更多和那個(gè)對象類似的對象。這就可以完全避免把一個(gè)應(yīng)用拆解成一系列嵌套抽象類的分類過程
在基于原型的系統(tǒng)中,我們創(chuàng)建的對象,看起來要像我們想要的所有這種類型的對象那樣,然后告訴javascript引擎,我們想要更多像這樣的對象。如果建筑是基于原型的,建筑師會(huì)先建一所房子,然后將房子都建成像這種模樣的。

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

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;
}

這是一種"差異化繼承"。通過定制一個(gè)新的對象,我們指明它與所基于的基本對象的區(qū)別。
有時(shí)候,它對某些數(shù)據(jù)結(jié)構(gòu)繼承于其他數(shù)據(jù)結(jié)構(gòu)的情形非常有用。

3.函數(shù)化--工廠模式

在偽類模式里,構(gòu)造器函數(shù)Cat不得不重復(fù)構(gòu)造器Mammal已經(jīng)完成的工作。在函數(shù)化模式中那不再需要了,因?yàn)闃?gòu)造器Cat將會(huì)調(diào)用構(gòu)造器Mammal,讓Mammal去做對象創(chuàng)建中的大部分工作,所有Cat只關(guān)注自身的差異即可。
函數(shù)化模式有很大的靈活性。它相比偽類模式不僅帶來的工作更少,還讓我們得到更好的封裝和信息隱藏,以及訪問父類方法的能力。

如果我們用函數(shù)化得樣式去創(chuàng)建對象,并且該對象的所有方法都不用this或that,那么該對象就是持久性的。一個(gè)持久性的對象就是一個(gè)簡單功能函數(shù)的集合。

私有變量:任何在函數(shù)中定義的變量,都可以認(rèn)為是私有變量,因?yàn)椴荒茉诤瘮?shù)外部訪問這些變量。

閉包

閉包是阻止垃圾回收器將變量從內(nèi)存中移除的方法,使的在創(chuàng)建變量的執(zhí)行環(huán)境的外面能夠訪問到該變量。
請記住:閉包由函數(shù)創(chuàng)建。每次調(diào)用函數(shù)會(huì)創(chuàng)建一個(gè)唯一的執(zhí)行環(huán)境對象。函數(shù)執(zhí)行完后,執(zhí)行對象就會(huì)被丟棄,除非調(diào)用者引用了它。當(dāng)然,如果函數(shù)返回的是數(shù)字,就不能引用函數(shù)的執(zhí)行環(huán)境對象。但是如果函數(shù)返回的是一個(gè)更復(fù)雜的結(jié)構(gòu),像是函數(shù)、對象或者數(shù)組,將返回值保存到一個(gè)變量上,就創(chuàng)建了一個(gè)對執(zhí)行環(huán)境的引用。

Function.prototype.method = function (name,func) {
  this.prototype[name] = func;
  return this; 
}
// 工廠mammal函數(shù)
var mammal = function (spec) {
  var that = {};

  that.get_name = function () {
    return spec.name;
  }
  that.says = function (spec) {
    return spec.saying || '';
  } 

  return that;
}

// 工廠cat函數(shù)(基于mammal的函數(shù))
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;
}

// 創(chuàng)建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函數(shù)(基于cat函數(shù))
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();

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

模塊模式

前面的模式是用于 自定義類型創(chuàng)建私有變量和特權(quán)方法的。而道格拉斯所說的模塊模式則是為 單例創(chuàng)建私有變量和特權(quán)方法。所謂單例指的就是只有一個(gè)實(shí)例的對象。(就是用對象字面量表示法創(chuàng)建的對象)

var singleton = function () {
  // 私有變量和函數(shù)
  var privateVariable = 10;

  function privateFunction () {
    return false;
  }
  //特權(quán)/公有方法和屬性
  return {
    publicProvperty: true;

    publicMethod: function () {
      privateVariable++;
      return privateFunction();
    }
  }
}

從本質(zhì)上講,這個(gè)對象字面量定義的是單例的公共接口。這種模式在需要對單例進(jìn)行某些初始化,同時(shí)又需要維護(hù)其私有變量時(shí)非常有用。簡言之,如果必須創(chuàng)建一個(gè)對象并以某些數(shù)據(jù)對其進(jìn)行初始化,同時(shí)還要公開一些能夠訪問這些私有數(shù)據(jù)的方法。

增強(qiáng)的模塊模式

這種增強(qiáng)的模塊模式適合那些單例必須是某種類型的實(shí)例,同時(shí)還必須添加某些屬性和方法對其加以增強(qiáng)的例子。

var singleton = function () {
  // 私有變量和函數(shù)
  var privateVariable = 10;

  function privateFunction () {
    return false
  }
  // 創(chuàng)建對象
  var object = new CustomType();

  // 添加特權(quán)/公有屬性和方法
  object.publicProperty = true;
  object.publicMethod = function () {
    privateVariable++;
    return privateFunction();
  }

  return object;
}()

相關(guān)文章

  • javascript創(chuàng)建對象的幾種模式介紹

    javascript創(chuàng)建對象的幾種模式介紹

    下面小編就為大家?guī)硪黄猨avascript創(chuàng)建對象的幾種模式介紹。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考
    2016-05-05
  • javascript學(xué)習(xí)筆記(七)Ajax和Http狀態(tài)碼

    javascript學(xué)習(xí)筆記(七)Ajax和Http狀態(tài)碼

    這篇文章主要介紹了javascript中Ajax和Http狀態(tài)碼,非常的簡單實(shí)用,有需要的朋友可以參考下
    2014-10-10
  • Javascript全局變量var與不var的區(qū)別深入解析

    Javascript全局變量var與不var的區(qū)別深入解析

    這篇文章主要介紹了Javascript全局變量var與不var的區(qū)別。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-12-12
  • js獲取height和width的方法說明

    js獲取height和width的方法說明

    js獲取height和width屬性的值在日常開發(fā)中很常見,于是本人搜集整理了一下,感興趣的朋友可以參考下
    2013-01-01
  • JavaScript split()使用方法與示例

    JavaScript split()使用方法與示例

    split定義和用法, 主要是將字符串分割為數(shù)組,再進(jìn)行輸出等操作,比較常用的函數(shù)。
    2009-12-12
  • javascript之Boolean類型對象

    javascript之Boolean類型對象

    本文主要介紹javascript中的Boolean類型對象,Boolean對象非常簡單,卻非常有用,希望能給大家做一個(gè)參考。
    2016-06-06
  • 一文搞懂JavaScript中原型與原型鏈

    一文搞懂JavaScript中原型與原型鏈

    js中的原型與原型鏈應(yīng)該是老生常談的話題了,在前端面試中基本都是必問的一個(gè)問題,但是很多人還是稀里糊涂的,只知道其表層含義。本文將帶大家深入了解JavaScript中的原型與原型鏈,感興趣的可以學(xué)習(xí)一下
    2022-05-05
  • 淺談JavaScript數(shù)組簡介

    淺談JavaScript數(shù)組簡介

    本文主要是給大家簡單介紹了Array的相關(guān)基礎(chǔ)知識,到這里也算是能對Array有更全面的理解了,希望大家能夠喜歡,后續(xù)我們將繼續(xù)介紹關(guān)于array的內(nèi)容。
    2021-11-11
  • 完全不用基礎(chǔ)的HTML5入門篇教程

    完全不用基礎(chǔ)的HTML5入門篇教程

    HTML的全稱為超文本標(biāo)記語言,是一種標(biāo)記語言。它包括一系列標(biāo)簽.通過這些標(biāo)簽可以將網(wǎng)絡(luò)上的文檔格式統(tǒng)一,使分散的Internet資源連接為一個(gè)邏輯整體。HTML文本是由HTML命令組成的描述性文本,HTML命令可以說明文字,圖形、動(dòng)畫、聲音、表格、鏈接等
    2022-03-03
  • Javascript this 函數(shù)深入詳解

    Javascript this 函數(shù)深入詳解

    這篇文章主要介紹了Javascript this 函數(shù)深入詳解的相關(guān)資料,這里詳細(xì)討論了this 的用法,需要的朋友可以參考下
    2016-12-12

最新評論