1. Why do we need to know both of these methods
As we all know, the toString () function and the valueof function, these two functions are inherently owned by objects of the object class, and they can also allow us to rewrite, so what is the use of these two functions?
From the name, toString () converts the object to a string, valueof the object to a value. So the question is: when do you need to convert the object to a value, and when do you need to convert the object to a string? ------This is the core of our article.
Before we talk about this problem, let's look at a topic first:
This is a very classic topic, the study is our understanding of some basic concepts, of course, it is a difficult topic, and even at first glance seems to be a problem impossible to achieve.
请用javascript语言实现,
var
a= add(1)(2)(3)(4)(5);
//结果为5个数相加,15------------来源于http://dmitry.baranovskiy.com/post/31797647
var add = function (n) { var result = N; var func1 = function (m) { result + = m; return func1; } func1.tostring = function () { return result.tostring (); } Overriding the object's Tostrig function func1.valueof = function () { return result; } Rewrite the object's valueof function return func1;} var a = Add (1) (2) (3) (4) (5); Console.log (a);//15console.log (a+10)//25 answer
.. The above topic is not so easy to think about, and generally speaking, the programmer will not write this kind of code that they look awkward. We only use this to derive some of the most basic concepts, but also the necessity of the existence of this article.
From the example above, we can see that, at the time of the output, the conversion between the function type and the string type is followed. So, how does this transition happen? In the second part, you will be given a satisfactory explanation!
Now we need to know a little bit: the ToString and valueof functions, which are used by the interpreter to help us automate the conversion between types (typically object-to-primitive conversions), and then output the results that satisfy us.
2. Rules for converting objects to basic data types
(1) vauleof takes precedence over ToString ()---------when the object is the operand (except for the date type)
Let's take a look at the following operations, the conversion of the data type
var x= "ten"; var a=+x; Console.log (typeof a); Number var b=a+x; Console.log (typeof b); String
This is just the three more common types of conversions I've listed, and some of the most basic concepts ... Let's take a moment to analyze how these three types of conversions happen.
3-4 lines: the "+" sign as a unary operator----under this operator, the conversion rules for the object to the base data type:
(1). When the operand is the base data type, call the number () function to convert it to a numeric value
(2). When the operand is an object, call the object's ToString or valueof function, convert the object to a value of the base data type, and then call the number () function on the value.
Therefore, according to the above conversion rules, the above output is number is reasonable.
However, in the second conversion rule, there is a big hole in it: whether to call ToString () or valueof (), if two functions can convert the object to the basic data type (such as the date type of object), who do you call?
This is similar to the following:
var x = { tostring:function () { return ' 0 '; }, valueof:function () { return 1;} } var a = + x; In this step, is it called ToString () or valueof ()? , in the + number as a part of the two-dollar operator, will give an explanation of Console.log (a);
1
1
7-8 Line: "+" number as a two-dollar operator----- under this operator, the conversion rules for the object to the base data type
When the "+" number is a 2-dollar operator, the situation is more complicated, because the "+" sign can be used as a string connection, or as a number of the addition and subtraction. You can check the conversion rules, how there is a 7, 8, see the people dazzled and changed. After a lot of testing, I also consulted some of the data, summed up the following rules:
Pseudo code, a + B operation translation rule:
var Pa = toprimitive (a);
var PB = toprimitive (b);
try {
if (Pa is String) | | (Pb is String)) {
Return Contact (string (Pa), String (Pb));
} else {
Return number (Pa) + number (PB);
}
} catch (e) {
Throw e;
}
Note: Toprimitive is the conversion of the operand to the basic data type, priority call to valueof, if the basic data type, then the end, otherwise continue to drop with ToString (). (that is, the priority of valueof is higher than ToString ())
Familiar with these, it can be seen that the + number as a unary operator conversion rules in fact, and its as a two-dollar operator almost, when converted to the basic data type is always the first call valueof (). Here's an example to verify:
var test = { valueof:function () { return 1; }, tostring:function () { return ' 0 '; }} CONSOLE.L OG (+ test); 1 var result = test + test; Console.log (result); 2
Having finished this, we can conclude that the conversion between data types always takes precedence in calling the valueof () function when the operand is operational (either unary or two), but when the "+" number is used as a two-tuple operator, the precedence is applied to objects of the date type. was reversed (ToString has a higher priority).
Keep in mind: the date type is a special case, and when and only if the + number is used as the two-dollar operator, toString () takes precedence, such as the following,
var date=new date (); Console.log (+date); Still priority call valueof Console.log (date+ "ToString precedence is called");
Output Result:
1421293488713
Thu Jan 11:44:48 gmt+0800tostring first called
(2): ToString () takes precedence over valueof () is invoked------when you want the output to be a string
When accessing variables of type object, we use [] this square bracket to access, the content of the square brackets is always preferentially converted to a string, that is, the first call to the toString () function. Look at the following example:
var test = { tostring:function () { return ' 0 ' }, valueof:function () { return 1; } }; var object={}; object[test]=1000; Console.log (object); Output Result:{0=+}
The principle of invocation at this point is described below:
[A] When accessed in this form: Var pa=toprimitive (a);
if (Pa is prmitive) {
var str=string (Pa);
}else{
Throw Error;//cannot Convert to String
}
[Str]//str is the form of a string
Note: toprimitive () first calls the ToString () function, and if the result is a base type, return, otherwise continue calling valueof ();
There are several examples where ToString takes precedence over the valueof () call
var test = { tostring:function () { return ' 0 ' }, valueof:function () { return 1; }}; alert (test); Priority call to ToString () output 0
var test = { tostring:function () { return ' 0 ' }, valueof:function () { return 1; }}; var test1 = { tostring:function () { return ' 0 ' }, valueof:function () { return 1; }} var array = [ test, test1];console.log (array + ')///We analyze the output process://1.array+ "" When performing an operation, call the Array.valueof () function first , it is found that the value of the base type cannot be output//2. Then call the Array.tostring () function. This function is overridden by the array class and, after rewriting, calls the ToString () function for each array element//priority and then calls the valueof () function. (This is a rewrite of the custom rule, not the default) two, the array is converted to a string first select ToString
3. Why these strange phenomena occur
As can be seen above, both the ToString and valueof functions can be called at the time of conversion, except that the priority of the call is different in the environment. These may be transparent to our programmers, but for the interpreter, they can do a lot of work ... The sentence boils down to: The interpreter always transforms the context as much as possible into the result we want. Other words:
When an object is used as an operand, the interpreter always invokes valueof ()--(except when the object of date type is two "+"), whereas in other cases, the interpreter always thinks we want a string, so it takes precedence over the call to ToString ().
Note: The date type Object will call ToString () in favor of the $ two + operation, also because in most cases, time is always used with a string connection, and time and a number are added together, so the ToString () priority is higher in the date type.
It is precisely because the interpreter always wants to perfect the output of the results we want, it will cause this messy phenomenon and rules appear. There is no perfect thing in the world, spears and shields always depend on each other.
Understand the rules before you take advantage of the rules and look back at the first questions we have. Is it the rational use of these rules?
Digression: Writing this article is to show the importance of basic knowledge, not the pursuit of a bizarre program, the programmer should be easy to understand the code (Boulevard to Jane) rather than these seemingly sibuxiang programs, remember to put the cart before the horse!
In addition, after reading these are not there is a back to read the impulse Ah, if there is, then my purpose is reached ... Ha ha!
Note: tolocalestring () This function is the localized output of the implementation string, usually the same as the ToString () output, nothing special, just a normal function. In the date type, the function is rewritten.
The ToString () and valueof () functions of JavaScript