JS可以将getter和setter方法命名为property属性吗?

Ala*_*Kis 18 javascript getter setter

我想实现像代码中的行为:

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

var myFoo = new Foo('myName');

myFoo.name('newMyName'); // sets myFoo.name = 'newMyName'
myFoo.name(); // returns 'myName'
Run Code Online (Sandbox Code Playgroud)

但很明显,在这种情况下,我用name函数覆盖了name属性.无论如何可以实现这个功能?

sle*_*man 31

在javascript中讨论getter和setter时,您可能会谈论以下两个概念之一:

1. Getters和setter作为任何其他OO语言的概念.

这是您的问题中的代码所示的情况.在这种情况下,对象的属性就是一个属性,它可以是对象或函数.javascript在同一名称空间内跟踪两者.实际上,函数只是javascript中的对象,因此没有像C语言中那样的函数的单独命名空间的概念.

在这种情况下,"getters"和"setter"只是常规函数,因此需要单独存储值.围绕这个有几种策略.

一种是使用Java中常见的隐式getSomething()setSomething()样式函数.这允许您从属性名称中消除getter和setter的歧义,因为getter和setter在名称中添加了"get"和"set".

第二个策略是你在问题中写的那个.在这种情况下,您需要以另一个名称存储该属性,以便不与getter/setter共享相同的名称.

第三种策略是将值存储在闭包中:

    function Foo (name) {
        var name = name;
        this.name = function (str) {
            if (str !== undefined) name = str;
            return name;
        }
    }
Run Code Online (Sandbox Code Playgroud)

请注意,在上面的代码中存储了值,name但getter/setter this.name是一个完全不同的变量.这允许您的示例代码按预期工作:

    var me = new Foo('Mark');
    me.name(); // returns Mark
    me.name('Andy'); // sets name to Andy
Run Code Online (Sandbox Code Playgroud)

2. getters和setter作为javascript中的一种机制.

这是遵循ECMAscript 5规范的较新版本的javascript的功能.此功能允许属性在读取或写入时执行代码,类似于.innerHTMLDOM对象的属性在为其分配内容时调用HTML解析器的方式.

getter和setter的语法类似于函数,但引入了getset关键字代替function.

一个带getter和setter的属性的简单示例:

    var me = {
        first_name : "",
        last_name : "",
        get name() {
            return this.first_name + " " + this.last_name;
        },
        set name(str) {
            var n = str.split(/\s+/);
            this.first_name = n.shift();
            this.last_name = n.join(' ');
        }
    }
Run Code Online (Sandbox Code Playgroud)

上面的代码允许您处理函数以获取和设置它first_name,last_name就像它是变量而不是函数一样.要使用namegetter和setter,您只需执行以下操作:

    me.name = "James Bond";
    alert(me.first_name); // should alert James
    alert(me.last_name); // should alert Bond
    me.last_name = "Dean";
    alert(me.name); // should alert James Dean
Run Code Online (Sandbox Code Playgroud)

使用javascript get/set机制,您无法使用相同的名称将值存储在对象中.例如:

    var foo = {
        set bar(x) {this.bar=x}
    }
Run Code Online (Sandbox Code Playgroud)

上面的代码将编译但是尝试设置bar:foo.bar = 1由于无限循环将导致堆栈溢出 - this.bar=setter内部将再次调用setter.