日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
JS語法:由++[[]][+[]]+[+[]]=10引發(fā)的問題

解釋:為什么 ++[[]][+[]]+[+[]] = 10

成都創(chuàng)新互聯(lián)主要為客戶提供服務(wù)項目涵蓋了網(wǎng)頁視覺設(shè)計、VI標(biāo)志設(shè)計、網(wǎng)絡(luò)營銷推廣、網(wǎng)站程序開發(fā)、HTML5響應(yīng)式網(wǎng)站建設(shè)、成都手機(jī)網(wǎng)站制作、微商城、網(wǎng)站托管及網(wǎng)站建設(shè)維護(hù)、WEB系統(tǒng)開發(fā)、域名注冊、國內(nèi)外服務(wù)器租用、視頻、平面設(shè)計、SEO優(yōu)化排名。設(shè)計、前端、后端三個建站步驟的完善服務(wù)體系。一人跟蹤測試的建站服務(wù)標(biāo)準(zhǔn)。已經(jīng)為混凝土攪拌站行業(yè)客戶提供了網(wǎng)站開發(fā)服務(wù)。

[0]是一個帶有0成員的數(shù)組,[0][0]是取它的第1個成員,所以必是0。

用了[0][0] = '1'雖然改了第1成員的值,但下一個[0][0]是獨(dú)立的取成員值的表達(dá)式,所以得到0數(shù)字值。

[] = 1是右值不是iterable(可迭代的)造成的錯誤,這應(yīng)該是”解構(gòu)賦值”造成的錯誤,以不同的瀏覽器調(diào)試:

 
 
 
  1. // Chrome
  2. TypeError: undefined is not a function
  3.  
  4. // Firefox
  5. TypeError: 1 is not iterable
  6.  
  7. // Safari
  8. TypeError: [] is not a function. (In '[]', '[]' is undefined) 

數(shù)組解構(gòu)賦值的話,右值必需是iterable(可迭代的),下面的例子的錯誤與[] = 1是一樣錯誤,所以應(yīng)該會先檢查右值是否為iterable時,先拋出類型錯誤:

 
 
 
  1. [] = {};
  2. [] = undefined;
  3. [] = null; 

***的,[] = '1'不會有錯誤,是因?yàn)樽址菍儆趇terable(可迭代的)。

JS的{} + {}與{} + []的結(jié)果是什么?

ToPrimitive內(nèi)部運(yùn)算

因此,加號運(yùn)算符只能使用于原始數(shù)據(jù)類型,那么對于對象類型的值,要如何轉(zhuǎn)換為原始數(shù)據(jù)類型?下面說明是如何轉(zhuǎn)換為原始數(shù)據(jù)類型的。

在ECMAScript 6th Edition #7.1.1,有一個抽象的ToPrimitive運(yùn)算,它會用于對象轉(zhuǎn)換為原始數(shù)據(jù)類型,這個運(yùn)算不只會用在加號運(yùn)算符,也會用在關(guān)系比較或值相等比較的運(yùn)算中。下面有關(guān)于ToPrimitive的說明語法:

ToPrimitive(input, PreferredType?)input代表代入的值,而PreferredType可以是數(shù)字(Number)或字符串(String)其中一種,這會代表”優(yōu)先的”、”***的”的要進(jìn)行轉(zhuǎn)換到哪一種原始類型,轉(zhuǎn)換的步驟會依這里的值而有所不同。但如果沒有提供這個值也就是預(yù)設(shè)情況,則會設(shè)置轉(zhuǎn)換的hint值為”default”。這個***的轉(zhuǎn)換原始類型的指示(hint值),是在作內(nèi)部轉(zhuǎn)換時由JS視情況自動加上的,一般情況就是預(yù)設(shè)值。

而在JS的Object原型的設(shè)計中,都一定會有兩個valueOf與toString方法,所以這兩個方法在所有對象里面都會有,不過它們在轉(zhuǎn)換e有可能會交換被調(diào)用的順序。

當(dāng)PreferredType為數(shù)字(Number)時

當(dāng)PreferredType為數(shù)字(Number)時,input為要被轉(zhuǎn)換的值,以下是轉(zhuǎn)換這個input值的步驟:

  1. 如果input是原始數(shù)據(jù)類型,則直接返回input。
  2. 否則,如果input是個對象時,則調(diào)用對象的valueOf()方法,如果能得到原始數(shù)據(jù)類型的值,則返回這個值。
  3. 否則,如果input是個對象時,調(diào)用對象的toString()方法,如果能得到原始數(shù)據(jù)類型的值,則返回這個值。
  4. 否則,拋出TypeError錯誤。

當(dāng)PreferredType為字符串(String)時

上面的步驟2與3對調(diào).

