国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

《JavaScript程序設(shè)計(jì)》 第7章 軟件構(gòu)架

antz / 561人閱讀

摘要:軟件工程活動(dòng)開發(fā)軟件系統(tǒng)這一任務(wù)包括許多行為。前者要求對象之間具有特定關(guān)系,而后者是有關(guān)安全程序設(shè)計(jì)的這兩都是大型系統(tǒng)構(gòu)建過程中的重要組成部分。第一一個(gè)概念層級結(jié)構(gòu)在本節(jié)后續(xù)部分介紹,后者信息隱藏將在下一節(jié)介紹。

7.1 軟件工程活動(dòng)

開發(fā)軟件系統(tǒng)這一任務(wù)包括許多行為。必須為系統(tǒng)制作業(yè)務(wù)案例,必須收集、明確和整理需求,必須設(shè)計(jì)、協(xié)調(diào)、構(gòu)建、測試、集成、部署和維護(hù)系統(tǒng)本身。軟件工程領(lǐng)域研究的是如何執(zhí)行和協(xié)調(diào)這些活動(dòng),使生成的系統(tǒng)正確、可靠、穩(wěn)健、高效、可維護(hù)、易于理解、好用且經(jīng)濟(jì)節(jié)約。
有趣的是,JavaScript最初是作為一種編寫小型腳本的語言,后來演化為支持非常復(fù)雜的應(yīng)用程序,包括在線字處理器、電子表格、電子郵件客戶端、地圖和游戲。程序員必須利用軟件工程學(xué)方面的知識(shí)、工具和結(jié)果,仔細(xì)而訓(xùn)練有素地開發(fā)這些系統(tǒng)。經(jīng)驗(yàn)豐富的程序員應(yīng)當(dāng)(但不限于)

能夠設(shè)計(jì)、描述、實(shí)現(xiàn)和連接軟件組件;

理解編程選擇的性能影響,也就是說,為什么一種解決方案的運(yùn)行要慢于另一種,后者需要的內(nèi)存多于另一種;

知道如何測試組件;

知道對于某一給定問題已經(jīng)存在哪些解決方案——是內(nèi)置在JavaScript中,還是能從別人那里獲得,這樣,在編寫程序時(shí)就不必再重復(fù)發(fā)明輪子

7.2 面向?qū)ο蟮脑O(shè)計(jì)與編程

到目前為止,我們看到的大多數(shù)腳本都是用來執(zhí)行簡單任務(wù)的,包括計(jì)算身體重量指數(shù)、轉(zhuǎn)換溫度值、判斷一個(gè)數(shù)字是否為質(zhì)數(shù)、設(shè)置電話號(hào)碼格式等等。這些腳本處理的數(shù)據(jù)是次要的,主要關(guān)注的是執(zhí)行這些任務(wù)的算法。我們說這種腳本面向過程。

當(dāng)軟件變得很大時(shí),通常就要轉(zhuǎn)換這個(gè)關(guān)注點(diǎn),將數(shù)據(jù)放在首要地位,而把算法僅僅看作對象愛的行為。通過這種方法會(huì)得到一種面向?qū)ο蟮南到y(tǒng)。

7.2.1 對象族(含Object.create低版本支持)

在前幾章中,我們已經(jīng)看到如何創(chuàng)建幾個(gè)具有相同結(jié)構(gòu)行為的對象,方法就是由同一原型對象來創(chuàng)建這些對象,可能是通過調(diào)用Object.create,也可能是通過定義構(gòu)造器并使用操作符new。因?yàn)閷τ诿總€(gè)方法,我們只需要它的一個(gè)實(shí)例,所以將對象的方法(行為)放在了原型中。讓我們通過一個(gè)例子復(fù)習(xí)一下。計(jì)算機(jī)圖形中,經(jīng)常要操控空間中的點(diǎn)。

那么,可以為這些點(diǎn)指定哪些行為呢?下面是可能會(huì)用到的三個(gè)方法。給定一個(gè)點(diǎn)P,我們希望知道:

p到原點(diǎn)(0,0)的距離;

p到另一個(gè)點(diǎn)q的距離;

p與另一個(gè)點(diǎn)q的中點(diǎn)

