简体   繁体   English

Object.defineProperty-范围和内部函数返回对象?

[英]Object.defineProperty - scope and use inside function returning object?

I'm learning JavaScript (using latest Google Chrome build on 64bit Debian Jessie) for a couple of days now and right now I'm stuck in understanding how exactly Object.defineProperty works. 我已经学习了几天的JavaScript(使用最新的基于64位Debian Jessie的Google Chrome构建),现在我一直在了解Object.defineProperty工作原理。 I have the following page: 我有以下页面:

function createPerson() {
    var person = {
        firstName: 'Lilly',
        lastName: 'Louis',
    };

    Object.defineProperty(person, 'fullName', {
        get: function() {
            return this.firstName + ' ' + this.lastName;
        },
        set: function(name) {
            var words = name.split(' ');
            this.firstName = words[0] || '';
            this.lastName = words[1] || '';
        }
    });
}

var p1 = createPerson();
console.log("Person's default name is \"" + p1.fullName + "\"");

I get Uncaught TypeError: Cannot read property 'fullName' of undefined at the line where I try to use the property inside console.log(...) . 我收到Uncaught TypeError: Cannot read property 'fullName' of undefinedconsole.log(...)内部使用该属性的行Uncaught TypeError: Cannot read property 'fullName' of undefined If I place both the definition of person along with the Object.defineProperty outside the function everything works fine. 如果我将person的定义与Object.defineProperty放在函数之外,则一切正常。 If I move only Object.defineProperty outside the function after p1 is created like this: 如果像这样创建p1之后仅将 Object.defineProperty移到函数外:

var p1 = createPerson();
Object.defineProperty(p1, 'fullName', {
    get: function() {
        return this.firstName + ' ' + this.lastName;
    },
    set: function(name) {
        var names = name.split(' ');
        this.firstName = names[0] || '';
        this.lastName = names[1] || '';
    }
});

I get Uncaught TypeError: Object.defineProperty called on non-object followed by the console pointing out that it is invoked on an (anonymous function) (that is p1 ) which is even more confusing since I've just read that if I assign callPerson to my p1 without the brackets I'm passing the function object to it otherwise I'm calling the function itself and assigning its return value (if none, undefined is returned) to p1 . 我收到了Uncaught TypeError: Object.defineProperty called on non-object然后控制台指出它是在(anonymous function) (即p1 )上调用的,这更加令人困惑,因为我刚刚读过,如果我分配了callPerson不带括号将其传递给我的p1 ,将函数对象传递给它,否则我调用函数本身并将其返回值(如果没有返回,则返回undefined )给p1

I have the feeling both issues are completely separate but still since I'm not 100% sure I've decided to put both in the same question. 我觉得这两个问题是完全分开的,但是由于我不确定100%是否已决定将两个问题都放在同一个问题中。 Any advice what I'm doing wrong here? 有什么建议我在这里做错了吗? I can define my getter and setter the old fashioned way by simply doing 我可以通过简单的方法来定义我的gettersetter方法

function createPerson() {
    var person = {
        firstName: 'Lilly',
        lastName: 'Louis',
        getFullName: function() {
            return ...;
        }
        setFullName: function(name) {
            ...
        }
    };
}

but I would like to understand what's going on here. 但我想了解这里的情况。 :D :D

Your defineProperty call is absolutely fine. 您的defineProperty调用绝对正确。 The problem is that createPerson never returns anything, so the result of calling it is undefined . 问题在于createPerson从不返回任何内容,因此调用它的结果是undefined You want return person; 你要return person; at the end: 在末尾:

 function createPerson() { var person = { firstName: 'Lilly', lastName: 'Louis', }; Object.defineProperty(person, 'fullName', { get: function() { return this.firstName + ' ' + this.lastName; }, set: function(name) { var words = name.split(' '); this.firstName = words[0] || ''; this.lastName = words[1] || ''; } }); return person; // <======= } var p1 = createPerson(); console.log("Person's default name is \\"" + p1.fullName + "\\""); 

Alternately, make it a constructor function (used with new ) rather than a factory function, and use this within the function. 或者,使其成为构造函数(与new )而不是工厂函数,然后在函数内使用this In that case, we'd drop create from the name, and we wouldn't (typically) use return this; 在这种情况下,我们将从名称中删除create ,并且(通常)不使用return this; at the end because if the function doesn't return a different object, by default the result of new XYZ is the object created by the new operator and supplied to the function as this : 在端部,因为如果该函数不返回不同的对象,通过默认的结果new XYZ是由创建该对象new操作者,并提供给该功能的this

 function Person() { this.firstName = 'Lilly'; this.lastName = 'Louis'; Object.defineProperty(this, 'fullName', { get: function() { return this.firstName + ' ' + this.lastName; }, set: function(name) { var words = name.split(' '); this.firstName = words[0] || ''; this.lastName = words[1] || ''; } }); } var p1 = new Person(); console.log("Person's default name is \\"" + p1.fullName + "\\""); 

This is because you created a person variable, but never returned it. 这是因为您创建了一个person变量,但从未返回它。 Hence nothing is being returned from the function, and the assignment is undefined: 因此,该函数未返回任何内容,并且赋值是不确定的:

function createPerson() {
    var person = {
        firstName: 'Lilly',
        lastName: 'Louis',
    };

    Object.defineProperty(person, 'fullName', {
        get: function() { return this.firstName + ' ' + this.lastName; },
        set: function(name) {
            var words = name.split(' ');
            this.firstName = words[0] || '';
            this.lastName = words[1] || '';
        }
    });
    return person; // Add this line
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM