7

Considering the basic scenario of usage, do

foo.bar = 'baz';

and

Object.defineProperty(foo, 'bar', {
  value: 'baz',
  configurable: true,
  enumerable: true,
  writable: true
});

behave exactly the same in supported browsers?

Can we fall back to vanilla in pre-ES6 applications just because of favourable syntax or mix both of them without any side effects?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • 1
    Your question has a question mark at the end, but it isn't really a question. Can you rephrase the question please? – Richard Rout Apr 25 '15 at 05:18
  • When you define a property without using defineProperty, obj.property = 'value' and with defineProperty with all the descriptor object with true values both are same. But when you change the the descriptor object properties like configurable, enumerable or writable both the declaration differ. – Jagadish Dharanikota Apr 25 '15 at 06:02
  • In the vast majority of circumstances, they behave in exactly the same way. However, there is an edge case if the prototype has a different property descriptor: [Creating new objects from frozen parent objects](http://stackoverflow.com/q/19698533/2074608) – Qantas 94 Heavy Apr 25 '15 at 08:06
  • Thank you all, gents, that's essentially what I wanted to know. – Estus Flask Apr 26 '15 at 14:32

1 Answers1

4

Yes, they behave the same when

  • there is no bar property in foo (not even an inherited one), so a new one is created, or
  • there is a bar property that has the writable and configurable attributes set to true

However, if neither of those is given, the two indeed produce slightly different results.

  • defineProperty does not consider inherited properties and their descriptors
  • If the existing (possibly inherited) property is an accessor, the assignment will try to call the setter (and fail if none exists), while definePropery will overwrite the property with the data descriptor (or fail if it is an own, non-configurable one)
  • If an existing inherited property is a data property, the assignment will fail if writable is false, or create a new own property if true, like the defineProperty always does
  • If an existing own property is a data property, the assignment will fail if writable is false, or set the new value if true, while defineOwnProperty will fail iff configurable is false and overwrite the attributes otherwise.

Considering the basic scenario of usage

If by "basic usage" you mean no usage of fancy property attributes, then yes they are equivalent. Yet you should just use the simple assignments, for they are easier to read and faster to execute.

Can we fall back to vanilla in pre-ES6 applications

Notice that full support of defineProperty comes with ES5, so unless you need to consider pre-ES5 (old IE) browsers you wouldn't care at all.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Another requirement for behaving the same is assuming that `Object` is the global one (has not been shadowed) and neither the global `Object` nor its `defineProperty` property have been modified. – Oriol Apr 25 '15 at 12:09
  • @Oriol: Yeah, sure, I expected `Object.defineProperty` to be the intrinsic method – Bergi Apr 25 '15 at 12:24
  • Thanks, Bergi, quite comprehensive – Estus Flask Apr 26 '15 at 14:33