【问题标题】:Object.defineProperty not recognising getter or setter syntaxObject.defineProperty 无法识别 getter 或 setter 语法
【发布时间】:2020-02-08 17:54:09
【问题描述】:

考虑下面的代码:

"use strict";

var obj = {
    firstName : "abhay",
    lastName : "Deol"
};


Object.defineProperty(obj, "fullName" , {

    get fullName(){
        return this.firstName + this.lastName;
    },

    set fullName(value){
        let words = value.toString().split(' ');
        this.firstName = words[0];
        this.lastName = words[1];
    },

    enumerable : true,
    configurable : true
});

console.log(Object.getOwnPropertyDescriptor(obj,"fullName"));
obj.fullName = "good boys"; // Error

我收到以下错误:

TypeError: Cannot assign to read only property 'fullName' of object '#<Object>'
    at Object.<anonymous> 
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
    at internal/main/run_main_module.js:17:11

它似乎无法识别二传手。此外,如果我试图获得价值,它会给我undefined。这表明,吸气剂也没有得到认可。但为什么呢?

在上面的代码中,它将其识别为数据属性而不是访问器属性。显然,它在描述符对象中不接受 getter/setter 的语法。但为什么 ?这可以通过this的输出来证明-

console.log(Object.getOwnPropertyDescriptor(obj,"fullName"));

作为

{
  value: undefined,
  writable: false,
  enumerable: true,
  configurable: true
}

我在 getter/setter 代码中使用的语法,如果我在对象字面量中使用它就可以正常工作,那么为什么描述符对象会失败呢?我的意思是下面是可以接受的,但上面的代码语法不是!

var obj = {

    firstName : "abhay",
    lastName : "Deol",

    get fullName(){
        return this.firstName + this.lastName;
    },

    set fullName(value){
        let words = value.toString().split(' ');
        this.firstName = words[0];
        this.lastName = words[1];
    }
};

【问题讨论】:

    标签: javascript


    【解决方案1】:

    这不是正确的语法:

    get fullName(){}
    

    您需要在对象上定义键 getset 以便 descriptorObject.get().set() 是可调用的。您正在为描述符对象上的属性 fullName 定义 getter 和 setter — 但 definedProperty() 不是在寻找 fullName

    每个 MDN:

    访问器描述符还具有以下可选键:
    得到...
    设置...

    你传递的对象,没有定义这些键。

    尝试只使用:

    get(){}
    set(v){}
    

    例如:

    "use strict";
    
    var obj = {
        firstName : "abhay",
        lastName : "Deol"
    };
    
    
    Object.defineProperty(obj, "fullName" , {
        get(){
            return this.firstName + this.lastName;
        },
    
        set(value){
            let words = value.toString().split(' ');
            this.firstName = words[0];
            this.lastName = words[1];
        },
        enumerable : true,
        configurable : true
    });
    
    console.log(obj, obj.firstName)
    obj.fullName = "good boys"; 
    console.log(obj, obj.fullName)

    【讨论】:

    • Thnx Mark 但我的问题是为什么我的语法错误。我已经通过你的方式知道它会起作用。我在代码中使用的语法如果我在对象文字中使用它就可以正常工作,那么为什么描述符对象会失败?
    • @Number945 getset 是描述符上的键。您需要使用功能定义这些键。您正在尝试为传入的对象定义一个 getter 和 setter - 您最终为 fullName 定义了 getter/setter,这使得键 getset 未定义。
    • 那为什么this 可以接受语法呢?你的推理也应该适用于此。我在属性描述符上方发布了问题。请看一看。你会看到,它将把它作为数据属性!甚至没有访问器属性。
    • 是的,因为它没有被传递给definedProperty,所以它为键fullName 设置了一个getter/setter。 definedProperty 不会寻找该属性。它会寻找并尝试调用get()set()。您发布的链接中的对象没有属性getset。尝试在链接代码中调用 obj.get() — 这就是 defineProperty 将尝试做的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多