摘要:原文來(lái)源于我的前言身為一種弱類(lèi)型的語(yǔ)言,不用像語(yǔ)言那樣要定義等等數(shù)據(jù)類(lèi)型,因?yàn)樵试S變量類(lèi)型的隱式轉(zhuǎn)換和允許強(qiáng)制類(lèi)型轉(zhuǎn)換。
原文來(lái)源于我的github 0.前言
js身為一種弱類(lèi)型的語(yǔ)言,不用像c語(yǔ)言那樣要定義int、float、double、string等等數(shù)據(jù)類(lèi)型,因?yàn)樵试S變量類(lèi)型的隱式轉(zhuǎn)換和允許強(qiáng)制類(lèi)型轉(zhuǎn)換。我們?cè)诙x一個(gè)變量的時(shí)候,就一個(gè)var、let、const搞定,不用擔(dān)心數(shù)據(jù)的類(lèi)型。比如常見(jiàn)的字符串拼接,用+號(hào)可以實(shí)現(xiàn)變量和字符串的拼接。
總的來(lái)說(shuō),一般的規(guī)則是
!后面的字符會(huì)被轉(zhuǎn)為換布爾
+后面的字符會(huì)被轉(zhuǎn)換為數(shù)值(-也是差不多)
[]+后面的字符會(huì)被轉(zhuǎn)換為字符串
對(duì)于object和number、string、boolean之間的轉(zhuǎn)換關(guān)系,這里偷網(wǎng)上一幅圖
Object 與Primitive,需要Object轉(zhuǎn)為Primitive
String 與 Boolean,需要兩個(gè)操作數(shù)同時(shí)轉(zhuǎn)為Number。
String/Boolean 與 Number,需要String/Boolean轉(zhuǎn)為Number。
undefined 與 null ,和所有其他值比較的結(jié)果都是false,他們之間==成立
ToPrimitive是指轉(zhuǎn)換為js內(nèi)部的原始值,如果是非原始值則轉(zhuǎn)為原始值,調(diào)用valueOf()和obj.toString()來(lái)實(shí)現(xiàn)。valueOf返回對(duì)象的值:在控制臺(tái),當(dāng)你定義一個(gè)對(duì)象按回車(chē),控制臺(tái)打印的是Object{...},obj.toString()返回對(duì)象轉(zhuǎn)字符串的形式,打印的是"[object Object]"
如果參數(shù)是Date對(duì)象的實(shí)例,那么先toString()如果是原始值則返回,否則再valueOf(),如果是原始值則返回,否則報(bào)錯(cuò)。
如果參數(shù)不是Date對(duì)象的實(shí)例,同理,不過(guò)先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 []==![] //true2.從[]==![]開(kāi)始
大家也可能聽(tīng)說(shuō)過(guò)[]!=[],主要是因?yàn)樗麄兪且妙?lèi)型,內(nèi)存地址不同所以不相等。那么為什么加了一個(gè)!就能等于了?不是內(nèi)存地址還是不一樣嗎?
這又引出一個(gè)問(wèn)題,符號(hào)的優(yōu)先度
1 | . [] () |
2 | ++ — ~ ! |
3 | * / % |
4 | + - + |
5 | << >> |
4 | + - + |
5 | < <= > >= |
4 | + - + |
6 | == != === !== |
可以看見(jiàn),!優(yōu)先度是第二,所以先判斷!再判斷=
給[]取反,會(huì)是布爾值,[]的取反的布爾值就是false
非布爾類(lèi)型轉(zhuǎn)布爾類(lèi)型:undefined、null 、0、±0、NaN、0長(zhǎng)度的字符串=》false,對(duì)象=》true
非數(shù)字類(lèi)型轉(zhuǎn)數(shù)字類(lèi)型:undefined=》NaN,null=》0,true=》1,false=》0,字符串:字符串?dāng)?shù)字直接轉(zhuǎn)數(shù)字類(lèi)型、字符串非數(shù)字=》NaN
[]也是對(duì)象類(lèi)型(typeof [] == "object"),轉(zhuǎn)為布爾類(lèi)型的![]就是false
2.2 等號(hào)兩邊對(duì)比我們知道,在比較類(lèi)型的時(shí)候,先會(huì)進(jìn)行各種各樣的類(lèi)型轉(zhuǎn)換。
從開(kāi)頭的表格可以看見(jiàn),他們比較的時(shí)候都是先轉(zhuǎn)換為數(shù)字類(lèi)型。右邊是布爾值false,左邊為一個(gè)空數(shù)組對(duì)象,對(duì)于左邊,先進(jìn)行P操作(ToPrimitive([])),先執(zhí)行valueOf([])返回的是[],非原始類(lèi)型,再
[].toString(),返回的是"",那P操作之后,結(jié)果就是""了
最后,左邊""和右邊f(xié)alse對(duì)比,他們?cè)俎D(zhuǎn)換為數(shù)字,就是0==0的問(wèn)題了
我們知道,數(shù)組有自己的一套方法,比如var arr = [1,2];arr.push(1),我們可以寫(xiě)成[1,2].push(1),還可以寫(xiě)成[1,2]["push"](1),那么前面拋出的問(wèn)題就解決了
[]["push"](1) //[1] []["map"] //function map() { [native code] } []["map"]+[] // "function map() { [native code] }"3.2 間接進(jìn)行下標(biāo)操作 3.2.1數(shù)字的獲取
我們可以通過(guò)類(lèi)型轉(zhuǎn)換,獲得0和1兩個(gè)數(shù)字,既然能得到這兩個(gè)數(shù)字,那么也可以得到其他的一切數(shù)字了:
+[] === 0; +!![] === 1
那么, +!![]+!![] ===2,+((+![])+(+!![])+[]+(+![]))===10(注意:中間沒(méi)[]的話,就是數(shù)字的1+0,結(jié)果就是1了,有的話就是"1"+""+"0")
+((+![])+(+!![])+[]+(+![]))-!![] ===9
簡(jiǎn)直就是無(wú)所不能
(![]+[])[+[]] //"f" (![]+[])[+!![]] // "a"
(![]+[])是"false",其實(shí)(![]+[])[+[]] 就相當(dāng)于"false"[0],第一個(gè)字母,就是f
我們就可以從上面的那些獲得單詞的字符串獲得其中的字母了
好了,說(shuō)道這里,要是誰(shuí)說(shuō)前端簡(jiǎn)單,那就給他一個(gè)(![]+[])[+!![]+!![]+!![]] +([]+{})[+!![]+!![]]
近來(lái)有人問(wèn)這個(gè)問(wèn)題(a==1 && a==2 && a==3) 或者(a===1 && a===2 && a===3) 能不能為true?
事實(shí)上是可以的,就是因?yàn)樵?=比較的情況下,會(huì)進(jìn)行類(lèi)型的隱式轉(zhuǎn)換。前面已經(jīng)說(shuō)過(guò),如果參數(shù)不是Date對(duì)象的實(shí)例,就會(huì)進(jìn)行類(lèi)型轉(zhuǎn)換,先valueOf再obj.toString()
所以,我們只要改變?cè)膙alueOf或者tostring方法就可以達(dá)到效果:
var a = { num: 0, valueOf: function() { return this.num += 1 } }; var eq = (a==1 && a==2 && a==3); console.log(eq); //或者改寫(xiě)他的tostring方法 var num = 0; Function.prototype.toString = function(){ return ++num; } function a(){} //還可以改寫(xiě)ES6的symbol類(lèi)型的toP的方法 var a = {[Symbol.toPrimitive]: (function (i) { return function(){return ++i } }) (0)};
每一次進(jìn)行等號(hào)的比較,就會(huì)調(diào)用一次valueOf方法,自增1,所以能成立。當(dāng)然,如果換個(gè)位置就不行了,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 ===
如果沒(méi)有類(lèi)型轉(zhuǎn)換,===的情況,還是可以的。跑題...
在vue源碼實(shí)現(xiàn)雙向數(shù)據(jù)綁定中,就利用了defineProperty方法進(jìn)行觀察,觀察到視圖層的變化并實(shí)時(shí)反映到model層。
每一次訪問(wèn)對(duì)象中的某一個(gè)屬性的時(shí)候,就會(huì)調(diào)用這個(gè)方法定義的對(duì)象里面的get方法。每一次改變對(duì)象屬性的值,就會(huì)訪問(wèn)set方法
在這里,我們自己定義自己的get方法:
var b = 1 Object.defineProperty(window, "a", { get:function() { return b++; } }) var s = (a===1 && a===2 && a === 3 ) console.log(s)
每一次訪問(wèn)a屬性,a的屬性值就會(huì)+1,當(dāng)然還是交換位置就不能為T(mén)RUE了
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94363.html
摘要:讓我們快速的復(fù)習(xí)一下在中一共有兩種類(lèi)型的值原始值和對(duì)象值原始值有布爾值數(shù)字還有字符串其他的所有值都是對(duì)象類(lèi)型的值包括數(shù)組和函數(shù)類(lèi)型轉(zhuǎn)化先按運(yùn)算符來(lái)分一下類(lèi)減號(hào),乘號(hào),肯定是進(jìn)行數(shù)學(xué)運(yùn)算,所以操作數(shù)需轉(zhuǎn)化為類(lèi)型。 前言 很多小伙伴們覺(jué)得javaScript很簡(jiǎn)單,下面的這行 javaScript代碼可能會(huì)讓你懷疑人生。 (!(~+[])+{})[--[~+][+[]]*[~+[]] +...
摘要:都快要來(lái)了,必須跟棧長(zhǎng)學(xué)起即將發(fā)布,新特性必須搶先看棧長(zhǎng)之前在技術(shù)棧微信公眾號(hào)分享過(guò)已發(fā)布,還能這樣玩這篇文章,介紹了的新玩法,讓大家耳目一新。更多關(guān)于的資訊干貨教程以及好消息,請(qǐng)關(guān)注微信公眾號(hào)技術(shù)棧,第一時(shí)間推送。 Java 13 都快要來(lái)了,12必須跟棧長(zhǎng)學(xué)起! Java 13 即將發(fā)布,新特性必須搶先看! 棧長(zhǎng)之前在Java技術(shù)棧微信公眾號(hào)分享過(guò)《Java 11 已發(fā)布,Stri...
摘要:前幾天李老哥秀了一個(gè)中騷操作給我看,即的值是各位也可以看一下臥槽,牛逼啊很好奇,如何得到這個(gè)結(jié)果,莫名其妙就得到了我第一感覺(jué)是不可能啊,可是結(jié)果就在那這就要思考了,這個(gè)是什么碼的騷操作計(jì)算得來(lái)的數(shù)字結(jié)果還是字符轉(zhuǎn)化,或是別的什么,它是通過(guò)什 前幾天李老哥秀了一個(gè)JavaScript中騷操作給我看,即++[[]][+[]]+[+[]]的值是10;各位也可以看一下 console.log(...
摘要:沒(méi)錯(cuò),在中你一樣可以這樣簡(jiǎn)單的操作,而不同的是你操作的是一整列的字符串?dāng)?shù)據(jù)。因?yàn)閷?duì)于類(lèi)型的,字符的操作發(fā)生在的非重復(fù)值上,而并非原上的所有元素上。下面的這些屬性基本都是關(guān)于查看和操作數(shù)據(jù)類(lèi)型的。 作者:xiaoyu 微信公眾號(hào):Python數(shù)據(jù)科學(xué) 知乎:python數(shù)據(jù)分析師 showImg(https://segmentfault.com/img/remote/146000001...
摘要:沒(méi)錯(cuò),在中你一樣可以這樣簡(jiǎn)單的操作,而不同的是你操作的是一整列的字符串?dāng)?shù)據(jù)。因?yàn)閷?duì)于類(lèi)型的,字符的操作發(fā)生在的非重復(fù)值上,而并非原上的所有元素上。下面的這些屬性基本都是關(guān)于查看和操作數(shù)據(jù)類(lèi)型的。 作者:xiaoyu 微信公眾號(hào):Python數(shù)據(jù)科學(xué) 知乎:python數(shù)據(jù)分析師 showImg(https://segmentfault.com/img/remote/146000001...
閱讀 2084·2021-09-22 15:54
閱讀 1844·2021-09-04 16:40
閱讀 869·2019-08-30 15:56
閱讀 2632·2019-08-30 15:44
閱讀 2159·2019-08-30 13:52
閱讀 1132·2019-08-29 16:35
閱讀 3352·2019-08-29 16:31
閱讀 2571·2019-08-29 13:48