Ok peep's so I know it's bad practice to mess with prototypes but here it is anyway...
Array.prototype.rev=
function(){
this.reverse();
}
Works fine! Updates the source array variable, ary
, as expected eg:
ary = [123, 456];
ary.rev();
// result: ary == [456, 123]
My problem comes when writing a similar property for String
.
What I would like to do is something like this...
String.prototype.rev=
function(){
this.split('');
this.reverse();
this.join('');
}
Seems simple enough right! Split the string, reverse it, and join it back together so the original string variable, str
, is a reverse of it's former self, as was with the ary
above!
Thing is: Although this.split()
has been called it needs to be stored as a variable, ie:
split = this.split('');
And there-in lies the this = this
problem...
Now split
is defined, it takes the focus away from editing the source variable and it's not like I can just say at the end of the function:
this = split;
As this
is 'immutable' or what ever it is when they mean it is static and unchangeable?
Getting to the point! My Question is this...
str = 'abc'
I want to be able to say str.rev()
not str = str.rev()
and get the result of str = 'cba'
where str === 'cba'
, catch my drift?!
All work-around's and tuition welcome peep's, I just ask that u know what ur talkin' 'bout. thx
My problem comes when writing a similar property for String
...
The main issue here is that strings are immutable in JavaScript; you cannot change a string in place. Because of that, it's impossible to define a rev
method that would behave like this:
var a = 'abc';
a.rev(); // <== This can't work this way
console.log(a); // cba
Instead, your rev
should do what all other String
methods do: Return a new string with the updates.
A secondary issue is that your code in your rev
method doesn't work, because you're not saving the results of things like this.split('');
anywhere, but the way split
works, it returns an array with the entries.
Here's a version of rev
that addresses both issues:
String.prototype.rev=
function(){
return this.split('').reverse().join('');
};
Then:
var a = 'abc'.rev();
console.log(a); // cba
Example:
String.prototype.rev = function(){
return this.split('').reverse().join('');
};
var a = 'abc'.rev();
snippet.log(a);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
This is how all of the standard string methods (toLowerCase
, replace
, substring
, ...) work, by returning the result.
The all-on-one-line version might not be hyper clear (and is hard to debug), here's the split-apart version for clarity:
String.prototype.rev=
function(){
var characters = this.split('');
characters.reverse();
return characters.join('');
};
(Note that Array#reverse
reverses the array in place and returns the array reference; the fact it also returns the array reference is what makes the all-in-one-line version possible.)
Side note: If you're going to play around with prototypes, consider using Object.defineProperty
rather than just assigning:
Object.defineProperty(String.prototype, "rev", {
value: function() { ... }
});
...so that the new properties are non-enumerable (don't show up in for-in
loops). Doesn't matter that much with String
, but a lot of people still incorrectly use for-in
for looping through arrays, so...
Example:
Object.defineProperty(String.prototype, "rev", {
value: function(){
return this.split('').reverse().join('');
}
});
var a = 'abc'.rev();
snippet.log(a);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>