成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

javascript---類與函數(shù)化

waruqi / 3555人閱讀

摘要:函數(shù)用于指定對象的行為。關于屬性只在構造器函數(shù)的原型上才有的屬性并指向該構造器,改寫了的原型對象默認是沒有屬性的。函數(shù)化工廠模式在偽類模式里,構造器函數(shù)不得不重復構造器已經完成的工作。

1.對象適合于收集和管理數(shù)據(jù),容易形成樹型結構。
Javascript包括一個原型鏈特性,允許對象繼承另一對象的屬性。正確的使用它能減少對象的初始化時間和內存消耗。
2.函數(shù)它們是javascript的基礎模塊單元,用于代碼復用、信息隱藏和組合調用。函數(shù)用于指定對象的行為。一般來說,編程就是將一組需求分解成一組函數(shù)和數(shù)據(jù)結構的技能。
3.模塊我們可以使用函數(shù)和閉包來構造模塊。模塊是一個提供接口卻隱藏實現(xiàn)狀態(tài)和實現(xiàn)的函數(shù)或對象。

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

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

在使用自定義類型模式實現(xiàn)繼承的時候,我們只需要將參數(shù)傳遞給構造函數(shù),然后將參數(shù)掛載在實例對象上。其他關于實例對象的方法都不用傳遞參數(shù),因為通過 實例對象調用的方法內部的this都可以訪問到該參數(shù)。掛載在實例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();

在繼承屬性和繼承方法上,我們一共調用了兩次超類構造函數(shù),當通過new調用超類構造函數(shù)創(chuàng)建子類構造函數(shù)的原型時,有一個問題,子類構造函數(shù)的原型對象現(xiàn)在便是超類構造函數(shù)的實例,因此也會有在超類構造函數(shù)為實例對象this添加的屬性,只是值為undefined而已,也就是說通過new調用超類構造器函數(shù)來更改子類改造器的原型時,那么在子類構造器的原型上便會有多余的屬性。這便造成了浪費。而我們需要的其實只是,子類構造器的原型能夠繼承超類構造器原型的方法而已。因此我們需要的,1.創(chuàng)建一個子類構造器原型對象。2.此子類構造器原型繼承自超類構造器的原型。3.因為我們在1中改寫了子類構造器的原型對象,也就是重新創(chuàng)建了原型對象,因此我們需要在新創(chuàng)建的原型對象上添加constructor屬性并將其賦值為子類構造器函數(shù)。
將上面的代碼改寫一些,如下所示。

關于constructor屬性:只在構造器函數(shù)的原型上才有的屬性并指向該構造器,改寫了的原型對象默認是沒有constructor屬性的。

寄生組合式--繼承
function inheritPrototype (subType,superType) {
    var prototype = Object.create(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操作細節(jié),現(xiàn)在看起來沒那么怪異了。但是否真的有所發(fā)現(xiàn):
沒有私有環(huán)境,所有屬性都是公開的。無法訪問父類的方法。難以調試

2.原型

在一個純粹的原型模式中,我們會擯棄類,轉而專注對象?;谠偷睦^承相比基于類的繼承在概念上更簡單:一個新對象可以繼承一個舊對象的屬性。你通過構造有用的對象開始,接著可以構造更多和那個對象類似的對象。這就可以完全避免把一個應用拆解成一系列嵌套抽象類的分類過程

在基于原型的系統(tǒng)中,我們創(chuàng)建的對象,看起來要像我們想要的所有這種類型的對象那樣,然后告訴javascript引擎,我們想要更多像這樣的對象。如果建筑是基于原型的,建筑師會先建一所房子,然后將房子都建成像這種模樣的。

方法Object.creat()作為new操作符的替代方案,使用它來創(chuàng)建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;
}

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

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

在偽類模式里,構造器函數(shù)Cat不得不重復構造器Mammal已經完成的工作。在函數(shù)化模式中那不再需要了,因為構造器Cat將會調用構造器Mammal,讓Mammal去做對象創(chuàng)建中的大部分工作,所有Cat只關注自身的差異即可。

函數(shù)化模式有很大的靈活性。它相比偽類模式不僅帶來的工作更少,還讓我們得到更好的封裝和信息隱藏,以及訪問父類方法的能力。
如果我們用函數(shù)化得樣式去創(chuàng)建對象,并且該對象的所有方法都不用this或that,那么該對象就是持久性的。一個持久性的對象就是一個簡單功能函數(shù)的集合。

私有變量:任何在函數(shù)中定義的變量,都可以認為是私有變量,因為不能在函數(shù)外部訪問這些變量。

閉包

閉包是阻止垃圾回收器將變量從內存中移除的方法,使的在創(chuàng)建變量的執(zhí)行環(huán)境的外面能夠訪問到該變量。

請記住:閉包由函數(shù)創(chuàng)建。每次調用函數(shù)會創(chuàng)建一個唯一的執(zhí)行環(huán)境對象。函數(shù)執(zhí)行完后,執(zhí)行對象就會被丟棄,除非調用者引用了它。當然,如果函數(shù)返回的是數(shù)字,就不能引用函數(shù)的執(zhí)行環(huán)境對象。但是如果函數(shù)返回的是一個更復雜的結構,像是函數(shù)、對象或者數(shù)組,將返回值保存到一個變量上,就創(chuàng)建了一個對執(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ù)化模塊模式有很大的靈活性。它相比構造函數(shù)模式不僅帶來的工作更少,還讓我們得到更好的封裝休息和隱藏,以及訪問父類方法的能力。如果對象的所有狀態(tài)都是私有的,那么該對象就成為一個"防偽(tamper-proof)"對象。該對象的屬性是可以被替換或者刪除,當該對象的完整性不會受到損壞。我們用函數(shù)式的樣式創(chuàng)建一個對象,并且該對象的所有方法都不使用this或者that,那么該對象就是持久性對象。一個持久性對象,就是一個簡單的函數(shù)功能的集合。
一個持久性的對象不會被入侵。訪問一個持久性的對象時,除非有方法授權,否則攻擊者不會訪問對象的內部狀態(tài)。

模塊模式

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

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

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

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

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

增強的模塊模式

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

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

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

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

    return object;
}()

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/78647.html