PreferredType沒提供時,也就是hint為”default”時

與PreferredType為數(shù)字(Number)時的步驟相同。

數(shù)字其實(shí)是預(yù)設(shè)的***類型,也就是說在一般情況下,加號運(yùn)算中的對象要作轉(zhuǎn)型時,都是先調(diào)用valueOf再調(diào)用toString。

但這有兩個異常,一個是Date對象,另一是Symbol對象,它們覆蓋了原來的PreferredType行為,Date對象的預(yù)設(shè)***類型是字符串(String)。

因此你會看到在一些教程文件上會區(qū)分為兩大類對象,一類是 Date 對象,另一類叫 非Date(non-date) 對象。因?yàn)檫@兩大類的對象在進(jìn)行轉(zhuǎn)換為原始數(shù)據(jù)類型時,***類型恰好相反。

模擬代碼說明

 
 
 
  1. a + b:
  2.     pa = ToPrimitive(a)
  3.     pb = ToPrimitive(b)
  4.  
  5.     if(pa is string || pb is string)
  6.        return concat(ToString(pa), ToString(pb))
  7.     else
  8.        return add(ToNumber(pa), ToNumber(pb)) 

JS對于Object與Array的設(shè)計

在JS中所設(shè)計的Object純對象類型的valueOf與toString方法,它們的返回如下:

valueOf方法返回值: 對象本身。(所以ToPrimitive***要返回toString的值了)

toString方法返回值: “[object Object]”字符串值,不同的內(nèi)建對象的返回值是”[object type]”字符串,”type”指的是對象本身的類型識別,例如Math對象是返回”[object Math]”字符串。但有些內(nèi)建對象因?yàn)楦采w了這個方法,所以直接調(diào)用時不是這種值。(注意: 這個返回字符串的前面的”object”開頭英文是小寫,后面開頭英文是大寫)

一元正號(+),具有讓***類型(也就是hint)設(shè)置為數(shù)字(Number)的功能,所以可以強(qiáng)制讓對象轉(zhuǎn)為數(shù)字類型,一般的對象會轉(zhuǎn)為:

這里***類型其實(shí)本身就是數(shù)字,+讓toString輸出的字符串再強(qiáng)轉(zhuǎn)了一次。

 
 
 
  1. > +{} //相當(dāng)于 +"[object Object]"
  2. NaN 

當(dāng)然,對象的這兩個方法都可以被覆蓋,你可以用下面的代碼來觀察這兩個方法的運(yùn)行順序,下面這個都是先調(diào)用valueOf的情況:

 
 
 
  1. let obj = {
  2.   valueOf: function () {
  3.       console.log('valueOf');
  4.       return {}; // object
  5.   },
  6.   toString: function () {
  7.       console.log('toString');
  8.       return 'obj'; // string
  9.   }
  10. }
  11. console.log(1 + obj);  //valueOf -> toString -> '1obj'
  12. console.log(+obj); //valueOf -> toString -> NaN
  13. console.log('' + obj); //valueOf -> toString -> 'obj' 

實(shí)例

基本類型間運(yùn)算

字符串 + 其他原始類型字符串在加號運(yùn)算有***的優(yōu)先運(yùn)算

 
 
 
  1. > '1' + 123
  2. "1123"
  3.  
  4. > '1' + false
  5. "1false"
  6.  
  7. > '1' + null
  8. "1null"
  9.  
  10. > '1' + undefined
  11. "1undefined" 

數(shù)字 + 其他的非字符串的原始數(shù)據(jù)類型數(shù)字為優(yōu)先

 
 
 
  1. > 1 + true //true轉(zhuǎn)為1, false轉(zhuǎn)為0
  2. 2
  3.  
  4. > 1 + null //null轉(zhuǎn)為0
  5. 1
  6.  
  7. > 1 + undefined //null轉(zhuǎn)為NaN
  8. NaN 

數(shù)字/字符串以外的原始數(shù)據(jù)類型作加法運(yùn)算就是轉(zhuǎn)為數(shù)字再運(yùn)算

 
 
 
  1. > true + true
  2. 2
  3.  
  4. > true + null
  5. 1
  6.  
  7. > undefined + null
  8. NaN 

對象類型間運(yùn)算

  • 空數(shù)組 + 空數(shù)組
 
 
 
  1. > [] + []
  2. "" 

兩個數(shù)組相加,依然按照valueOf -> toString的順序,但因?yàn)関alueOf是數(shù)組本身,所以會以toString的返回值才是原始數(shù)據(jù)類型,也就是空字符串,所以這個運(yùn)算相當(dāng)于兩個空字符串在相加,依照加法運(yùn)算規(guī)則第2步驟,是字符串連接運(yùn)算(concatenation),兩個空字符串連接***得出一個空字符串。

  • 空對象 + 空對象