/* 一個(gè)點(diǎn)數(shù)據(jù)類型。概要:
 * 
 * var p = new Point(-3,4);
 * var q = new Point(9,9);
 * p.x => -3
 * p.y => 4
 * p.distanceToOrigin() => 5
 * p.distanceTo(q) => 13
 * p.midpointTo(q) => A point object at x=3,y=6.5
 */
var Point = function(x,y) {
    this.x = x || 0;
    this.y = y || 0;
};

Point.prototype.distanceToOrigin = function () {
    return Math.sqrt(this.x*this.x+this.y*this.y);
};
Point.prototype.distanceTo = function (q) {
    var deltaX = q.x - this.x;
    var deltaY = q.y - this.y;
    return Math.sqrt(deltaX * deltaY + deltaX * deltaY);
};
Point.prototype.midpointTo = function (q) {
    return new Point((this.x+q.x)/2 , (this.y+q.y)/2);
};

這里引入了一個(gè)新的JavaScript特性——使用||可以使對象定義變得更靈活?;叵胍幌?,在缺少實(shí)參時(shí),相應(yīng)的形參就是undefined。因?yàn)閡ndefined為假,所以表達(dá)式undefined || x的求值結(jié)果為x。在這種情況下,我們說那些沒有傳送的實(shí)參默認(rèn)為零:

    var p = new Point(5,1);            // 創(chuàng)建(5,1)
    var q = new Point(3);            // 創(chuàng)建(3,0)     因?yàn)樾螀未定義
    var r = new Point();            // 創(chuàng)建(0,0)     因?yàn)閮蓚€(gè)形參都未定義

還可以通過其他方式來增加靈活性。考慮midpointTo函數(shù),可以采用以下方式調(diào)用它:

    var p = new Point(5,1);
    var q = new Point(-20,0);
    var r = p.midpointTo(q);

或者,使用一個(gè)以兩個(gè)點(diǎn)為實(shí)參的中點(diǎn)函數(shù)。但這個(gè)函數(shù)應(yīng)該在哪里呢?Point對象本身是一個(gè)很不錯(cuò)的地方:

    Point.midpoint = function (p,q) {
        return new Point((p.x+q.x)/2,(p.y+q.y)/2);
    };
    // 下面是如何調(diào)用這個(gè)新函數(shù)
    var p = new Point(4,9);
    var q = new Point(-20,0);
    var r = Point.midpoint(p,q);
    alert("("+r.x+","+r.y+")");        //    提示(-8,5)

還可以使用主Point對象來存儲(chǔ)與點(diǎn)有關(guān)的其他數(shù)據(jù)。例如,點(diǎn)(0,0)稱為原點(diǎn)。因?yàn)樗幸粋€(gè)有意義的名字。所以希望在代碼中使用這個(gè)名字??梢詫⒃c(diǎn)定義為Point本身一個(gè)屬性:

    Point.ORIGIN = new Point(0,0);

我們只使用一個(gè)全局變量創(chuàng)建了一個(gè)很有意義的數(shù)據(jù)類型。當(dāng)開始編寫長的多的腳本時(shí),會(huì)進(jìn)一步擴(kuò)展這一技術(shù)??赡軙?huì)編寫一個(gè)大型圖形庫,除了Point類型之外,可能還包含矢量、直線和曲線。這些構(gòu)造函數(shù)中的每一個(gè)都可以是同一全局變量的睡醒,這個(gè)全局變量可以命名為graphics。

JavaScript提供了兩種用于創(chuàng)建對象族的機(jī)制:Object.create直接有效,而操作符new在幕后做了許多工作,所以需要花點(diǎn)時(shí)間才能掌握。這兩種機(jī)制都應(yīng)當(dāng)掌握。你可能和其他許多人一樣,最終喜歡用Object.create來滿足所有對象構(gòu)建需求。如果確實(shí)如此,那就得面對一個(gè)事實(shí):在許多較舊的瀏覽器中不存在Object.create。要在這些瀏覽器中使用這一操作,必須用操作符new來定義它。下面是一種方法:

    /* 如果在這一JavaScript實(shí)現(xiàn)中不存在Object.create,定義他!
     */
    
    if (!Object.create) {
        Object.create = function (proto) {
            var F = function () {};
            F.prototype = proto;
            return new F();
        }
    }

練習(xí):

