defineProperty

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>屬性的操做</title>
</head>
<body>
    <script type="text/javascript">

        //bind 兼容
        if(!Function.prototype.bind){
            Function.prototype.bind = function(scope){
                var _this = this;
                return function(){
                    _this.call(scope);
                }
            }
        }
        /**
         * getter: 獲取某一個對象的某個屬性以前會回調的這個屬性的getter的鉤子函數
         * setter: 設置某一個對象的某個屬性以前會回調的這個屬性的setter的鉤子函數
         *
         *一個對象的任意屬性在沒有設置setter和getter鉤子函數的時候,默認系統有實現
         */
        var model = {
            name: "star",
            message: "this is message",
            isShow: true
        };
        //
        function observerFactory(model){
            for (var property in model ){
                addOSer(model, property, model[property]);
            }
        }
        function addOSer(model, property, value){
            Object.defineProperty(model, property,{
//            value:"star",
//            writable:false,//是否可寫入
                enumerable: true,//是否可meiju
                configurable: false,//是否之後還能夠配置name屬性
                set:function(nvalue){
                    console.log("進入set設置");
                    this.value = nvalue;
                },
                get:function(){
                    console.log("進入get設置");
                    return this.value;
                }
            });
        }
        observerFactory(model);
        model.name = "xxx";

//        function observerFactory(model){
//            for (var property in model){
//                model.__defineSetter__(property, function(value){
//                    /**
//                     * 問題:property循環出來的一直是isShow,
//                     * 緣由:閉包問題, observerFactory(model);執行了3次,因此property輸出來的一直是isShow
//                     * 解決辦法:用ES6語法,把var改爲let(let指的是:只在當前的做用域有用)
//                     */
//                    console.log("已經進入了"+ property +"屬性的setter");
//                    this.value = value;
//                });
//                model.__defineGetter__(property, function(){
//                    console.log("已經進入了"+ property +"屬性的getter");
//                    return this.value;
//                });
//            }
//        }
//        observerFactory(model);
        /**
         * 咱們能夠在對象的原型鏈上找到這些方法,有些方法不是不存在,而是咱們不關心它,
         * __defineGetter__(定義Getter):只要看到下劃線開頭的屬性或者函數,表明是隱私的意思,不想讓外面訪問或者更改
         * __defineGetter__基於原型鏈的,因此每一個對象都有__defineGetter__方法
         *
         * Object.defineGetter(); 靜態方法 static model,准許咱們使用的
         * __defineGetter__(私有的,能夠調用)和Object.defineGetter()區別:
         * __defineGetter__私有的,能夠調用,可是javascript引擎想告訴咱們最好不要這個用,強行用也是能夠的,
         * javascript提供了Object.defineGetter方法,這個方法和__defineGetter__同樣,推薦使用Object.defineGetter方法
         */
//         model.__defineSetter__("message", function(value){
//             console.log("已經進入了message屬性的setter");
//             this.value = value;
//         });
//         model.__defineGetter__("message", function(){
//             console.log("已經進入了message屬性的getter");
//             /**
//              * (強行使用__defineGetter__):這裏的this指的model自己,
//              */
//             return this.value;
//         });
        /**
         * 返回「undefined
         * 緣由:當咱們訪問message屬性的時候,__defineGetter__的鉤子函數攔截了
         * 當咱們訪問message的時候,會先調用get message鉤子函數,this.value是undefined,
         * 因此返回的是undefined
         *
         *解決辦法:須要先設置在獲取,先setter再getter
         */
//        model.name = "stas";
        console.log(model.name);
    </script>
</body>
</html>
相關文章
相關標籤/搜索