20

I've seen two different techniques of implementing non-native features in javascript, First is:

if (!String.prototype.startsWith) {
    Object.defineProperty(String.prototype, 'startsWith', {
        enumerable: false,
        configurable: false,
        writable: false,
        value: function(searchString, position) {
            position = position || 0;
            return this.lastIndexOf(searchString, position) === position;
        }
    });
}

and Second is:

String.prototype.startsWith = function(searchString, position) {
    position = position || 0;
    return this.lastIndexOf(searchString, position) === position;
}

I know that the second one is used to attach any method to the prototype chain of a particular standard built-in objects, but first technique is new to me. Can anybody explain what is the difference between them, why one is used and why one not and what are their significances.

bantya
  • 576
  • 11
  • 23
  • [did you look up `Object.defineProperty` to attempt to understand how it works](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)? – zzzzBov Aug 15 '16 at 19:10
  • 1
    `enumerable`, `configurable`, and `writable` all default to `false` and thus are not necessary. In any case, the advantage of this is that, uhh, properties so defined are not enumerable, configurable, or writable, all of which you probably want. –  Aug 15 '16 at 19:10
  • Yes, but found the official documentation on `developer.mozilla.org` slightly confusing. If we can add a property to prototype of particular standard built-in objects then what does `defineProperty` actually do, that was confusing part. – bantya Aug 15 '16 at 19:15

1 Answers1

36

In two cases you are adding a new property 'startsWith' in String.prototype.

First differs from the second in this cases:

You can configure the property to be enumerable, writable and configurable.

Writable - true means that you can change its value by assigning any value. If false - you can't change the value

Object.defineProperty(String.prototype, 'startsWith', {
        enumerable: false,
        configurable: false,
        writable: false, // Set to False
        value: function(searchString, position) {
            position = position || 0;
            return this.lastIndexOf(searchString, position) === position;
        }
    });

var test = new String('Test');

test.startsWith = 'New Value';
console.log(test.startsWith); // It still have the previous value in non strict mode

Enumerable - true means that it will be seen in the for in loop.

Object.defineProperty(String.prototype, 'startsWith', {
        enumerable: true, // Set to True
        configurable: false,
        writable: false, 
        value: function(searchString, position) {
            position = position || 0;
            return this.lastIndexOf(searchString, position) === position;
        }
    });

var test = new String('Test');

for(var key in test){
   console.log(key)  ;
}

Configurable - true if and only if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object.

Object.defineProperty(String.prototype, 'startsWith', {
            enumerable: false,
            configurable: false, // Set to False
            writable: false, 
            value: function(searchString, position) {
                position = position || 0;
                return this.lastIndexOf(searchString, position) === position;
            }
        });

    
    delete String.prototype.startsWith; // It will not delete the property
    console.log(String.prototype.startsWith);

And one advice to you, don't change the prototypes of build in types.

Community
  • 1
  • 1
Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
  • Okk, that means by using`defineProperty`, we can set the behavior of required property to what we want to be, is that right? – bantya Aug 15 '16 at 19:21
  • 2
    Yes you are right. If you will define a property and miss the writable, enumerable and configurable their values will be `false` by default – Suren Srapyan Aug 15 '16 at 19:23
  • Thanks for your demonstration with code, it is really a **big** help in understanding the scenario.. Thanks again.. – bantya Aug 15 '16 at 20:53