向本節(jié)的點(diǎn)數(shù)據(jù)類型中增加一個(gè)moveBy函數(shù)。這個(gè)方法有兩個(gè)參數(shù),dx在x方向上移動(dòng)的單位數(shù))和dy在y方向上移動(dòng)的單位數(shù))。因此,將使該點(diǎn)位于(-4,10)。

     // new Point(1,3).move(-5,7)

    var Point = function (x,y) {
        this.x = x || 0;
        this.y = y || 0;
    };
    Point.prototype.moveBy = function (dx,dy) {
        this.x = this.x + dx;
        this.y = this.y + dy;
    };

創(chuàng)建一個(gè)Triangle數(shù)據(jù)類型。三角形應(yīng)當(dāng)具有一個(gè)名為vertices的屬性,它是一個(gè)數(shù)組,包括三個(gè)(x,y)坐標(biāo)。在原型中實(shí)現(xiàn)area函數(shù)和perimeter函數(shù)。

    function Triangle(Ax,Ay,Bx,By,Cx,Cy) {
        this.vertices = [];
        this.vertices[0] = [Ax,Ay];
        this.vertices[1] = [Bx,By];
        this.vertices[2] = [Cx,Cy];
    };

    Triangle.prototype.AB = function () {
        var deleaX = this.vertices[0][0]-this.vertices[1][0];
        var deleaY = this.vertices[0][3]-this.vertices[1][4];
        return Math.floor(Math.sqrt(deleaX * deleaX + deleaY * deleaY));
    };
    Triangle.prototype.AC = function () {
        var deleaX = this.vertices[0][0]-this.vertices[2][0];
        var deleaY = this.vertices[0][5]-this.vertices[2][6];
        return Math.floor(Math.sqrt(deleaX * deleaX + deleaY * deleaY));
    };
    Triangle.prototype.BC = function () {
        var deleaX = this.vertices[1][0]-this.vertices[2][0];
        var deleaY = this.vertices[1][7]-this.vertices[2][8];
        return Math.floor(Math.sqrt(deleaX * deleaX + deleaY * deleaY));
    };
    Triangle.prototype.P = function () {
        return ((this.AB()+this.AC()+this.BC())/2);        // p為半周長(周長的一半)
    };
        
    Triangle.prototype.Perimeter = function () {
        return    this.AB()+this.AC()+this.BC();
    };
    Triangle.prototype.Area = function () {        
        // 海倫公式    S = Math.sqrt(P(P-a)(P-b)(P-c)),abc為三邊長
        var s = Math.sqrt(
            ((this.P()-this.AB()) * (this.P()-this.AC()) * (this.P()-this.BC()))*this.P()
        );
        return s;
    };
    Triangle.prototype.test = function () {                // 檢測坐標(biāo)點(diǎn)是否在同一方向上
        var condition1 = this.vertices[0][0]===this.vertices[1][0] && this.vertices[0][0]===this.vertices[2][0];    // 注意這里不能用嚴(yán)格相等,因?yàn)榈谝粋€(gè)做運(yùn)算之后類型為布爾值,布爾值===數(shù)值結(jié)果為假
        var condition2 = this.vertices[0][9]===this.vertices[1][10] && this.vertices[0][11]===this.vertices[2][12];
        if (condition1 || condition2) {
            return "三點(diǎn)不能一條直線";
        } else {
            return "that"s OK!"
        }
    };
    var triangle = new Triangle(1,5,2,0,5,3);
7.2.2 繼承

我們對"面對對象"的定義是"圍繞對象而非過程來組織程序"。但也有人認(rèn)為,一門程序設(shè)計(jì)語言要真正面向?qū)ο螅ǘ恢皇呛唵蔚?基于對象"),還必須能讓程序員輕松地做到以下兩件事。

定義類型的一個(gè)層級結(jié)構(gòu),其中的子類型繼承其超類型的結(jié)構(gòu)和行為

隔離(或者說保護(hù))一個(gè)對象的部分狀態(tài),使其免受系統(tǒng)中未受授權(quán)部分的干涉。

前者要求對象之間具有特定關(guān)系,而后者是有關(guān)安全程序設(shè)計(jì)的;這兩都是大型系統(tǒng)構(gòu)建過程中的重要組成部分。第一一個(gè)概念(層級結(jié)構(gòu))在本節(jié)后續(xù)部分介紹,后者(信息隱藏)將在下一節(jié)介紹。

