7

Using eslint with React configurations I get an error when using Object.defineProperty. The error says:

Avoid using Object.defineProperty, instead use Reflect.defineProperty. (prefer-reflect)

On the eslint documentation of prefer-reflect they say it's deprecated, the reason being:

The original intent of this rule now seems misguided as we have come to understand that Reflect methods are not actually intended to replace the Object counterparts the rule suggests, but rather exist as low-level primitives to be used with proxies in order to replicate the default behavior of various previously existing functionality.

Then my question is: is there any advantage in using Reflect.defineProperty instead of Object.defineProperty?

1
  • 1
    Yes, the deprecation notice explains it just fine. You should not use this rule. Commented Mar 3, 2018 at 15:56

3 Answers 3

6

There is a slight difference between Object.defineProperty and Reflect.defineProperty: the former returns the target object and throws an exception when the descriptor could not be applied (e.g. when the property is non-writable or non-configurable or when the object is non-extensible), while the latter does return a boolean value whether it worked.

I'd argue that this makes Object.defineProperty a bit more useful, unless you're implementing a defineProperty proxy trap.

Sign up to request clarification or add additional context in comments.

Comments

2

Just to complement the last answer, with Object.defineProperty you must use a try/catch block for contolling exceptions while with Reflect.defineProperty you just can do a boolean check with an if statement for correct property creation.

Comments

1

Most of the time you'll want to use Object.defineProperty(). But in the unusual case where you need to test the success of the operation, you'll want to use Reflect.defineProperty().

That's because it doesn't throw an error if your property definition fails due to an existing non-configurable property or non-extensible object. That means you don't need a try/catch block if you want to know if property definition was successful or not. You can just check the return value which will be true or false.

Furthermore with Object.defineProperty() using try/catch to test for success is problematic because there are other reasons why your code might throw. For example it would be a programming error if the target is not an object, or the descriptor attributes include both get or set and value or writable. In such cases it's better not to catch the error making try/catch undesirable. Try/catch is also notoriously slow.

So with Reflect.defineProperty() try/catch is not needed to discover the success of the operation, and you still have the advantage that it throws if there is a problem with the target value or the descriptor. The only caveat is that Reflect.defineProperty() is not supported in ES5 browsers. But the good news is that it can easily be polyfilled:

self.Reflect = self.Reflect || {};
Reflect.defineProperty = Reflect.defineProperty || function defineProperty(obj, prop, descriptor) {
    if (Object(obj)!==obj) {
        throw TypeError("Reflect.defineProperty called on non-object")
    }
    prop in obj;// throw if prop cannot convert to string/symbol
    if ("get" in descriptor || "set" in descriptor) {
        if (typeof descriptor.get!="function" && typeof descriptor.get!="undefined") {
            throw TypeError("property descriptor's get field is neither undefined nor a function")
        }
        if (typeof descriptor.set!="function" && typeof descriptor.set!="undefined") {
            throw TypeError("property descriptor's set field is neither undefined nor a function")
        }
        if ("value" in descriptor || "writable" in descriptor) {
            throw TypeError("property descriptor's attributes cannot contain both get or set and value or writable")
        }
    }
    try {
        var success = Object.defineProperty(obj, prop, descriptor);
    }
    catch(e) {
    }
    return !!success
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.