Javascript 進階 封裝

來源:互聯網
上載者:User

 

js中處處是對象,物件導向的第一步當然就是封裝了,由於Js中沒有類的概念,所以封裝起來也比較麻煩,下面介紹兩種js的封裝。

1、使用約定優先的原則,將所有的私人變數以_開頭

 

 <script type=text/javascript>        /**         * 使用約定優先的原則,把所有的私人變數都使用_開頭         */        var Person = function (no, name, age)        {            this.setNo(no);            this.setName(name);            this.setAge(age);        }        Person.prototype = {            constructor: Person,            checkNo: function (no)            {                if (!no.constructor == string || no.length != 4)                    throw new Error(學號必須為4位);            },            setNo: function (no)            {                this.checkNo(no);                this._no = no;            }, getNo: function ()            {                return this._no;            }, setName: function (name)            {                this._name = name;            }, getName: function ()            {                return this._name;            }, setAge: function (age)            {                this._age = age;            }, getAge: function ()            {                return this._age;            }, toString: function ()            {                return no =  + this._no +  , name =  + this._name +  , age =  + this._age;            }        };        var p1 = new Person(0001, 鴻洋, 22);        console.log(p1.toString());        //no = 0001 , name = 鴻洋 , age = 22        p1.setNo(0003);        console.log(p1.toString());      //no = 0003 , name = 鴻洋 , age = 22        p1.no = 0004;        p1._no = 0004;        console.log(p1.toString());    //no = 0004 , name = 鴻洋 , age = 22    </script>

看完代碼,是不是有種被坑的感覺,僅僅把所有的變數以_開頭,其實還是可以直接存取的,這能叫封裝麼,當然了,說了是約定優先嘛,這種方式還是不錯的,最起碼成員變數的getter,setter方法都是prototype中,並非存在對象中,總體來說還是個不錯的選擇。如果你覺得,這不行,必須嚴格實現封裝,那麼看第二種方式。

2、嚴格實現封裝

 

<script type=text/javascript>        /**         *  使用這種方式雖然可以嚴格實現封裝,但是帶來的問題是get和set方法都不能儲存在prototype中,都是儲存在對象中的         * 這樣無形中就增加了開銷         */        var Person = function (no, name, age)        {            var _no , _name, _age ;            var checkNo = function (no)            {                if (!no.constructor == string || no.length != 4)                    throw new Error(學號必須為4位);            };            this.setNo = function (no)            {                checkNo(no);                _no = no;            };            this.getNo = function ()            {                return _no;            }            this.setName = function (name)            {               _name = name;            }            this.getName = function ()            {                return _name;            }            this.setAge = function (age)            {                _age = age;            }            this.                    getAge = function ()            {                return _age;            }            this.setNo(no);            this.setName(name);            this.setAge(age);        }        Person.prototype = {            constructor: Person,            toString: function ()            {                return no =  + this.getNo() +  , name =  + this.getName() +  , age =  + this.getAge();            }        }        ;        var p1 = new Person(0001, 鴻洋, 22);        console.log(p1.toString());        //no = 0001 , name = 鴻洋 , age = 22        p1.setNo(0003);        console.log(p1.toString());      //no = 0003 , name = 鴻洋 , age = 22        p1.no = 0004;        console.log(p1.toString());    //no = 0003 , name = 鴻洋 , age = 22    </script>

看上面的代碼,去掉了this.屬性名稱,嚴格的實現了封裝,只能通過getter,setter訪問成員變數了,但是存在一個問題,所有的方法都存在對象中,增加了記憶體的開銷。

 

 

3、以閉包的方式封裝

 

<script type=text/javascript>        /**         *  使用這種方式雖然可以嚴格實現封裝,但是帶來的問題是get和set方法都不能儲存在prototype中,都是儲存在對象中的         * 這樣無形中就增加了開銷         */        var Person = (function ()        {            var checkNo = function (no)            {                if (!no.constructor == string || no.length != 4)                    throw new Error(學號必須為4位);            };            //共用變數            var times = 0;            return function (no, name, age)            {                console.log(times++);    // 0 ,1 , 2                var no , name , age;                this.setNo = function (no)                {                    checkNo(no);                    this._no = no;                };                this.getNo = function ()                {                    return this._no;                }                this.setName = function (name)                {                    this._name = name;                }                this.getName = function ()                {                    return this._name;                }                this.setAge = function (age)                {                    this._age = age;                }                this.                        getAge = function ()                {                    return this._age;                }                this.setNo(no);                this.setName(name);                this.setAge(age);            }        })();        Person.prototype = {            constructor: Person,            toString: function ()            {                return no =  + this._no +  , name =  + this._name +  , age =  + this._age;            }        }        ;        var p1 = new Person(0001, 鴻洋, 22);        var p2 = new Person(0002, abc, 23);        var p3 = new Person(0003, aobama, 24);        console.log(p1.toString());        //no = 0001 , name = 鴻洋 , age = 22        console.log(p2.toString());      //no = 0002 , name = abc , age = 23        console.log(p3.toString());    //no = 0003 , name = aobama , age = 24    </script>

上述代碼,js引擎載入完後,會直接執行Student = 立即執行函數,然後此函數返回了一個子函數,這個子函數才是new Student所調用的建構函式,又因為子函數中保持了對立即執行函數中checkNo(no) ,times的引用,(很明顯的閉包)所以對於checkNo和times,是所有Student對象所共有的,建立3個對象後,times分別為0,1,2 。這種方式的好處是,可以使Student中需要複用的方法和屬性做到私人且對象間共用。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.