Modifying Objects in ECMAScript
- Previous Page Define a class or object
- Next Page Instance of Inheritance Mechanism
By using ECMAScript, not only can objects be created, but the behavior of existing objects can also be modified.
The prototype property can not only define properties and methods of the constructor, but also add properties and methods to the local object.
Create new methods
Create new methods through existing methods
You can use the prototype property to define new methods for any existing class, just like handling your own class. For example, do you remember the toString() method of the Number class? If you pass it a parameter of 16, it will output a hexadecimal string. If the parameter of this method is 2, it will output a binary string. We can create a method that can directly convert a number object to a hexadecimal string. Creating this method is very simple:
Number.prototype.toHexString = function() { return this.toString(16); };
In this environment, the keyword this points to a Number instance, so you can fully access all methods of Number. With this code, you can perform the following operations:
var iNum = 15; alert(iNum.toHexString()); //Output 'F'
Since the number 15 is equal to 'F' in hexadecimal, the warning will display 'F'.
Rename existing methods
We can also rename existing methods to more understandable names. For example, we can add two methods enqueue() and dequeue() to the Array class, which simply call the existing push() and shift() methods repeatedly:
Array.prototype.enqueue = function(vItem) { this.push(vItem); }; Array.prototype.dequeue = function() { return this.shift(); };
Add methods unrelated to existing methods
Of course, you can also add methods that are unrelated to existing methods. For example, suppose you want to determine the position of an item in an array, and there is no local method to do this. We can easily create the following method:
Array.prototype.indexOf = function (vItem) { for (var i=0; i<this.length; i++) { if (vItem == this[i]) { return i; } } return -1; }
The indexOf() method in this method is consistent with the同名 method in the String class, searching for each item in the array until it finds an item that matches the one passed in. If the same item is found, it returns the position of that item; otherwise, it returns -1. With this definition, we can write the following code:
var aColors = new Array("red","green","blue"); alert(aColors.indexOf("green")); //Output: "1"
Add new methods to local objects
Finally, if you want to add a new method to each local object in ECMAScript, you must define it on the prototype property of the Object object. As we mentioned in the previous chapters, all local objects inherit from the Object object, so any changes made to the Object object will reflect on all local objects. For example, if you want to add a method that outputs the current value of an object with a warning, you can use the following code:
Object.prototype.showValue = function () { alert(this.valueOf()); }; var str = "hello"; var iNum = 25; str.showValue(); //Output: "hello" iNum.showValue(); //Output: "25"
Here, both the String and Number objects inherit the showValue() method from the Object object, and calling this method on their objects will display "hello" and "25".
Redefine existing methods
Just like you can define new methods for existing classes, you can also redefine existing methods. As described in the previous chapters, function names are just pointers to functions, so they can easily point to other functions. What will happen if you modify a local method, such as toString()?
Function.prototype.toString = function() { return "Function code hidden"; }
The previous code is completely legal, and the running result is exactly as expected:
function sayHi() { alert("hi"); } alert(sayHi.toString()); //Output: "Function code hidden"
Perhaps you still remember that the Function object chapter introduces that the toString() method usually outputs the source code of the function. Overriding this method can return another string (in this example, it can return "Function code hidden"). However, what about the original function that toString() points to? It will be collected by the unused storage unit recycling program because it has been completely abandoned. There is no way to recover the original function, so it is safer to store its pointer before overriding the original method. Sometimes you may even call the original method in the new method:
Function.prototype.originalToString = Function.prototype.toString; Function.prototype.toString = function() { if (this.originalToString().length > 100) { return "Function too long to display."; } else { return this.originalToString(); } };
In this code, the first line stores a reference to the current toString() method in the property originalToString. Then a custom method overrides the toString() method. The new method checks if the length of the function source code is greater than 100. If so, it returns an error message stating that the function code is too long; otherwise, it calls the originalToString() method and returns the source code of the function.
Late Binding (Very Late Binding)
Technically, there is no such thing as late binding. This book uses this term to describe a phenomenon in ECMAScript, where methods can be defined after the object is instantiated. For example:
var o = new Object(); Object.prototype.sayHi = function () { alert("hi"); }; o.sayHi();
In most programming languages, it is necessary to define the methods of an object before instantiating the object. Here, the method sayHi() is added after creating an instance of the Object class. Not only have we never heard of such an operation, but we have also never heard that the method would automatically assign to the instance of the Object object and be usable immediately (in the next line).
Note:It is not recommended to use late binding methods, as it is difficult to track and record them. However, it is still important to understand this possibility.
- Previous Page Define a class or object
- Next Page Instance of Inheritance Mechanism