相關文章

  • TS 類與接口

    摘要:二正文中與的區(qū)別接口只聲明成員方法,不做實現(xiàn)。在中,我們可以采用全新的基于類繼承的模式設計更優(yōu)雅的語義化接口,這是因為中的可以繼承動態(tài)構造的類,這一點和其他的靜態(tài)聲明類的編程語言不同。 一 前言 1.在typescript上遇到過實例化對象的兩種寫法:implement和extends。extends很明顯就是ES6里面的類繼承,那么implement又是做什么的呢?它和extends...

    garfileo 評論0 收藏0
  • Python方法(二) - 類與繼承

    摘要:在類內部的方法中使用時。類的私有方法兩個下劃線開頭,聲明該方法為私有方法,不能在類地外部調用。先在本類中查找調用的方法,找不到才去基類中找。如果在繼承元組中列了一個以上的類,那么它就被稱作多重繼承。 類定義 類對象:創(chuàng)建一個類之后,可以通過類名訪問、改變其屬性、方法 實例對象:類實例化后,可以使用其屬性,可以動態(tài)的為實例對象添加屬性(類似javascript)而不影響類對象。 類...

    DevWiki 評論0 收藏0
  • JavaScript基礎: 類與繼承

    摘要:類的方法相當于之前我們定義在構造函數(shù)的原型上。的構造函數(shù)中調用其目的就是調用父類的構造函數(shù)。是先創(chuàng)建子類的實例,然后在子類實例的基礎上創(chuàng)建父類的屬性。 前言   首先歡迎大家關注我的Github博客,也算是對我的一點鼓勵,畢竟寫東西沒法獲得變現(xiàn),能堅持下去也是靠的是自己的熱情和大家的鼓勵?!   ≡S久已經沒有寫東西了,因為雜七雜八的原因最近一直沒有抽出時間來把寫作堅持下來,感覺和跑步一...

    liuchengxu 評論0 收藏0
  • 《前端竹節(jié)》(3)【原型與對象】

    摘要:從原型對象指向構造函數(shù)畫一條帶箭頭的線。線上標注,表示該原型對象的構造函數(shù)等于。但除此之外,若構造函數(shù)所指的顯示原型對象存在于的原型鏈上,結果也都會為。執(zhí)行構造函數(shù),并將指針綁定到新創(chuàng)建的對象上。 做前端開發(fā)有段時間了,遇到過很多坎,若是要排出個先后順序,那么JavaScript的原型與對象絕對逃不出TOP3。 如果說前端是海,JavaScript就是海里的水 一直以來都想寫篇文章梳理...

    lentrue 評論0 收藏0
  • javascript類與繼承

    摘要:的類與繼承的類與一般的面向對象語言有很大的不同,類的標識是它的構造函數(shù),下面先定義一個類顯然我們可以看出這兩個函數(shù)是不同的,雖然它們實現(xiàn)了相同的功能。利用構造函數(shù)來繼承上面的方法子類顯然無法繼承父類的原型函數(shù),這樣不符合我們使用繼承的目的。 javascript的類與繼承 javascript的類與一般的面向對象語言有很大的不同,類的標識是它的構造函數(shù),下面先定義一個類 var ...

    impig33 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<