使用setter方法的JavaScript属性不是真正的属性吗?

时间:2014-12-28 02:50:09

标签: javascript inheritance

function Name(first, last) {
  this.first = first;
  this.last = last;
  this.fullName = first + " " + last
}

Name.prototype = {
  get fullName() {
    return this.first + " " + this.last;
  },

  set fullName(name) {
    var names = name.split(" ");
    this.first = names[0];
    this.last = names[1];
  }
};

var person = new Name("Foo", "Bar");
// person.fullName = "Foo Bar"
person.hasOwnProperty("fullName") // false

有没有办法返回属性?

3 个答案:

答案 0 :(得分:6)

hasOwnProperty不会检查对象的原型链,在您的情况下,人getset通过原型链继承

hasOwnProperty

  

来自Object的每个对象都继承hasOwnProperty方法。   此方法可用于确定对象是否具有   指定属性作为该对象的直接属性;与in不同   运算符,此方法不会检查对象的原型   链



function Name(first, last) {
    this.first = first;
    this.last = last;
    this.fullName = first + " " + last;
}
var person = new Name("Foo", "Bar");
console.log(person.fullName);
console.log(person.hasOwnProperty("fullName")); // true
console.log(Name.prototype.hasOwnProperty("fullName")); // false

for (var prop in person) {
    console.log(prop);
}

console.log('');

Name.prototype = {
    get fullName() {
        return this.first + " " + this.last;
    },

    set fullName(name) {
        var names = name.split(" ");
        this.first = names[0];
        this.last = names[1];
    }
};
var person2 = new Name("Foo", "Bar");
console.log(person2.fullName);
console.log(person2.hasOwnProperty("fullName")); // false
console.log(Name.prototype.hasOwnProperty("fullName")); // true




引用@JLRishe

  

当你使用this.fullName =" ...&#34 ;;在你的构造函数中,你是   调用继承的setter,而不是添加新属性。

如果要查找此类属性,可以使用for ... in语句:

for (var prop in person) {
    console.log(prop);
}

答案 1 :(得分:3)

正如InvernoMuto指出的那样,Object.hasOwnProperty("fullName")会返回false,因为它不是person自己的财产;它是通过原型链继承的。在构造函数中使用this.fullName = "...";时,您正在调用继承的setter,而不是添加新属性。

如果您想找到这样的属性,您可以:

  1. 使用for..in循环:
  2. for (var prop in person) {
        // this will iterate over EVERY property in person's prototype chain
    }
    
    1. 在构造函数中附加属性:
    2. 
      
      function Name(first, last) {
        this.first = first;
        this.last = last;
      
        Object.defineProperty(this, "fullName", {
          get: function() {
            return this.first + " " + this.last;
          },
          set: function(name) {
            var names = name.split(" ");
            this.first = names[0];
            this.last = names[1];
          }
        });
      }
      
      var person = new Name("Ronald", "McDonald");
      console.log(person.hasOwnProperty("fullName")); // true
      
      
      

      1. 使用您在那里的get / set语法在构造函数中创建一个全新的对象。在这种情况下,我们不会使用new关键字,只需调用函数:
      2. 
        
        function Name(first, last) {
            return {
                first: first,
                last: last, 
        
                get fullName() { return this.first + " " + this.last; },
                set fullName(name) { 
                    var names = name.split(" ");
                    this.first = names[0];
                    this.last = names[1];
                }
            };
        };
        
        var person = Name("Ronald", "McDonald");
        console.log(person.hasOwnProperty("fullName")); // true
        
        
        

答案 2 :(得分:0)

根据MDN“get语法将对象属性绑定到将在查找该属性时调用的函数。”这意味着每当您尝试访问fullName实例的Name时(例如person.fullName),javascript将委托给该getter函数,该函数恰好位于Name.prototype上宾语。

此外,“当set语法试图设置该属性时,{{3}}语法将对象属性绑定到要调用的函数。”因此,即使明确地为每个实例提供fullName属性,javascript实际上也会查看原型上的set函数。如果你想解决这个问题,让person.hasOwnProperty("fullName")返回true,你可以这样做:

function Name(first, last) {
  this.first = first;
  this.last = last;
  this.fullName = first + " " + last
}

Name.prototype.setFullName = function(fullName){
  var names = fullName.split(" ");
  this.first = names[0];
  this.last = names[1];
  this.fullName = fullName;
};

var person = new Name("Foo", "Bar");
// person.fullName = "Foo Bar"
person.hasOwnProperty("fullName") // true