7.3 Modifying Native Objects - Video Tutorials & Practice Problems
Video duration:
7m
Play a video:
<v Instructor>In this final section</v> on the JavaScript object system, we're going to talk about something controversial: modifying native objects. So what do I mean by this? Well, in this file, we've defined a reverse function on strings. So I can do something like this; (typing) but a good argument can be made that strings should know how to reverse themselves, using syntax like this: (typing) Of course, this doesn't work, because JavaScript strings can't reverse themselves, but we can add this to JavaScript ourselves. Now, this is controversial because if you add too many things to native objects, it could lead to surprising behavior for anybody using your code, without knowing the details of what modifications you've made. So we'll adhere to the philosophy that it's okay to do this but only in very restricted cases. You should only modify built-in objects if you have a good understanding of why you're doing it. In this case, there's a pretty good argument to be made that strings should know how to reverse themselves. And luckily, the JavaScript prototype system gives us the power to add it. So we'll see how that works. We saw in the last section that we could do TranslatedPhrase.prototype = newPhrase. Well, we can also use this syntax to add new methods to the prototype. In particular, we can add something to the string prototype. So let's get rid of this. Actually, let me cut this. We don't need translated phrase anymore, it was just for demonstration purposes. And then at the top, we're gonna change the prototype of string itself, like this: string.prototype.reverse is going to be a function, just like this; (typing) Adds 'reverse' borrowed from markdown. All right, let's take a look at this. String.prototype.reverse is a function, well, it doesn't have to be a function of a string anymore, because strings know about themselves, so instead of reversing a string, we'll reverse nothing. What do you suppose we replace string with here? Well, in the context of a string object, how do we represent the object itself? We saw it before with phrase. That's what this is. So instead of return Array.from(string).reverse().join(""); we say return Array.from(this). Let's see if we can load this. I'm actually not sure if this will work, we've broken the code, because this reverse function doesn't exist anymore. (typing) It worked, look at that. So now we can say (typing) this should now break, (typing) Now look at that, it still worked. That's weird. Oh, I think I know what happened. I think we've previously defined reverse, so it's still here in the REPL. I bet if I quit out and restart it and it will not work. Let's take a look at this. (typing) Put this in the buffer here. (typing) Yeah, so now it breaks. So what happened before, is in the REPL, we had already defined reverse from our previous dot load, so I went out of node and back into it. And so now reverse is not defined and it's complaining. So here, instead of reverse(this.processedContent()); we can call reverse right on process content, like this: (typing) Okay. (typing) All right, it's working. Let's try a slightly longer palindrome. We've seen this before. Call it napoleonslament. The theme is palindrome. (typing) Napoleon was exiled to the island of Elba, although he later returned, and then was exiled even further to the island Saint Helena. And so one might say Napoleon was able, before he went to Elba, and his lament might be "Able was I ere I saw Elba" which is in fact a palindrome. (typing) All right, we have successfully added a reverse method to all strings, so strings now know their own reverses, and we've updated phrase to use that reverse method. Now this raises an interesting question. Might we add palindrome itself to strings? So strings would know whether or not they're palindromes. We could then call something like this, (typing) and it would return true or false based on whether or not this string is a palindrome. Of course, that doesn't work here, but we could do it like this. (typing) And there we go. All right, can we really do this in JavaScript? Well, we just showed that it's possible, but whether or not you should make this kind of modification is really a matter of judgment. And it depends in large part on the culture of the language. Is this the kind of thing that people reasonably do? In some languages like Ruby, there's a relatively high level of tolerance for this kind of practice, but JavaScript tends to be more cautious about these sorts of things. So in this case, because of the culture of the language, I would tend to err on the side of caution and not put palindrome on string itself, as cool as it might be. But of course, if you want to add palindrome to string, there's nothing I can do to stop you.