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

rba*_*dar 1 javascript scope properties

我正在学习 JavaScript(使用基于 64 位 Debian Jessie 的最新 Google Chrome 构建)几天,现在我一直在理解到底是如何Object.defineProperty工作的。我有以下页面:

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 + "\"");
Run Code Online (Sandbox Code Playgroud)

我到达Uncaught TypeError: Cannot read property 'fullName' of undefined了尝试使用内部属性的行console.log(...)。如果我将 的定义personObject.defineProperty函数外部一起放置,则一切正常。如果我在创建后 Object.defineProperty移动到函数外部,如下所示:p1

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] || '';
    }
});
Run Code Online (Sandbox Code Playgroud)

Uncaught TypeError: Object.defineProperty called on non-object后面的控制台指出它是在(anonymous function)(即p1) 上调用的,这更令人困惑,因为我刚刚读到,如果我在没有括号的情况下分配callPerson给 my ,我会将函数对象传递给它,否则我' p1m 调用函数本身并将其返回值(如果没有,则返回undefinedp1 )分配给.

我感觉这两个问题是完全独立的,但由于我不能 100% 确定,所以我决定将这两个问题放在同一个问题中。有什么建议我在这里做错了什么吗?我可以通过简单地定义我的gettersetter老式的方式

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

但我想了解这里发生了什么。:D

T.J*_*der 5

你的defineProperty电话绝对没问题。问题是它createPerson永远不会返回任何内容,因此调用它的结果是undefined. 你想return person;在最后:

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 + "\"");
Run Code Online (Sandbox Code Playgroud)

或者,将其设为构造函数(与 一起使用new)而不是工厂函数,并this在函数内使用。在这种情况下,我们会create从名称中删除,并且(通常)不会return 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 + "\"");
Run Code Online (Sandbox Code Playgroud)