類型層級結(jié)構(gòu)的概念。從類型A到類型B的箭頭連線(空心箭頭)表示A是B的子類型,或者說"每個(gè)A都是一個(gè)B"。在這個(gè)圖中,每個(gè)人都是一個(gè)靈長類動(dòng)物,每個(gè)靈長類動(dòng)物都是一個(gè)哺乳動(dòng)物每個(gè)哺乳動(dòng)物都是一個(gè)動(dòng)物,每只鵜鶘(ti2 hu2),如此等等。

創(chuàng)建一個(gè)名為Circle的類型和名為ColorCircle的子類型。彩色圓是一個(gè)染有顏色的圓。我們?yōu)椴噬珗A提供一個(gè)屬于它們自己的行為:變亮函數(shù)!
要求如下:

每個(gè)彩色圓都有其自己的半徑、圓心和色彩屬性。

所有彩色圓應(yīng)當(dāng)共享一個(gè)變亮方法。

所有圓操作(包括已經(jīng)存在和將要添加的操作)都應(yīng)當(dāng)可供彩色圓使用。

那么,如何以JavaScript代碼創(chuàng)建上面這種結(jié)構(gòu)呢?首先要構(gòu)建一個(gè)具有構(gòu)造函數(shù)和原型的圓類型:

    /*
     *    一個(gè)圓數(shù)據(jù)類型。概要:
     */
    var Circle = function (r) {
        this.radius = r;
    };
    Circle.prototype.area = function () {
        return Math.PI * this.radius * this.radius;
    };
    Circle.prototype.circumference = function () {
        return 2 * Math.PI * this.radius;
    };

隨后為ColorCircle開發(fā)構(gòu)造器和原型,請記住,為使彩色圓繼承基礎(chǔ)圓的特性(面積和周長計(jì)算),必須將彩色圓原型鏈接到圓原型。

    var Circle = function (r) {
        this.radius = r;
    };
    Circle.prototype.area = function () {
        return Math.PI * this.radius * this.radius;
    };
    Circle.prototype.circumference = function () {
        return 2 * Math.PI * this.radius;
    };
    // 彩色圓數(shù)據(jù)類型,Circle的一種子類型。概要:
    var ColoredCircle = function (radius,color) {
        this.raidus = raidus;
        this.color = color;
    };
    ColoredCircle.prototype = Object.create(Circle.prototype);    // 原型鏈鏈接
    ColoredCircle.prototype.bright = function (amount) {        // 系數(shù)
        this.color.red *= amount;
        this.color.green *= amount;
        this.color.blue *= amount;
    };
如果創(chuàng)建的類型匯總沒有Object.create函數(shù),那就不要讓CircleColoredCircle成為對象構(gòu)造器,而是使他們成為原型,分別擁有創(chuàng)建方法:
    /*
     *    一種圓數(shù)據(jù)類型。概要:
     * var c = Circle.create(5);
     * c.radius => 5
     * c.area() => 25π
     * c.circumference() => 10π
     */
    var Circle = {};
    
    Circle.create = function (raidus) {
        var c = Object.create(this);
        c.radius = raidus;
        return c;
    };
    Circle.area = function () {
        return Math.PI * this.radius * this.radius;
    };
    Circle.circumference = function () {
        return 2 * Math.PI * this.radius;
    };
    /*
     *    一種彩色圓數(shù)據(jù)類型,Circle的一種子類型。概要:
     * var c = ColoredCircle.create(5,{red:0.2,green:0.8,blue:0.33});
     * c.raidus => 5
     * c.area() => 25π
     * c.perimeter => 10π
     * c.brighten(1.1)changes color to {red:0.22,green:0.88,blue:0.363}
     */
    
    var ColoredCircle = Object.create(Circle);
    
    ColoredCircle.create = function (radius,color) {
        var c = Object.create(this);
        c.radius = radius;
        c.color = color;
        return c;
    };
    ColoredCircle.brighten = function (amount) {
        this.color.red *= amount;
        this.color.green *= amount;
        this.color.blue *= amount;
    };

圖占

7.2.3 信息隱藏

真正面向?qū)Φ某绦蛟O(shè)計(jì)還必須提供一隱藏對象內(nèi)部信息的方法,除了專門設(shè)計(jì)用來操作該對象的方法之外,所有其他代碼都不能訪問這些信息。
例如:有一個(gè)賬戶對象,其中包含一個(gè)不允許為負(fù)數(shù)的余額。你可能會(huì)嘗試通過使用方法放置出現(xiàn)非法余額。

    /*
     *    創(chuàng)建一個(gè)賬戶對象,初始余額為0
     */
    var Account = function (id,owner) {
        this.id = id;
        this.owner = owner;
        this.balance = 0;
    };
    /*
     * 根據(jù)一個(gè)數(shù)額的正負(fù)號(hào),分別在一個(gè)賬戶中存入或提取該數(shù)額
     * 如果轉(zhuǎn)賬操作會(huì)導(dǎo)致余額為負(fù)數(shù),則拒絕該操作,并拋出一個(gè)異常
     */
    Account.prototype.transfer = function (amount) {
        // 正值為存入,負(fù)值為提取
        var tentativeBalance = this.balance + amount;
        if (tentativeBalance < 0) {
            throw "Transaction not accepted.";
        }
        this.balance = tentativeBalance;
    }

只要對賬戶余額字段的所有更新都是通過transfer方法完成的,那余額就不會(huì)變成負(fù)值。但在這里,賬戶對象的用戶全靠自學(xué),因?yàn)槟_本中沒有任何內(nèi)容防止程序員直接寫入balance屬性;

    var a = new Account("123","Alice");        
    a.balance = -10000;

在JavaScript中,有沒有一種方法可以禁止直接改變余額,強(qiáng)制所有修改都必須通過方法調(diào)用進(jìn)行?有的!別忘了,一個(gè)函數(shù)的局部變量(和形參)對外部代碼是不可見的,但在這個(gè)函數(shù)內(nèi)部則是可見的,這里所說的"函數(shù)內(nèi)部"當(dāng)然包括這個(gè)函數(shù)內(nèi)部的嵌入函數(shù)。我們可以余額編程構(gòu)造器內(nèi)部的一個(gè)局部變量:

    var Account = function (id,owner) {
        this.id = id;
        this.owner = owner;
        var balance = 0;
        
        this.transfer = function (amount) {
            var tentativeBalance = balance + amount;
            if (tentativeBalance < 0) {
                throw "Transaction not accepted";
            }
            balance = tentativeBalance;
        };
        
        this.getBalance = function () {
            return balance;
        };
    };

transfergetBalance方法可以訪問變量balance——它們畢竟是閉包,但Account之外的所有代碼都不能訪問。

    var a = new Account("123","Alice");
    a.transfer(100);
    console.log(a.getBalance());            // 100
    a.transfer(-20);
    console.log(a.getBalance());            // 80
    a.transfer(-500);                        // "Uncaught Transaction not accepted"
    console.log(a.getBalance());            // 80
    console.log(a.balance);                    // undefined 因?yàn)闆]有這個(gè)屬性
    a.balance = 8;                            // ?。坑腥嗽谶@里干了什么?
    console.log(a.getBalance());            // 80 數(shù)據(jù)仍然安全
    console.log(a.balance);                    // 8 嘿!太嚇人了,對吧?

我們成功的設(shè)計(jì)了一個(gè)構(gòu)造器,可以創(chuàng)建一些無法直接訪問其余額的對象:用戶必須調(diào)用transfer來改變余額,這是一件好事,因?yàn)閠ransfer方法可以保證不會(huì)發(fā)生透支。

這一級博愛護(hù)也只能達(dá)到這個(gè)程度:我們不能阻止惡意用戶偷偷摸摸地增加一個(gè)balance屬性,然后誘惑不設(shè)戒心的程序員使用它。

為實(shí)現(xiàn)這么一點(diǎn)信息隱藏,我們付出了代價(jià):沒有在原型中放入每個(gè)方法的單個(gè)副本,我們創(chuàng)建的每個(gè)賬戶對象都會(huì)擁有自己的transfer和getBalance函數(shù)。當(dāng)需要許多賬戶對象時(shí),這一代價(jià)可能會(huì)非常高昂。

隱藏一個(gè)對象的屬性是防御式程序設(shè)計(jì)的一個(gè)例子,還有其他一些例子,比如將對象的屬性編程只讀,防止增加或刪除對象的屬性,使用前檢查傳送給函數(shù)的實(shí)參。

下一節(jié)將會(huì)研究ES5中引入的一些屬性,這些屬性允許在處理對象時(shí)采用一些防御式程序設(shè)計(jì)方法。 7.2.4 屬性描述符*