特別注意: {} + {}在不同的瀏覽器有不同結(jié)果

如果在***個(前面)的空對象加上圓括號(()),這樣JS就會認(rèn)為前面是個對象,就可以得出同樣的結(jié)果:

 
 
 
  1. > ({}) + {}
  2. "[object Object][object Object]" 

注: 上面說的行為這與加號運(yùn)算的***個(前面)的對象字面值是不是個空對象無關(guān),就算是里面有值的對象字面,例如{a:1, b:2},也是同樣的結(jié)果。

  • Date對象
 
 
 
  1. > 1 + (new Date())
  2. > "1Sun Nov 27 2016 01:09:03 GMT+0800 (CST)" 

要得出Date對象中的valueOf返回值,需要使用一元加號(+),來強(qiáng)制轉(zhuǎn)換它為數(shù)字類型,例如以下的代碼:

 
 
 
  1. > +new Date()
  2. 1480180751492 

總結(jié)

解構(gòu)賦值產(chǎn)生的問題

 
 
 
  1. > {name: 1}['name'] = '2'
  2. {name: 1}['name'] = '2'
  3.           ^^^^^^
  4. SyntaxError: Invalid destructuring assignment target 

上述錯誤。

 
 
 
  1. > {name: 1}[name] = '2'
  2. '2' 

{name: 1}[name]相當(dāng)于{name: 1};[name]。解構(gòu)賦值成功。

{}問題

 
 
 
  1. > var name = 'test'
  2. > {[name]:1}
  3. Object {1: 1}
  4. > {[name]:1};[name] = '1'
  5. VM174:1 Uncaught SyntaxError: Unexpected token : 

上述錯誤其實(shí)是由于,{[name]:1}中{}是表達(dá)式,返回對象;{[name]:1};[name] = ‘1’中{}是語句,語句中不允許”[name]:1“,換而言之語句中允許”{name: 1}”寫法。

{} + {}

{} + {}的結(jié)果是會因?yàn)g覽器而有不同結(jié)果,Chrome(v55)中是object Object字符串連接,但其它的瀏覽器則是認(rèn)為相當(dāng)于+{}運(yùn)算,得出NaN數(shù)字類型。

{} + []的結(jié)果是相當(dāng)于+[],結(jié)果是0數(shù)字類型。

Date對象

Date對象上面有提及是***類型為”字符串”的一種異常的對象,這與其他的對象的行為不同(一般對象會先調(diào)用valueOf再調(diào)用toString),在進(jìn)行加號運(yùn)算時時,它會優(yōu)先使用toString來進(jìn)行轉(zhuǎn)換,***必定是字符串連接運(yùn)算(concatenation)

 
 
 
  1. > 1 + (new Date())
  2. > "1Sun Nov 27 2016 01:09:03 GMT+0800 (CST)" 

toString()

Object.prototype.toString()才是用來檢測變量本身的類型,typeof是檢測基本類型,instanceof是檢測是否在原型鏈上。(注意一下Object.prototype.toString與Number.prototype.toString、Array.prototype.toString不同)

 
 
 
  1. > var a = 1
  2. undefined
  3. > a.toString()
  4. '1'
  5. > Number.prototype.toString.call(a)
  6. '1'
  7. > Object.prototype.toString.call([1, 2])
  8. '[object Array]'
  9. > Array.prototype.toString.call([1, 2])
  10. '1,2'
  11. > [1, 2].join()
  12. '1,2' 

toString方法返回值: “[object Object]”字符串值,不同的內(nèi)建對象的返回值是”[object type]”字符串,”type”指的是對象本身的類型識別,例如Math對象是返回”[object Math]”字符串。但有些內(nèi)建對象因?yàn)楦采w了這個方法,所以直接調(diào)用時不是這種值。(注意: 這個返回字符串的前面的”object”開頭英文是小寫,后面開頭英文是大寫。

 
 
 
  1. > Object.prototype.toString.call(null)
  2. '[object Null]'
  3. > typeof null
  4. 'object'
  5. > Object.prototype.toString.call(1)
  6. '[object Number]' 

Number()、String()與Boolean()

常被搞混的是直接使用Number()、String()與Boolean()三個強(qiáng)制轉(zhuǎn)換函數(shù)的用法,這與包裝對象的用法不同,包裝對象是必須使用new關(guān)鍵字進(jìn)行對象實(shí)例化的,例如new Number(123),而Number(‘123’)則是強(qiáng)制轉(zhuǎn)換其他類型為數(shù)字類型的函數(shù)。


分享題目:JS語法:由++[[]][+[]]+[+[]]=10引發(fā)的問題
URL地址:http://www.5511xx.com/article/ccdjese.html