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