cabbageforall
cabbageforall

Reputation: 660

Javascript: Check if something can have properties _added_ to it

EDIT: Made clearer that the need is to determine if I can add properties to a value, not if a value can have its own properties.

Is there a way to check if is possible to add properties to a value?

For example, if I have this code:

function test( value ) {
    // return true if it is possible to add properties to value
}

Other than actually adding a property value to test, is there a reliable way to deduce if value is something that properties can be added to?

For example, I know an object can have properties and undefined can't, but I'm not keen on creating a list of known things that might not suffice in the future. Is something like instanceof object sufficient?

Upvotes: 4

Views: 73

Answers (3)

cabbageforall
cabbageforall

Reputation: 660

As pointed out by Jonas Wilms:

Bad usecase. You are just writing your next headache :)

I need to refactor my code so it doesn't need to jump through hoops.

Upvotes: 0

Jonas Wilms
Jonas Wilms

Reputation: 138557

The list of values that do not have properties is quite short: undefined and null. Testing for those should be straightforward (value == null).

Note that all other primitives can have properties (through boxing), but as the boxed object gets lost immeadiately there is no sense in adding properties to them:

 1..test = 1;
 "test".test = 1;
 Infinity.test = 1;
 NaN.test = 1;
 true.test = 1;
 Symbol().test = 1;
 1n.test = 1;

To check for non-primitives, typeof value === "object" can be used, but as null is also an object (a very special one, actually it counts as a primitive but typeof lies about that), you have to explicitly check for value !== null.

While you can usually add properties to objects, they can be frozen, then adding properties is useless, the same applies to Proxies.

  const obj = {};
  Object.freeze(obj);
  obj.test = 1;
  console.log(obj.test);

And as Proxies can't be detected, there is no way to find out wether a property can be added or not.

Upvotes: 4

gaetanoM
gaetanoM

Reputation: 42054

A simple idea (although it does not solve completely the case as per Jonas Wilms answer) may be:

function test(value) {
    try {
        if (value.p === undefined) {
            value.p = 10;
            if (value.p === undefined) {
                return false;
            }
            delete value.p;
        }
    } catch(e) {
        return false;
    }
    return true;
}

console.log('null: ' + test(null));
console.log('undefined: ' + test(undefined));
console.log('number: ' + test(10));
console.log('object: ' + test({a:10}));
var  obj = { get p() { return false; }, set p(v) {} };
console.log('object with property name confict: ' + test(obj));

Upvotes: 0

Related Questions