Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

looping over an Object in a prototype

I know how to loop oven an Object I in javascript. But when i try to do that inside a prototype of an Object then i am getting 'undefined is not a function' error. My code is as below

var createObject = function(strIn) {
  this.result = strIn;
}

createObject.prototype.toObject = function() {
  var objData = this.result.split('&');
  this.result = Object.create(null); //{}
  var res = Object.create(null);
  objData.forEach(function(value, index) {
    var test = value.split('=')
    return res[test[0]] = test[1];
  });
  this.result = res;
  res = Object.create(null);
  return this.result;

}

createObject.prototype.toString = function() {
  //{ jake: 'dog', finn: 'human' }
  //"jake=dog&finn=human"
  var key,
    objIn = Object.create(null),
    returnresult = '';
  objIn = this.result; //this is causing issue
  console.log('obj', objIn);
  console.log(typeof(objIn))
  for (key in objIn) {
    console.log(objIn.hasOwnProperty('key')) //trying to see wht this results in ::GIVES 'undefined is not a function error'
      //     if(objIn.hasOwnProperty(key)){
      //       returnresult += key+'='+objIn[key]+'&'
      //     }
  }
  this.result = returnresult;
  returnresult = Object.create(null);
  return this.result;
}


var test = new createObject('jake=dog&finn=human');

console.log(test);
console.log(test.toObject())
console.log(test);
console.log(test.toString());
console.log(test);

Result and error as below is:

{ result: 'jake=dog&finn=human' } 
{ jake: 'dog', finn: 'human' } 
{ result: { jake: 'dog', finn: 'human' } } 
obj { jake: 'dog', finn: 'human' } 
object 
solution.js:52 
    console.log(objIn.hasOwnProperty('key')  ) 
                      ^ 
TypeError: undefined is not a function 
    at createObject.toString (solution.js:52:23) 
    at solution.js:68:18 

Its not a spelling mistake so not sure whats going on ..

Thanks ..

like image 617
Mani Avatar asked Mar 09 '26 00:03

Mani


2 Answers

Objects are reference types.

Object.create(null) returns really empty object without prototype. For example:

var emptyObj = Object.create(null)
emptyObj.hasOwnProperty // Return undefined.
emptyObj.prototype // Return undefined.

So:

createObject.prototype.toObject = function() {
  var objData = this.result.split('&');
  this.result = Object.create(null); //{}
  var res = Object.create(null);
  objData.forEach(function(value, index) {
    var test = value.split('=')
    return res[test[0]] = test[1];
  });

  // Here you say - this.result = res
  // But it's reference type, so the address of this variable will be
  // Setted to `this`
  this.result = res;

  // here you change the reference value of res.
  // so this.result will be = Object.create(null) after next line exec.
  res = Object.create(null);

  return this.result;

}

I think this is the problem.

like image 183
Ifch0o1 Avatar answered Mar 11 '26 12:03

Ifch0o1


You are creating this.result off of the res object, created with Object.create(null) - that uses null as its prototype, so it does not have any initial properties. You end up assigning some properties in the statement

return res[test[0]] = test[1];

but hasOwnProperty is not among them. You can create empty objects with Object.create(Object) instead.

And you want to use the version that does not have key in quotes:

  //     if(objIn.hasOwnProperty(key)){
like image 28
Danny Avatar answered Mar 11 '26 13:03

Danny



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!