为 js 对象分配 setter / getter

assigning setter / getter for js object

我试图为我的 js "class" 分配 setter:

function testing(){
    this.value = "content";
    set a(b){
        this.value = b;
    };
}
var test1 = new testing();
test1.a = "nope";

但是它在行 set a(b){ 上抛出了 SyntaxError: missing ; before statement 有人能告诉我正确的语法是怎样的吗?

有几种方法可以做到这一点。

构造函数和Object.defineProperty

要像您一样在构造函数中执行此操作,您需要使用 Object.definePropertyObject.defineProperties。例如:

function Testing(){
    this.value = "content";
    Object.defineProperty(this, "a", {
        set: function(b){
            this.value = b;
        }
    });
}

实例:

function Testing() {
  this.value = "content";
  Object.defineProperty(this, "a", {
    set: function(b) {
      this.value = b;
    }
  });
}
var t = new Testing();
snippet.log("t.value before: " + t.value);
t.a = "new content";
snippet.log("t.value after: " + t.value);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

(注:我在Testing大写的第一个t因为那是JavaScript中的压倒性约定对于构造函数。)

构造函数属性和Object.defineProperty使用原型

或者您可以在原型上定义 setter:

function Testing(){
    this.value = "content";
}
Object.defineProperty(Testing.prototype, "a", {
    set: function(b){
        this.value = b;
    }
});

实例:

function Testing(){
    this.value = "content";
}
Object.defineProperty(Testing.prototype, "a", {
    set: function(b){
        this.value = b;
    }
});
var t1 = new Testing();
snippet.log("t1.value before: " + t1.value);
t1.a = "new content";
snippet.log("t1.value after: " + t1.value);
var t2 = new Testing();
snippet.log("t2.value before: " + t2.value);
t2.a = "new content";
snippet.log("t2.value after: " + t2.value);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

原型的构造函数和对象初始化器

您尝试使用的语法是针对对象初始值设定项的,而不是构造函数。我们可以使用对象初始值设定项 替换 Testing.prototype,像这样:

function Testing(){
    this.value = "content";
}
Testing.prototype = {
    constructor: Testing, // The old object had this, so let's maintain it
    set a(b){
        this.value = b;
    }
};

实例:

function Testing(){
    this.value = "content";
}
Testing.prototype = {
    constructor: Testing, // The old object had this, so let's maintain it
    set a(b){
        this.value = b;
    }
};
var t1 = new Testing();
snippet.log("t1.value before: " + t1.value);
t1.a = "new content";
snippet.log("t1.value after: " + t1.value);
var t2 = new Testing();
snippet.log("t2.value before: " + t2.value);
t2.a = "new content";
snippet.log("t2.value after: " + t2.value);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

一次性对象的对象初始值设定项

这只是创建了一个一次性对象,而不是一个可以用来构建一堆这些对象的函数:

var t = {
  value: "content",
  set a(b) {
    this.value = b;
  }
};

实例:

var t = {
  value: "content",
  set a(b) {
    this.value = b;
  }
};
snippet.log("t.value before: " + t.value);
t.a = "new content";
snippet.log("t.value after: " + t.value);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

构建函数和 Object.create 原型

构造函数(您与 new 一起使用的函数)并不是市面上唯一一种在其背后创建对象的游戏。如果你愿意,你也可以使用构建器函数来做到这一点,通过 Object.create:

var testingPrototype = {
    set a(b){
        this.value = b;
    }
};
function testing(){
    var obj = Object.create(testingPrototype);
    obj.value = "content";
    return obj;
}

你不对这些使用 new,因为它们自己创建对象:

实例:

var testingPrototype = {
    set a(b){
        this.value = b;
    }
};
function testing(){
    var obj = Object.create(testingPrototype);
    obj.value = "content";
    return obj;
}
var t1 = testing();
snippet.log("t1.value before: " + t1.value);
t1.a = "new content";
snippet.log("t1.value after: " + t1.value);
var t2 = testing();
snippet.log("t2.value before: " + t2.value);
t2.a = "new content";
snippet.log("t2.value after: " + t2.value);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

构建器函数,无原型

最后但同样重要的是,您可以使用构建器函数而不使用原型:

function testing() {
    return {
        value: "content",
        set a(b){
            this.value = b;
        }
    };
}

您也不要将 new 与这些一起使用:

实例:

function testing(){
    return {
        value: "content",
        set a(b){
            this.value = b;
        }
    };
}
var t1 = testing();
snippet.log("t1.value before: " + t1.value);
t1.a = "new content";
snippet.log("t1.value after: " + t1.value);
var t2 = testing();
snippet.log("t2.value before: " + t2.value);
t2.a = "new content";
snippet.log("t2.value after: " + t2.value);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

在这样的示例中,集合需要成为对象的一部分:

一种方法是这样的:

function testing(){
    var value = "content";
    return {
        set a(b){
            value = b;
        },
        get a() {
            return value;
        }
    };
}
var test1 = new testing();
test1.a = "nope";

http://jsfiddle.net/GarryPas/1s7v0rdn/