摘要:方法和方法介紹方法和我們知道在中,一切皆為對象。每個對象都有一個方法和方法,其中方法返回一個表示該對象的字符串,方法返回該對象的原始值。這兩個方法都是原型鏈上的方法,被每個對象所繼承。
valueOf()方法和toString()方法介紹
valueOf()方法和toString()
我們知道在js中,"一切皆為對象"。每個對象都有一個toString()方法和value方法,其中toString()方法返回一個表示該對象的字符串,value方法返回該對象的原始值。對于toString方法來說,當對象被表示為文本值或者當以期望字符串的方式引用對象時。該方法被自動調用。對于一個對象,toSting()返回"[object type]",其中type是對象類型。如果x不是對象,toString()返回應有的文本值。
對于valueOf() 方法來說,默認情況下, valueOf() 會被每個對象Object繼承。每一個內置對象都會覆蓋這個方法為了返回一個合理的值,如果對象沒有原始值,valueOf() 就會返回對象自身。
但是注意,對于Null如果
不同類型的對象的value方法的返回值
對象 | 返回值 |
---|---|
Array | 返回數組對象本身 |
Boolean | 布爾值 |
Date | 返回的時間是從1970年1月1日午夜開始計的毫秒數UTC |
Function | 函數本身 |
Number | 數字值 |
Object | 對象本身。這是默認情況 |
String | 字符串值 |
Math和Error對象沒有valueOf方法 |
二者的使用場景以及區別與比較
通過來自MDN[!https://developer.mozilla.org...]上面對兩個方法的介紹,我們得知。這兩個方法都是Object原型鏈上的方法,被每個對象所繼承。下面,我們看下該方法在兩個應用場景下的區別。
1、對于值類型數據(又叫基本類型)場景下,toString及valueOf方法的使用
var str = "hello",n = 123,bool = true; console.log(typeof(str.toString())+ "_"+ str.toString()) //string_hello console.log(typeof(n.toString())+"_"+n.toString() ) //string_123 console.log(typeof(bool.toString())+"_"+bool.toString()) //string_true
toString放對于值類型數據使用而言,其效果相當于類型轉換,將原類型轉為字符串。
console.log(typeof(str.valueOf())+"_"+str.valueOf()) //string_hello console.log(typeof(n.valueOf())+"_"+n.valueOf()) //string_123 console.log(typeof(bool.valueOf())+"_"+bool.valueOf()) //string_true console.log(str.valueOf === str) // // true console.log(n.valueOf === n) // // true console.log(bool.valueOf() === bool) // true
由上面的例子可以得出,
toString方法對于值類型數據使用而言,其效果相當于類型轉換,將原類型轉為字符串。
valueOf方法對于值類型數據使用而言,其效果將相當于返回原數據。
2、復合對象類型數據使用toString及valueOf方法
var obj = {}; console.log(obj.toString()); //[object Object] 返回對象類型 console.log(obj.valueOf()); //{} 返回對象本身
可以看到與方法介紹中所說一致。下面讓我們看下,具體兩個方法是如何執行的。
var test = { i: 10, toString: function() { console.log("toString"); return this.i; }, valueOf: function() { console.log("valueOf"); return this.i; } } alert(test);// 10 toString alert(+test); // 10 valueOf alert(""+test); // 10 valueOf alert(String(test)); // 10 toString alert(Number(test)); // 10 valueOf alert(test == "10"); // true valueOf alert(test === "10"); // false
其中,第一個alert,我們可以看到調用了toString方法,說明alert這里是需要一個字符串,這樣我們可以推測,toString()方法一般不需要我們主動去顯示的調用,符合對象類型會在相應的場景中調用適合的方法,返回適當類型的值。
第二個,這里通過alert我們知道這里依然是需要一個字符串的值,所以這里是+test調用了toString方法。而對于test,調用valueOf方法。在有運算操作符的情況下,valueOf的優先級要高一點。可以看一個例子。
var ab = { i: 1, valueOf: function () { alert("你調用了a的valueOf函數"); return this.i; }, toString: function () { alert("你調用了a的toString函數"); return this.i; } }; var c = { i: +ab, valueOf: function () { alert("你調用了c的valueOf函數"); return this.i; }, toString: function () { alert("你調用了c的toString函數"); return this.i; } }; alert(c);
第三個,同樣我們可以把上面的例子改為。
var c = { i: ""+ab, valueOf: function () { alert("你調用了c的valueOf函數"); return this.i; }, toString: function () { alert("你調用了c的toString函數"); return this.i; } }; alert(c);
第四個,String方法是要返回一個字符串類型,所以這里調用了toString()方法。
第五個,強轉換為數字類型,調用了valueOf方法。
第六個,這個里面的判等的順序是,獲取原始值,然后判斷兩邊的原始值是否相等,所以調用valueOf。
第七個,alert(bbb === "10"); // false
===操作符不進行隱式轉換,判全等的第一個步驟是判斷類型,因為類型都不一樣了,所以后面什么都不會調用.
總結:
1、在進行強轉字符串類型時將優先調用toString方法,強轉為數字時優先調用valueOf。
2、在有運算操作符的情況下,valueOf的優先級高于toString。
這兩個方法一般是交由js去隱式調用,以滿足不同的運算情況。
在數值運算里,會優先調用valueOf(),如 a + b;
在字符串運算里,會優先調用toString(),如alert(c).
補充下toString()方法和String()方法的區別
toString()方法和String()方法都可以轉換為字符串類型。
1、toString()可以將所有的數據都轉換為字符串,但是要排除null和undefined
var str = false.toString(); console.log(str, typeof str); //false, string
但是 null和undefined不能轉換為字符串,null和undefined調用toString()方法會報錯
var str = null.toString(); var str = undefined.soString();
如果當前數據為數字類型,則toString()括號中的可以寫一個數字,代表進制,可以將數字轉化為對應進制字符串。
var num = 123; console.log(num.toString()+"_"+ typeof(num.toString())); //123_string console.log(num.toString(2)+"_"+typeof(num.toString())); //1111011_string console.log(num.toString(8)+"_"+typeof(num.toString())); //173_string console.log(num.toString(16)+"_"+typeof(num.toString())); //7b_string
2、String()可以將null和undefined轉換為字符串,但是沒法轉進制字符串。當 String() 和運算符 new 一起作為構造函數使用時,它返回一個新創建的 String 對象,存放的是字符串 s 或 s 的字符串表示。
var str = new String("123"); console.log(str+"_"+typeof(str)); //123_object
當不用 new 運算符調用 String() 時,它只是把s轉換成原始的字符串,并返回轉換后的值。
var str = String(s); console.log(str+"_"+typeof(str)) //123_stringSymbol.toPrimitive
對象的Symbol.toPrimitive屬性。指向一個方法。該對象被轉化為原始類型的值時,會調用這個辦法,返回該對象對應的原始類型值。
Symbol.toPrimitive被調用時,會接受一個字符串參數,表示當前運算的模式,一個有三種模式。
Number:該場合需要轉成數值
String:該場合需要轉成字符串
Default:該場合可以轉成數值,也可以轉成字符串。
以上內容來自阮老師的ES6入門,下面我們結合幾個例子,具體看下Symbol.toPrimitive是如何被調用的。
// 沒有 Symbol.toPrimitive 屬性的對象 var obj1 = {}; console.log(+obj1); //NaN console.log(`${obj1}`); //"[object Object]" console.log(obj1 + ""); //"[object Object]"
上面的結果我們可以通過上面說的toSting()方法和value方法去理解。
第一個,+符號。可以看成是是把數據轉化為數字類型,由于obj是個空對象,所以結果是NaN
第二個,是es6中的字符串的新語法,這里需要的結果是一個字符串,所以使用的是toString()方法,而toString()方法返回的是對象的類型。
第三個,這里是連接符連接obj。實際上也是需要字符串的結果,所以同理。
// 擁有 Symbol.toPrimitive 屬性的對象 var obj2 = { [Symbol.toPrimitive](hint) { if(hint == "number"){ return 10; } if(hint == "string"){ return "hello"; } return true; } } console.log(+obj2); //10 --hint in "number" console.log(`${obj2}`); //hello --hint is "string" console.log(obj2 + ""); //"true"
// 擁有 Symbol.toPrimitive 屬性的對象 let obj = { [Symbol.toPrimitive](hint) { if(hint === "number"){ console.log("Number場景"); return 123; } if(hint === "string"){ console.log("String場景"); return "str"; } if(hint === "default"){ console.log("Default 場景"); return "default"; } } } console.log(2*obj); // Number場景 246 console.log(3+obj); // String場景 3default console.log(obj + ""); // Default場景 default console.log(String(obj)); //String場景 str
由以上例子可以總結,一般情況下,+連接運算符傳入的參數是default,而對于乘法等算數運算符傳入的是number。對于String(str),${str}等情況,傳入的參數是defalut。
Symbol.toPrimitive和toString、valueOf
當然,你也可以重寫一個不做參數判斷的Symbol.toPrimitive方法,結合上面提到的toString,可以有以下例子。
let ab = { valueOf() { return 0; }, toString() { return "1"; }, [Symbol.toPrimitive]() { return 2; } } console.log(1+ab); console.log("1"+ab);
可以看到,Symbol.toPrimitive方法在轉換基本類型的時候優先級最高。
參考鏈接:
http://www.sohu.com/a/1464105...
https://www.cnblogs.com/good1...
https://www.jb51.net/article/...
https://yuchengkai.cn/docs/zh...
https://github.com/ruanyf/es6...
https://developer.mozilla.org...
https://blog.csdn.net/kittyji...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97524.html
摘要:本文將介紹規范中的抽象操作。它們主要用于規范的說明,不需要被真正地實現。該抽象操作接受一個參數和一個可選的參數。根據規范中的加法操作,對于操作,會調用和把和轉化為原始數據類型。 本文將介紹ECMAScript7規范中的ToPrimitive抽象操作。 預備知識 ECMAScript數據類型 ECMAScript數據類型細分為兩大類數據類型,一種是語言類型,一種是規范類型: 語言類型...
摘要:我們首先了解一下中有關類型轉換的知識。新增類型拋出異常從列表可以明顯看到少了一個類型轉換為的規則。這里要強調一點第二個表達式沒有涉及到強制類型轉換。如果文中有錯誤或者有某些強制轉換的情形沒有涉及到請及時留言告知,我會修改并補充進去。 javascript是一門非常奇特的語言,它有時候奇特的會讓人懷疑人生。比如讓我們看一下下面的一些奇葩例子: false == 0 ...
摘要:先測試得到以下結果可看到正則進行全局搜索判斷返回一個數據數組的首元素為成功匹配的文本因此每次進行時都會返回數組的首元素也就是匹配的文本由此實現這個功能參考自微信公眾號魚頭的海洋 參考自 微信公眾號 魚頭的Web海洋 關于這道題目: var a = ?; if (a == 1 && b == 2 && c == 3) { console.log(yes); } 學習了網上的幾種解...
摘要:通過使用其構造函數,可以將一個值的類型轉換為另一種類型。如果使用兩次,可用于將該值轉換為相應的布爾值。 編譯自:[1] + [2] – [3] === 9!? Looking into assembly code of coercion.全文從兩個題目來介紹類型轉換、寬松相等以及原始值的概念: [1] + [2] – [3] === 9 如果讓 a == true && a == fa...
摘要:我們再來回顧下文首提出的這個比較運算,首先為對象,則調用函數將其轉化為字符串對于右側的,首先會進行顯式類型轉換,將其轉化為。 JavaScript 運算符規則與隱式類型轉換詳解 從屬于筆者的現代 JavaScript 開發:語法基礎與工程實踐系列文章,主要探討 JavaScript 中令人迷惑的加減乘除與比較等常見運算中的規則與隱式類型轉換;本文中涉及的參考資料全部聲明在了JavaSc...
閱讀 2096·2021-11-23 09:51
閱讀 2839·2021-11-22 15:35
閱讀 2937·2019-08-30 15:53
閱讀 1037·2019-08-30 14:04
閱讀 3276·2019-08-29 12:39
閱讀 1802·2019-08-28 17:57
閱讀 1086·2019-08-26 13:39
閱讀 551·2019-08-26 13:34