關于js類型轉換騷操作

本文是lhyt本人原創(chuàng),希望用通俗易懂的方法來理解一些細節(jié)和難點。轉載時請注明出處。文章最早出現(xiàn)于本人github

0.前言

js身為一種弱類型的語言,不用像c語言那樣要定義int、float、double、string等等數(shù)據(jù)類型,因為允許變量類型的隱式轉換和允許強制類型轉換。我們在定義一個變量的時候,就一個var、let、const搞定,不用擔心數(shù)據(jù)的類型。比如常見的字符串拼接,用+號可以實現(xiàn)變量和字符串的拼接。

總的來說,一般的規(guī)則是

!后面的字符會被轉為換布爾

+后面的字符會被轉換為數(shù)值(-也是差不多)

[]+后面的字符會被轉換為字符串

對于object和number、string、boolean之間的轉換關系,這里偷網(wǎng)上一幅圖

Object 與Primitive,需要Object轉為Primitive

String 與 Boolean,需要兩個操作數(shù)同時轉為Number。

String/Boolean 與 Number,需要String/Boolean轉為Number。

undefined 與 null ,和所有其他值比較的結果都是false,他們之間==成立

ToPrimitive是指轉換為js內部的原始值,如果是非原始值則轉為原始值,調用valueOf()和obj.toString()來實現(xiàn)。valueOf返回對象的值:在控制臺,當你定義一個對象按回車,控制臺打印的是Object{...},obj.toString()返回對象轉字符串的形式,打印的是"[object Object]"

如果參數(shù)是Date對象的實例,那么先toString()如果是原始值則返回,否則再valueOf(),如果是原始值則返回,否則報錯。

如果參數(shù)不是Date對象的實例,同理,不過先valueOf再obj.toString()。

1.奇葩例子

![] //false;

+[] // 0

+![] // 0

[]+[] // ""

{}+{}//"[object Object][object Object]"

{}+[]//0

{a:0}+1 // 1

[]+{}//"[object Object]"

[]+![]//"false"

{}+[]//0

![]+[] // "false"

''+{} //"[object Object]"

{}+'' //0

[]["map"]+[] //"function map() { }"

[]["a"]+[] // "undefined"

[][[]] + []// "undefined"

+!![]+[] //"1"

+!![] //1

1-{} //NaN

1-[] //1

true-1 //0

{}-1 //-1

[]==![] //true

2.從[]==![]開始

大家也可能聽說過[]!=[],主要是因為他們是引用類型,內存地址不同所以不相等。那么為什么加了一個!就能等于了?不是內存地址還是不一樣嗎?

這又引出一個問題,符號的優(yōu)先度

1. [] ()

2 ++ — ~ !

3 * / %

4 + - +

5 <<? >>?

6 + - +

7 < <= > >=

8 + - +

9 ==? !=? ===? !==

可以看見,!優(yōu)先度是第二,所以先判斷!再判斷=

給[]取反,會是布爾值,[]的取反的布爾值就是false

2.1 []的反就是false?

ECMA規(guī)范:

非布爾類型轉布爾類型:undefined、null 、0、±0、NaN、0長度的字符串=》false,對象=》true

非數(shù)字類型轉數(shù)字類型:undefined=》NaN,null=》0,true=》0,false=》1,字符串:字符串數(shù)字直接轉數(shù)字類型、字符串非數(shù)字=》NaN

[]也是對象類型(typeof [] == "object"),轉為布爾類型的![]就是false

2.2 等號兩邊對比

我們知道,在比較類型的時候,先會進行各種各樣的類型轉換。

從開頭的表格可以看見,他們比較的時候都是先轉換為數(shù)字類型。右邊是布爾值false,左邊為一個空數(shù)組對象,對于左邊,先進行P操作(ToPrimitive([])),先執(zhí)行valueOf([])返回的是[],非原始類型,再

