Javascript中定义setter和getter的样式之间的区别

时间:2014-05-16 06:26:32

标签: javascript object getter-setter

我正在用JavaScript探索setter和getter:

CODE1:

http://jsfiddle.net/imrukhan/7j8ZS/3/

参考:http://whereswalden.com/2010/04/16/more-spidermonkey-changes-ancient-esoteric-very-rarely-used-syntax-for-creating-getters-and-setters-is-being-removed/

<html>
    <head>
        <script>
            var Person = function(name){
                this.name = name;
                defineGetter(this, "Name", function() {
                    console.log("inside getter method");
                    return this.name;
                }); 
                defineSetter(this, "Name", function(val) {
                    console.log("inside setter method");
                    this.name = val;
                }); 
            }
            function accessorDescriptor(field, fun) {
              var desc = { enumerable: true, configurable: true };
              desc[field] = fun;
              return desc;
            }

            function defineGetter(obj, prop, get) {

                if (Object.defineProperty)
                    return Object.defineProperty(obj, prop, accessorDescriptor("get", get));
                if (Object.prototype.__defineGetter__)
                    return obj.__defineGetter__(prop, get);

                throw new Error("browser does not support getters");
            }

            function defineSetter(obj, prop, set) {

                if (Object.defineProperty)
                    return Object.defineProperty(obj, prop, accessorDescriptor("set", set));
                if (Object.prototype.__defineSetter__)
                    return obj.__defineSetter__(prop, set);

                throw new Error("browser does not support setters");
            }

            function fun(){
                var per = new Person("ABC");
                console.log(per.Name);
                per.Name = "XYZ";
                console.log(per.Name);
            }

        </script>
    </head>
    <body>
        <input type="button" value="click" onclick="fun()"/>
    </body>
</html>

CODE2:

http://jsfiddle.net/imrukhan/9H2U6/1/

参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Using_object_initializers

<!DOCTYPE HTML>

<html>
    <head>
        <script>
            var Person = function(name) {
                this._name = name;
            };

            Object.defineProperty(Person.prototype, "name", {
                get: function() {
                    console.log("inside getter method");
                    return this._name;
                },
                set: function(val){
                    console.log("inside setter method");
                    this._name = val;
                }
            });

            function fun(){
                var per = new Person("ABC");
                console.log(per.name);
                per.name = "XYZ";
                console.log(per.name);
            }

        </script>
    </head>
    <body>
        <input type="button" value="click" onclick="fun()"/>
    </body>
</html>

我的疑问:
1)CODE1和CO之间是否存在功能差异? CODE2除了风格?
2)在JavaScipt中定义Setter和Getter的最佳方法是什么(CODE1 / CODE2 /请另外建议)?

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您应该在代码中考虑的一件事是:

在CODE1中,Person的每个实例都有自己的getter和setter方法。这意味着如果你创建了10个人,那么你将有20个方法可以获得getter和setter。

在CODE2中,它只会创建一个getter和一个setter方法,这些方法将由Person的所有实例共享。

因此,如果您正在寻找可以创建大量实例的Web / App,那么您一定应该使用CODE2。

答案 1 :(得分:0)

CODE1使用ECMA5标准(如果可用),否则将退回非标准。

CODE2仅使用ECMA5标准。

最佳取决于您编码的环境,更广泛的浏览器支持或仅ECMA5。

我相信以下三个链接应该为您提供所需的所有信息。

defineGetter

defineProperty

Defining getters and setters

当然,有很多方法可以用其他方式编写示例代码,2个示例。

CODE1的变化,(特征检测一次,分配给prototype

var defineGetter,
    defineSetter;

function accessorDescriptor(field, fun) {
    var desc = {
        enumerable: true,
        configurable: true
    };

    desc[field] = fun;
    return desc;
}

if (Object.defineProperty) {
    defineGetter = function defineGetter(obj, prop, get) {
        return Object.defineProperty(obj, prop, accessorDescriptor("get", get));
    };

    defineSetter = function (obj, prop, set) {
        return Object.defineProperty(obj, prop, accessorDescriptor("set", set));
    };
} else {
    if (Object.prototype.__defineGetter__) {
        defineGetter = function (obj, prop, get) {
            return obj.__defineGetter__(prop, get);
        };
    } else {
        throw new Error("browser does not support getters");
    }

    if (Object.prototype.__defineSetter__) {
        defineSetter = function (obj, prop, set) {
            return obj.__defineSetter__(prop, set);
        };
    } else {
        throw new Error("browser does not support setters");
    }
}

function Person(name) {
    this.name = name;
};

defineGetter(Person.prototype, "Name", function () {
    console.log("inside getter method");
    return this.name;
});

defineSetter(Person.prototype, "Name", function (val) {
    console.log("inside setter method");
    this.name = val;
});

CODE2的变化(没有defineProperty

var Person = function (name) {
    this.name = name;
};

Person.prototype.name = {
    get: function () {
        console.log("inside getter method");
        return this.name;
    },

    set: function (val) {
        console.log("inside setter method");
        this.name = val;
    }
};