Hello, I’m Li Bai~~
Recently, the weather in Shenzhen is changeable. Sometimes it rains cats and dogs, sometimes it’s sunny. I hope it will rain continuously for a few days. How nice~~
The frightening summer may be over. No one knows what happened to you this summer or this year, but I know.
Know that you work hard, or you may be slow. But in the face of autumn, in the face of the upcoming National Day holiday, please continue to work hard, not only the flow of life, there is time, come on~~
Today, as an author and reader, I hand in my homework for myself and on the way to technical learning~~
Now, let’s get to the point and understand what these two methods do
Basically, all JS data types have these two methods, except null. They are methods on the prototype chain, and also to solve the problem of JavaScript value operation and display.
valueOf
andtoString
Almost all of them are operators(+-*/==><)
Is called (implicit conversion).
toString
Returns a string representing the object. The toString method is called automatically when the object is represented as a text value or referenced as an expected string.
1. Call manually to see what effect
Well, it’s the same as the introduction. It’s not deceptive. It’s all converted into strings.
What’s special is that when you represent an object, it becomes[object Object]
When it represents an array, it becomes a string with the contents of the array connected by commas, which is equivalent toArray.join(',')
。
let a = {}
let b = [1, 2, 3]
let c = '123'
let d = function(){ console.log('fn') }
console.log(a.toString()) // '[object Object]'
console.log(b.toString()) // '1,2,3'
console.log(c.toString()) // '123'
console.log(d.toString()) // 'function(){ console.log('fn') }'
2. The most accurate type judgment
This belongs to a more accurate way of judgment, in some cases than usingtypeof
& instanceof
It’s more efficient and accurate.
toString.call(()=>{}) // [object Function]
toString.call({}) // [object Object]
toString.call([]) // [object Array]
toString.call('') // [object String]
toString.call(22) // [object Number]
toString.call(undefined) // [object undefined]
toString.call(null) // [object null]
toString.call(new Date) // [object Date]
toString.call(Math) // [object Math]
toString.call(window) // [object Window]
3. When will it be called automatically
When using the operator, if one side is an object, it will be called firsttoSting
Method, that isImplicit transformation
And then do the operation.
let c = [1, 2, 3]
let d = {a:2}
Object.prototype.toString = function(){
console.log('Object')
}
Array.prototype.toString = function(){
console.log('Array')
return this.join (',') // returns the default value of toString (test below)
}
console.log(2 + 1) // 3
console.log('s') // 's'
console.log('s'+2) // 's2'
console.log (C < 2) // false (once = >'array ')
console.log (c + C) // 1,2,31,2,3 (twice = >'array ')
console.log (d > d) // false (twice = >'object ')
4. RewritetoString
method
Now that I know, there is a problemtoString
This default method, we can also override this method
class A {
constructor(count) {
this.count = count
}
toString() {
Return 'I have so much money:'+ this.count
}
}
let a = new A(100)
console.log(a) // A {count: 100}
console.log (a.tostring()) // I have so much money: 100
console.log (a + 1) // I have so much money: 1001
Nice.
valueOf
Returns the original value of the current object.
Specific functions and functionstoString
Similar, also has the above automatic call and rewrite method.
Here is nothing to say, mainly for the difference between the two, please continue to look down
let c = [1, 2, 3]
let d = {a:2}
console.log(c.valueOf()) // [1, 2, 3]
console.log(d.valueOf()) // {a:2}
The difference between the two
- What’s common: it’s called automatically when you output objects.
- difference:The default return values are different, and there is a priority relationship。
In the case of coexistence of the two, thenumerical valueIn the operation, the priority is calledvalueOf
,character stringIn the operation, the priority is calledtoString
。
Look at the code
class A {
valueOf() {
return 2
}
toString() {
Return 'hahaha'
}
}
let a = new A()
console.log (string (a)) //'ha ha '= > (toString)
console.log(Number(a)) // 2 => (valueOf)
console.log(a + '22') // '222' => (valueOf)
console.log(a == 2) // true => (valueOf)
console.log (a = = = 2) // false = > (strictly equal to not trigger implicit conversion)
The result gives the impression that if converted to a string, thetoString
Method, called if it is converted to a numeric valuevalueOf
method.
But some of thema + '22'
Very discordant, string combination should be calledtoString
method. In order to find out the truth, we need more rigorous experiments.
- Let’s take a look at it for a moment
valueOf
Method remove
class A {
toString() {
Return 'hahaha'
}
}
let a = new A()
console.log (string (a)) //'ha ha '= > (toString)
console.log(Number(a)) // NaN => (toString)
console.log (a +'22 ') /'hahaha 22' = > (toString)
console.log(a == 2) // false => (toString)
- Remove
toString
Look at the method
class A {
valueOf() {
return 2
}
}
let a = new A()
console.log(String(a)) // '[object Object]' => (toString)
console.log(Number(a)) // 2 => (valueOf)
console.log(a + '22') // '222' => (valueOf)
console.log(a == 2) // true => (valueOf)
It’s different, isn’t it?! It’s not like abovetoString
So unified and regular.
For that[object Object]
I guess it’s fromObject
It’s inherited from there. Let’s take it out.
class A {
valueOf() {
return 2
}
}
let a = new A()
Object.prototype.toString = null;
console.log(String(a)) // 2 => (valueOf)
console.log(Number(a)) // 2 => (valueOf)
console.log(a + '22') // '222' => (valueOf)
console.log(a == 2) // true => (valueOf)
Conclusion:valueOf
It’s biased towards computation,toString
It tends to show.
- During object transformation, the
toString
Method, if not overriddentoString
, will callvalueOf
Method; if neither method is overridden, pressObject
OftoString
Output. - In progressStrongly convert string typeThe
toString
Method, which is called first when forced to a numbervalueOf
。 - In the case of operational operators,
valueOf
Priority of is higher thantoString
。
[Symbol.toPrimitive]
MDN: Symbol.toPrimitive Is a built-in symbol value, which exists as a function value attribute of an object. When an object is converted to its original value, this function will be called.
Is it a little confused??? Just think of it as a function~~
- Function: same as
valueOf()
andtoString()
It’s the same, butPriority should be given to both; -
When the function is called, a string parameter is passed
hint
, which represents the current operation mode. There are three modes:- String: string type
- Number: number type
- Default: default
Let’s take a look at the implementation
class A {
constructor(count) {
this.count = count
}
valueOf() {
return 2
}
toString() {
Return 'hahaha'
}
//I'm here
[Symbol.toPrimitive](hint) {
if (hint == "number") {
return 10;
}
if (hint == "string") {
return "Hello Libai";
}
return true;
}
}
const a = new A(10)
console.log(`${a}`) // 'Hello Libai' => (hint == "string")
console.log(String(a)) // 'Hello Libai' => (hint == "string")
console.log(+a) // 10 => (hint == "number")
console.log(a * 20) // 200 => (hint == "number")
console.log(a / 20) // 0.5 => (hint == "number")
console.log(Number(a)) // 10 => (hint == "number")
console.log(a + '22') // 'true22' => (hint == "default")
console.log(a == 10) // false => (hint == "default")
The more special is the (+) splice, which belongs to thedefault
It’s a new model.
Highlight: this method is not compatible with ie, so embarrassed that I don’t want to write it out~~
Analysis of interview questions
The following interview questions, which are required by big companies, are perfectly presentedtoString
AndvalueOf
The role of the government.
1. A = = 1 & & A = = 2 & & A = = 3 is true
Double equal sign (=): will triggerImplicit type conversion
, so it can be usedvalueOf
perhapstoString
To achieve.
Every judgment will triggervalueOf
Methods, and letvalue+1
To make the next judgment true.
class A {
constructor(value) {
this.value = value;
}
valueOf() {
return this.value++;
}
}
const a = new A(1);
if (a == 1 && a == 2 && a == 3) {
console.log("Hi Libai!");
}
Congruent (= = =): strictly equal to noImplicit transformation
, used hereObject.defineProperty
Data hijacking
let value = 1;
Object.defineProperty(window, 'a', {
get() {
return value++
}
})
if (a === 1 && a === 2 && a === 3) {
console.log("Hi Libai!")
}
Above we are the whole situationwindow
abovea
, whena
It’s triggered every time you make a judgmentget
Attribute to get the value, and each time to get the value will trigger a function to implement a self increment, judgment three times will be self increment three times, so the final formula will hold.
- Note:
defineProperty
Can refer to this article to learn, click me to enter the portal - How to make the value of (a = = 1 & & A = = 2 & & A = = 3) true?
2. Realize an infinite accumulation function
Problem: using JS to realize an infinite accumulation functionadd
Examples are as follows:
add(1); // 1
add(1)(2); // 3
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10
//And so on
function add(a) {
Function sum (b) {// using closure
A = B? A + B: a; // accumulation
return sum;
}
sum.toString =Function () {// is only called the last time
return a;
}
Return sum; // returns a function
}
add(1) // 1
add(1)(2) // 3
add(1)(2)(3) // 6
add(1)(2)(3)(4) // 10
add
Function internal definitionsum
Function and return to realize continuous callsum
Function to form a closure, each call to accumulate values, and then return the current functionsum
add()
One function is returned each timesum
Until the last one is not called, it will be triggered by defaulttoString
Method, so we rewrite it heretoString
Method and returns the cumulative final valuea
Only in this way can we understand:
add(10)
: execute functionadd(10)
, backsum
Function, note that this time there is no callsum
, default executionsum.toString
method. So output10
;
add(10)(20)
: execute functionadd(10)
, return sum (in this case, a is 10), and then executesum(20)
, at this timeA = 30
, backsum
Last callsum.toString()
output30
. Add (10) (20)… (n) and so on.
3. Realize multi parameter accumulation by Coriolis
Here is the above cumulative upgrade, to achieve multi parameter transfer accumulation.
add(1)(3,4)(3,5) // 16
add(2)(2)(3,5) // 12
function add(){
//1 converts all parameters to an array
let args = Array.prototype.slice.call(arguments)
//2 call the add function again to pass and merge the current and previous parameters
let fn = function() {
let arg_fn = Array.prototype.slice.call(arguments)
return add.apply(null, args.concat(arg_fn))
}
//Finally, it is called by default to return the merged value
fn.toString = function() {
return args.reduce(function(a, b) {
return a + b
})
}
return fn
}
//ES6 writing
function add () {
let args = [...arguments];
let fn = function(){
return add.apply(null, args.concat([...arguments]))
}
fn.toString = () => args.reduce((a, b) => a + b)
return fn;
}
summary
If Xiaobai’s writing is not good, please give me a suggestionIf it helps you, please like it
More information sharing:
- A programming ape who can’t write is not a good programming ape
- A front-end learning notes based on vuepress, record, just for better fishing
- Vue, nuxt server rendering, nodejs full stack project ~ perfect system for Xiaobai~