[].toString(),返回的是"",那P操作之后,結果就是""了

最后,左邊""和右邊f(xié)alse對比,他們再轉換為數(shù)字,就是0==0的問題了

3.從已有的得到想不到的

3.1 間接獲取數(shù)組方法

我們知道,數(shù)組有自己的一套方法,比如var arr = [1,2];arr.push(1),我們可以寫成[1,2].push(1),還可以寫成[1,2]['push'](1),那么前面拋出的問題就解決了

[]['push'](1)//[1]

[]["map"] //function map() { [native code] }

[]["map"]+[] // "function map() { [native code] }"

3.2 間接進行下標操作

3.2.1數(shù)字的獲取

我們可以通過類型轉換,獲得0和1兩個數(shù)字,既然能得到這兩個數(shù)字,那么也可以得到其他的一切數(shù)字了:

+[] === 0; +!![] === 1

那么, +!![]+!![] ===2,+((+![])+(+!![])+[]+(+![]))===10(注意:中間沒[]的話,就是數(shù)字的1+0,結果就是1了,有的話就是'1'+''+'0')

+((+![])+(+!![])+[]+(+![]))-!![] ===9

簡直就是無所不能

3.2.2 字符串下標

(![]+[])[+[]] //"f"

(![]+[])[+!![]] // "a"

(![]+[])是"false",其實(![]+[])[+[]] 就相當于"false"[0],第一個字母,就是f

我們就可以從上面的那些獲得單詞的字符串獲得其中的字母了

好了,說道這里,要是誰說前端簡單,那就給他一個(![]+[])[+!![]+!![]+!![]] +([]+{})[+!![]+!![]]

4.關于(a==1 && a==2 && a==3)

4.1 ==

近來有人問這個問題(a==1 && a==2 && a==3) 或者(a===1 && a===2 && a===3) 能不能為true?

事實上是可以的,就是因為在==比較的情況下,會進行類型的隱式轉換。前面已經(jīng)說過,如果參數(shù)不是Date對象的實例,就會進行類型轉換,先valueOf再obj.toString()

所以,我們只要改變原生的valueOf方法就可以達到效果:

var a = {

num: 0,

valueOf: function() {

return this.num += 1

}

};

var eq = (a==1 && a==2 && a==3);

console.log(eq);

每一次進行等號的比較,就會調用一次valueOf方法,自增1,所以能成立。當然,如果換個位置就不行了,var eq = (a==2 && a==1 && a==3);

另外,減法也是同理:

var a = {

num: 4,

valueOf: function() {

return this.num -= 1

}

};

var eq = (a==3 && a==2 && a==1);

console.log(eq);

4.2 ===

如果沒有類型轉換,===的情況,還是可以的。跑題...

在vue源碼實現(xiàn)雙向數(shù)據(jù)綁定中,就利用了defineProperty方法進行觀察,觀察到視圖層的變化并實時反映到model層。

每一次訪問對象中的某一個屬性的時候,就會調用這個方法定義的對象里面的get方法。每一次改變對象屬性的值,就會訪問set方法

在這里,我們自己定義自己的get方法:

var b = 1

Object.defineProperty(window, 'a', {

get:function() { return b++; }

})

var s = (a===1 && a===2 && a === 3 )

console.log(s)

每一次訪問a屬性,a的屬性值就會+1,當然還是交換位置就不能為TRUE了


原文來自lhyt的github

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,546評論 0 13
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評論 19 139
  • 秋天最好看的風景是,陽光肆意,微風白云,佳人的披肩與短裙,明媚“凍”人,與金黃色的落葉交相輝映,一切都恰好,連心情...
    yaparis閱讀 275評論 0 0
  • 閱讀時間:2016年1月26日,19:30-21:30,2小時; 閱讀書本:《失控》,作者:【美】凱文·凱利;新星...
    時空山莊閱讀 234評論 0 1

友情鏈接更多精彩內容