2009-12-07 39 views
6

數的方法奇怪的語法看看下面的代碼:的JavaScript中

Number.prototype.isIn = function() { 
    for (var i = 0, j = arguments.length; i < j; ++i) { 
     if (parseInt(this, 10) === arguments[i]) { 
      return true; 
     } 
    } 
    return false; 
}; 

var x = 2; 
console.log(x.isIn(1,2,3,4,5)); // <= 'true' 
console.log(2.isIn(1,2,3,4,5)); // <= Error: 'missing) after argument list' 

爲什麼,當它是一個變量,代碼工作正常但是當它是一個數字的文字,它失敗了呢?


而且,奇怪的是,爲什麼下面的行會起作用?

console.log((2).isIn(1,2,3,4,5)); // <= 'true' 

在上面的一行中,我基本上將括號中的文字括起來。

回答

10

這是一個語法錯誤,因爲您代表的是數字。字符串可以以這種方式工作,但不能用數字,因爲緊跟在數字後面的一個句號表示十進制值。 .之後的字符導致錯誤。

-1

我的理解是數字是文字,而不是的一個對象。但是,當您將一個變量定義爲一個數字時,它將變成一個新的Number()對象。

這樣做如下:

var x = 10; 

與去相同;

var x = new Number(10); 

至於第二個例子;我只能假設在數字周圍放置括號使得JavaScript編譯器假定這個值是一個匿名的Number()對象。這是有道理我猜...

+3

'x = 10'和'x = new Number(10)'是不等價的。 – 2009-12-07 16:31:15

+0

正確:'alert(typeof 10);'''alert(typeof new Number(10));' – 2009-12-07 16:35:31

+0

感謝您的更正。 – Cammy 2009-12-07 18:00:16

0

雖然區別往往是因爲自動類型轉換並不明顯,JavaScript的支持許多基本數據類型,以及對象:

var foo = 10; 
var bar = new Number(10); 
alert(foo.toString(16)); // foo is automatically wrapped in an object of type Number 
         // and that object's toString method is invoked 
alert(bar.toString(16)); // bar is already an object of type Number, 
         // so no type conversion is necessary before 
         // invoking its toString method 
var foo2 = "foo"; 
var bar2 = new String("foo"); 
alert(typeof foo2);  // "string" - note the lowercase "s", not a String object 
alert(typeof bar2);  // "object" 

alert(typeof true)  // "boolean" 
alert(typeof new Boolean(true)) // "object" 

和一些真正的困惑問題:

// the next line will alert "truthy" 
alert("Boolean object with value 'false'" + (new Boolean(false) ? " is truthy" : " is falsy")); 
// the next line will alert "falsy" 
alert("boolean primitive with value 'false'" + (false ? " is truthy" : " is falsy")); 

儘管依靠自動類型轉換,讓生活變得更輕鬆,每個人都應該有一個處的腦海裏什麼類型的原始值有很好的理解和實際的對象;出現了大量的JS bug,這是因爲人們沒有意識到這一點,例如,看起來像一個數字的東西實際上是一個字符串,或者他們進行的一些操作導致了一些曾經包含數字的東西被分配了一個新的值,它是一個字符串或一個對象。

編輯:更緊密地解決原來的問題,我現在意識到我沒有明確回答:10.foo()會導致語法錯誤的.被看作是一個小數點,而foo()是不是一個有效的序列字符被解析爲數字。 (10).foo()將作爲封閉括號(10)使.之前的整個構造成爲一個單一的表達式。評估該表達式並返回原始數值10。然後.被視爲在對象上下文中處理該原始值,因此它會自動包裝在類型爲Number的對象中(這是自動類型轉換的實際操作)。然後引用在其原型鏈上找到的該對象的foo屬性;並且最後的()導致該屬性被視爲函數引用,並在遇到.時包圍在原始值周圍的Number對象的'this'上下文中調用該屬性。

+0

'10'和'Number(10)'是相同的。 'bar = Number(10)'不會將'bar'變成「Number類型的對象」。也許你打算把'10'與'新號碼(10)'進行比較?或'10'與'Number('10')'? – 2009-12-07 17:22:26

+0

糟糕,趕上 - '新'失蹤。我應該從控制檯中複製這些東西,而不是重新輸入:-) – NickFitz 2009-12-07 17:33:20

2

喬希是正確的,但你不必使用變量來使用數字的方法, 雖然這樣做通常更方便。

5.isIn(1,2,3,4,5) returns an error 

5.0.isIn(1.2.3.4.5) returns true, as does 
(5).isIn(1,2,3,4,5) 
+0

'5..isIn'和'5 .isIn'也會去除[解析]歧義。 – 2009-12-07 20:09:26

7

大多數答案已經指出,數字文字之後的點被認爲是該數字的一部分,作爲分數分隔符。但是如果你仍然想使用點作爲操作符,那麼快速簡單的修復就會在數字和空間之間留下一個空白空間。

2 .isIn(1,2,3,4,5) // <- notice the space between 2 and . 
+0

+1嗯,這是一個有趣的空白使用! – 2009-12-07 21:39:35

+0

實際上它很合乎邏輯 - 點是JavaScript中的標準運算符,就像+或=或 - 。你可以寫4 + 5這樣的東西,所以你可以使用4。 isIn()也是如此。 – Andris 2009-12-08 10:10:12

+0

@Andris,很好的答案。然而,要注意的是,添加括號更好(2).isIn(1,2,3,4,5,6)(在可讀性方面) – shabunc 2011-07-26 12:13:47