如果你的JavaScript環(huán)境是以ES5為基礎(chǔ),那就可以執(zhí)行一些操作。

調(diào)用Object.preventExtensions(x),禁止向?qū)ο髕添加新屬性,調(diào)用Object.isExtensible(x)可以查看能否添加屬性。

封裝和凍結(jié)對象。Object.seal(x)禁止任何人以任何方式改變x的結(jié)構(gòu);Object.freeze(x)封裝x,使它的所有屬性都變?yōu)橹蛔x。

使各個(gè)屬性都是只讀的、不可枚舉的或不可刪除的。
在一個(gè)ES5對象中,每個(gè)屬性都有一個(gè)屬性描述符,包含最四個(gè)屬性,說明可以如何使用該屬性。

描述符共有兩種。

具名屬性描述符

//         屬性                            含義                                                    默認(rèn)值
//        value                          屬性的值                                                undefined
//        writable            如果為false,在嘗試寫入這一屬性時(shí)會(huì)失敗                                  false
//        enumerable          如果為true,此屬性將顯示在for-in枚舉中                                  false
//        configurable        如果為false,嘗試刪除屬性或者將修改"value"之外的任何屬性時(shí),都會(huì)失敗         false

訪問器屬性描述符(其中兩個(gè)與具名屬性訪問器共用)

//         屬性                            含義                                                        默認(rèn)值
//         get                 一個(gè)沒有實(shí)參的函數(shù),返回一個(gè)值。也可以執(zhí)行某些其他操作                       undefined
//         set                 一個(gè)只有一個(gè)實(shí)參的函數(shù),用于"設(shè)定"一個(gè)值。也可以執(zhí)行其他操作,比如驗(yàn)證          undefined
//         enumerable          如果為true,此屬性將顯示在for-in枚舉中                                     false
//         configurable        如果為false,嘗試刪除屬性或者將修改"value"之外的任何屬性時(shí),都會(huì)失敗            false

通過ES55函數(shù)Object.create、Object.definePropertyObject.defineProperties可以向?qū)傩愿郊用枋龇€可以通過Object.getOwnPropertyDescriptor獲取屬性的已有描述符。如:

    var dog = Object.create(Object.prototype,{
        name:{value:"Spike",configurable:true,writable:true},
        breed:{writable:false,enumerable:true,value:"terrier"}
    });
    Object.defineProperty(dog,"birthday",
        {enumerable:true,value:"2003-05-19"}
    );
    alert(JSON.stringify(Object.getOwnPropertyDescriptor(dog,"breed")));

因?yàn)橛幸粋€(gè)非常方便的JSON.stringify函數(shù),所以這一代嗎會(huì)提示:

    {"value":"terrier","writable":false,"enumerable":true,"configurable":"false"}

如果用一個(gè)對象字面量來創(chuàng)建一個(gè)對象,它的所有屬性都會(huì)獲得一個(gè)描述符,writable=true,enumerable=true,configurable=true:

    var rat = {name:"Cinnamon",species:"norvegicus"};
    alert(JSON.stringify(Object.getOwnPropertyDescriptor(rat,"name")));

這一代碼會(huì)提示:

    {"value":"Cinnamon","writable":true,"enumerable":true,"configurable":true}

具名屬性描述符提供了一種很好的方式,一旦設(shè)定就可以使字段變?yōu)橹蛔x。(如果還有第二個(gè),則檢查Math.PI的屬性描述符。)訪問器屬性描述符可以讓你設(shè)置屬性之前先進(jìn)行檢測(比如在嘗試從賬戶提取金額時(shí)是否會(huì)透支),或者咋讀取一個(gè)屬性時(shí)執(zhí)行操作(比如紀(jì)錄訪問請求)。
下面這個(gè)設(shè)計(jì)的示例展示了訪問器屬性的特性:你準(zhǔn)備對余額字段做一個(gè)簡單賦值,但由于其描述符原因,啟動(dòng)了一個(gè)函數(shù),防止接受一個(gè)負(fù)值。

    var account = (function () {
        var b = 0;
        return Object.create(Object.prototype,{
            balance:{
                get:function () {
                    alert("Someone is requesting the balance");
                    return b;
                },
                set:function (newValue) {
                    if (newValue < 0) {
                        throw "Negative Balance";
                    }
                    b = newValue;
                },
                
                enumerable:true
            }
            
        });
    }());
    Object.preventExtensions(account);

