1

I have been trying to write getters and setters using object.defineproperty,but could not .I have been trying this example but it throws an error as no firstName property defined.can someone please help me this

function person(fName, lName) {


  Object.defineProperty(this, 'firstName', {
    get:function() { return firstName; },
    set:function(newValue){firstName=newValue;}
 });
}
var p1=person("xyz","abc");
console.log(p1.firstName);

Thanks

Geeky
  • 7,420
  • 2
  • 24
  • 50
  • Where do you use `fName` and `lName`? Uhuh, you don't. How do you expect to pass on a value, without passing it on? ;-) – Stephan Bijzitter Nov 25 '16 at 22:11
  • My idea is to create a firstName property in person object which should have fName value – Geeky Nov 25 '16 at 22:12
  • could not find a way of how can i do it – Geeky Nov 25 '16 at 22:13
  • Well, the error is clear. You don't define a `firstName` variable anywhere so `return firstName` throws, and `firstName=newValue` creates a global property in sloppy mode and throws in strict mode. – Oriol Nov 25 '16 at 22:22

3 Answers3

2

In your getter you're returning firstName, but it is not defined yet, so right above Object.defineProperty declare firstName and assign the fName argument to it.

Also, when you declare p1 use the new operator so your person constructor works and assigns "xyz" to the firstName property.

So, try this:

function person(fName, lName) {

  var firstName = fName;

  Object.defineProperty(this, 'firstName', {

    get:function() { return firstName; },
    set:function(newValue){firstName=newValue;}

 });

}

var p1 = new person("xyz","abc");

console.log(p1.firstName);

p1.firstName = "abc";

console.log(p1.firstName);
2

You should new up your Person to create the Person instance. As you can see, you can simply use the variables that you passed into the constructor for your getter and setter.
I purposely named the constructor parameters to see how all the variables play together.

In your getter, you return the firstNameFromConstructor variable, or do some processing and then return it.
In your setter, you can change the value of the firstNameFromConstructor variable.

function Person(firstNameFromConstructor, lastNameFromConstructor) {
  Object.defineProperty(this, 'firstName', {
      get:function() { return firstNameFromConstructor; },
      set:function(newFirstName){  firstNameFromConstructor = newFirstName;}
  });
  Object.defineProperty(this, 'lastName', {
      get:function() { return lastNameFromConstructor; },
      set:function(newLastName){ lastNameFromConstructor = newLastName;}
  });
}

var p1= new Person("xyz","abc");
console.log(p1.firstName);
p1.firstName = 'zyx'
console.log(p1.firstName);
Swimburger
  • 6,681
  • 6
  • 36
  • 63
  • This is based on [this mdn page](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Custom_Setters_and_Getters). – Swimburger Nov 25 '16 at 22:25
0

You need to save references to the arguments you pass into the constructor, so that you may get/set them after instantiation.

function person(fName, lName) {    
  Object.defineProperty(this, 'firstName', {
    get: function () { return this._firstName; },
    set: function (newValue) { this._firstName = newValue; }
  });

  Object.defineProperty(this, 'lastName', {
    get: function () { return this._lastName; },
    set: function (newValue) { this._lastName = newValue; }
  });

  this.firstName = fName;
  this.lastName = lName;
}

var p1 = new person("xyz", "abc");
console.log(p1.firstName);
Jeff McCloud
  • 5,777
  • 1
  • 19
  • 21