问题
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.
回答1:
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.
来源:https://stackoverflow.com/questions/38961414/object-defineproperty-or-prototype