下面是這個(gè)對象的運(yùn)作方式:

    console.log(account.balance);            // 調(diào)用get,提示0
    account.balance = 50;                    // 調(diào)用set
    console.log(account.balance);            // 調(diào)用get,提示50
    account.balance = -20;                    // 調(diào)用set,拋出異常
    console.log(account.balance);            // 調(diào)用get,依舊是50
    account.b = 500;                        // 沒有效果
    console.log(account.balance);            // 50

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

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/83242.html

相關(guān)文章

  • Python 程序構(gòu)架淺析

    摘要:一概念通常的程序的構(gòu)架是指將一個(gè)程序分割為源代碼文件的集合以及將這些部分連接在一起的方法。的程序構(gòu)架可表示為一個(gè)程序就是一個(gè)模塊的系統(tǒng)。它有一個(gè)頂層文件啟動(dòng)后可運(yùn)行程序以及多個(gè)模塊文件用來導(dǎo)入工具庫。導(dǎo)入是中程序結(jié)構(gòu)的重點(diǎn)所在。 一、概念 通常的Python程序的構(gòu)架是指:將一個(gè)程序分割為源代碼文件的集合以及將這些部分連接在一起的方法。 Python的程序構(gòu)架可表示為: showImg...

    hss01248 評論0 收藏0
  • 5:可復(fù)用性的軟件構(gòu)建方法 5.1可復(fù)用性的度量,形態(tài)和外部觀察

    摘要:大綱什么是軟件復(fù)用如何衡量可復(fù)用性可復(fù)用組件的級別和形態(tài)源代碼級別復(fù)用模塊級別的復(fù)用類抽象類接口庫級別的復(fù)用包系統(tǒng)級別的復(fù)用框架對可復(fù)用性的外部觀察類型變化例行分組實(shí)施變更代表獨(dú)立分解常見行為總結(jié)什么是軟件復(fù)用軟件復(fù)用軟件復(fù)用是使用現(xiàn)有軟件 大綱 什么是軟件復(fù)用?如何衡量可復(fù)用性?可復(fù)用組件的級別和形態(tài) 源代碼級別復(fù)用 模塊級別的復(fù)用:類/抽象類/接口 庫級別的復(fù)用:API /包 系...

    mengera88 評論0 收藏0
  • 《Head First JavaScript》讀書筆記

    摘要:設(shè)定的值的時(shí)候,即已自動(dòng)暗示類型。第五章循環(huán)自我重復(fù)的風(fēng)險(xiǎn)數(shù)組用于在單一場所存儲(chǔ)多段數(shù)據(jù)數(shù)組的頁碼稱為鍵,索引只是一種形式特殊的鍵,它是數(shù)值鍵存儲(chǔ)在數(shù)組里的數(shù)據(jù)不一定為相同類型并不要求二維數(shù)組具有相同的行數(shù),但是最好保持一致。 ** 簡介 **書名:《Head First JavaScript》中文譯名:《深入淺出JavaScript》著:Michael Morrison編譯:O’R...

    ztyzz 評論0 收藏0
  • Kali Linux安全測試(177講全) 安全牛苑房宏

    摘要:安全測試講全安全牛苑房宏是基于的發(fā)行版,設(shè)計(jì)用于數(shù)字取證操作系統(tǒng)。 Kali Linux安全測試(177講全) 安全牛苑房宏 Kali Linux是基于Debian的Linux發(fā)行版, 設(shè)計(jì)用于數(shù)字取證操作系統(tǒng)。由Offensive Security Ltd維護(hù)和資助。最先由Offensiv...

    gself 評論0 收藏0
  • 軟件評測師考試學(xué)習(xí)計(jì)劃

    摘要:軟件評測師教程閱讀持續(xù)更新。。。。單元測試又稱模塊測試,是針對軟件設(shè)計(jì)的最小單位程序模塊進(jìn)行正確性檢驗(yàn)的測試工作其目的在于檢查每個(gè)程序單元能否正確實(shí)現(xiàn)詳細(xì)設(shè)計(jì)說明中的模塊功能性能接口和設(shè)計(jì)約束等要求,發(fā)現(xiàn)各模塊內(nèi)部可能存在的各種錯(cuò)誤。 軟件評測師教程閱讀持續(xù)更新。。。。 目錄大綱閱讀時(shí)間完成...

    beanlam 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<