tnkh
tnkh

Reputation: 1829

The option [method name] not supported with Object.prototype

I am extending the Object class in my webapp with Object.prototype as follows, but the backend returns error saying that the options [allFalse] is not supported

let MongoClient = require('mongodb').MongoClient;

Object.prototype.allFalse = function() { 
 for (var i in this) {
   if (i < 1) return;
   if (this[i] === true) return false;
 }
 return true;
}

router.get('/getmongo', function(req, res) {
  MongoClient.connect(process.env.DB_CONN, function(err, db) {
   (bunch of codes here)
  }
}

I replaced the code with the following and it works perfectly.

let MongoClient = require('mongodb').MongoClient;

Object.defineProperty(Object.prototype, 'allFalse', {
  value : function() {
    for (var i in this) {
      if (i < 1) return;
      if (this[i] === true) return false;
    }
    return true;
  }
 });

 router.get('/getmongo', function(req, res) {
   MongoClient.connect(process.env.DB_CONN, function(err, db) {
    (bunch of codes here)
   }
 }

Anyone can explain to me why?

Upvotes: 0

Views: 122

Answers (1)

Yury Tarabanko
Yury Tarabanko

Reputation: 45121

"but the backend returns error" ... "I replaced the code with the following and it works perfectly."

The difference is that the first variant makes allFalse property enumerable. So the code that is serializing options somehow before sending it to the backend serializes allFalse property as well.

Consider the following code snippet that fakes the possible serialization that would be affected by the way you have extended object prototype in the first case.

Object.prototype.allFalse1 = function allFalse1() {}

Object.defineProperty(Object.prototype, 'allFalse2', {
  value: function allFalse2() {}
})

const a = {a: 1}

console.log(serialize(a))

console.log(
 Object.getOwnPropertyDescriptor(Object.prototype, 'allFalse1').enumerable,
 Object.getOwnPropertyDescriptor(Object.prototype, 'allFalse2').enumerable
)


// fake serialization that traverses inherited properties
function serialize(obj) {
  const params = []
  
  for(const key in obj) {
    params.push(`${key}=${encodeURIComponent(obj[key])}`)
  }
  return params.join('&')
}

Upvotes: 2

Related Questions