back to devpro   download
(function(Object){
    
    // (C) WebReflection - Mit Style License
    
    function createGetter(callback) {
        return function get() {
            if (arguments.length) {
                throw "setting a property that has only a getter";
            }
            return callback.call(this);
        };
    }
    
    function createSetter(callback) {
        return function set(value) {
            callback.call(this, value);
            // a setter does not return anything
            // since 123 === (obj.setter = 123)
            // value is returned by design
            return value;
        };
    }
    
    function createGetterAndSetter(get, set) {
        return function getOrSet(value) {
            // obj.setter(undefined)
            // is still a setter
            // same as obj.setter = undefined in ES5
            if (arguments.length) {
                set.call(this, value);
                // a setter does not return anything
                // since 123 === (obj.setter = 123)
                // value is returned by design
                return value;
            } else {
                return get.call(this);
            }
        };
    }
    
    function defineHybridProperty(object, property, descriptor) {
        var
            get = hasOwnProperty.call(descriptor, "get") && descriptor.get,
            set = hasOwnProperty.call(descriptor, "set") && descriptor.set
        ;
        if (hasOwnProperty.call(descriptor, "value")) {
            if (get || set) {
                throw "Invalid property. 'value' present on property with getter or setter";
            }
            object[property] = descriptor.value;
        } else if (get && set) {
            object[property] = createGetterAndSetter(get, set);
        } else if(get) {
            object[property] = createGetter(get);
        } else if(set) {
            object[property] = createSetter(set);
        }
        return object;
    }
    
    function defineHybridProperties(object, descriptor) {
        for (var key in descriptor) {
            if (hasOwnProperty.call(descriptor, key)) {
                defineHybridProperty(object, key, descriptor[key]);
            }
        }
        hiddenNatives(object, descriptor);
        return object;
    }
    
    var
        hasOwnProperty = Object.prototype.hasOwnProperty,
        hiddenNatives,
        name
    ;
    
    for (name in {toString:1}) {
        hiddenNatives = function (object, descriptor) {};
    }
    
    if (!hiddenNatives) {
        name = "constructor.hasOwnProperty.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.valueOf".split(".");
        hiddenNatives = function (object, descriptor) {
            var i = name.length, key;
            while (i--) {
                if (hasOwnProperty.call(descriptor, key = name[i])) {
                    defineHybridProperty(object, key, descriptor[key]);
                }
            }
        };
    }
    
    Object.defineHybridProperty = defineHybridProperty;
    Object.defineHybridProperties = defineHybridProperties;
    
}(Object));
back to devpro   download
Creative Commons License