javascript - slice用法 - true js
你如何檢查一個變量是否是JavaScript中的數組? (16)
這個問題在這裡已經有了答案:
- 檢查對像是否是數組? 37個答案
我想檢查一個變量是JavaScript中的數組還是單個值。
我找到了一個可能的解決方案...
if (variable.constructor == Array)...
這是可以做到的最好的方式嗎?
代碼來自https://github.com/miksago/Evan.js/blob/master/src/evan.js
var isArray = Array.isArray || function(obj) {
return !!(obj && obj.concat && obj.unshift && !obj.callee);};
以為我會為那些可能已經在其腳本中使用Underscore.js庫的人添加另一個選項。 Underscore.js有一個isArray()函數(請參閱http://underscorejs.org/#isArray )。
_.isArray(object)
如果object是一個Array,則返回true。
在Crockford的JavaScript Good Part中 ,有一個函數來檢查給定的參數是否為數組:
var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};
他解釋說:
首先,我們問這個價值是否真實。 我們這樣做是為了拒絕null和其他falsy值。 其次,我們詢問類型值是否是“對象”。 這對於對象,數組和(奇怪)null都是如此。 第三,我們詢問該值是否具有數字的長度屬性。 對於數組來說,這總是如此,但通常不適用於對象。 第四,我們詢問該值是否包含拼接方法。 對於所有陣列來說,這也是如此。 最後,我們問長度屬性是否可枚舉(將由for循環產生長度?)。 這對所有陣列都是錯誤的。 這是我發現的最可靠的陣列測試。 不幸的是,它太複雜了。
在現代瀏覽器(以及一些傳統瀏覽器)中,您可以這樣做
Array.isArray(obj)
( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray Chrome 5,Firefox 4.0,IE 9,Opera 10.5和Safari 5支持)
如果您需要支持較舊版本的IE,則可以使用es5-shim來es5-shim Array.isArray; 或添加以下內容
# only implement if no native implementation is available
if (typeof Array.isArray === 'undefined') {
Array.isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
};
如果你使用jQuery,你可以使用jQuery.isArray(obj)
或者$.isArray(obj)
。 如果你使用下劃線,你可以使用_.isArray(obj)
如果你不需要檢測在不同幀中創建的數組,你也可以使用instanceof
obj instanceof Array
注意 :可用於訪問函數參數的arguments
關鍵字不是數組,即使它(通常)的行為如下所示:
var func = function() {
console.log(arguments) // [1, 2, 3]
console.log(arguments.length) // 3
console.log(Array.isArray(arguments)) // false !!!
console.log(arguments.slice) // undefined (Array.prototype methods not available)
console.log([3,4,5].slice) // function slice() { [native code] }
}
func(1, 2, 3)
如果您正在使用Angular,則可以使用angular.isArray()函數
var myArray = [];
angular.isArray(myArray); // returns true
var myObj = {};
angular.isArray(myObj); //returns false
對於那些使用高爾夫球的人來說,用最少的字符進行不可靠的測試:
function isArray(a) {
return a.map;
}
這在遍歷/展平層次結構時通常使用:
function golf(a) {
return a.map?[].concat.apply([],a.map(golf)):a;
}
input: [1,2,[3,4,[5],6],[7,[8,[9]]]]
output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
我個人喜歡Peter的建議: https://.com/a/767499/414784 : Array.isArray()
對於ECMAScript 3.對於ECMAScript 5,請使用Array.isArray()
)
但是,對帖子的評論表明,如果toString()
完全改變,那麼檢查數組的方式將失敗。 如果你真的想要具體,並確保toString()
沒有被改變,並且對像類屬性沒有問題( [object Array]
是一個數組對象的類屬性),那麼我建議做像這樣的東西:
//see if toString returns proper class attributes of objects that are arrays
//returns -1 if it fails test
//returns true if it passes test and it's an array
//returns false if it passes test and it's not an array
function is_array(o)
{
// make sure an array has a class attribute of [object Array]
var check_class = Object.prototype.toString.call([]);
if(check_class === '[object Array]')
{
// test passed, now check
return Object.prototype.toString.call(o) === '[object Array]';
}
else
{
// may want to change return value to something more desirable
return -1;
}
}
請注意,在JavaScript權威指南第六版7.10中,它說Array.isArray()
是使用ECMAScript 5中的Array.isArray()
實現的。另外請注意,如果您要擔心toString()
'如果實施方式發生變化,您也應該擔心其他內置方法也在變化。 為什麼使用push()
? 有人可以改變它! 這種做法很愚蠢。 上述檢查是為那些擔心toString()
更改的人提供的解決方案,但我相信檢查是不必要的。
我剛想到的東西:
if (item.length) //This is an array else //not an array
我喜歡Brian的回答:
function is_array(o){
// make sure an array has a class attribute of [object Array]
var check_class = Object.prototype.toString.call([]);
if(check_class === '[object Array]') {
// test passed, now check
return Object.prototype.toString.call(o) === '[object Array]';
} else{
// may want to change return value to something more desirable
return -1;
}
}
但你可以這樣做:
return Object.prototype.toString.call(o) === Object.prototype.toString.call([]);
我正在使用這一行代碼:
if (variable.push) {
// variable is array, since AMAIK only arrays have push() method.
}
我認為使用myObj.constructor == Object和myArray.constructor == Array是最好的方法。 它比使用toString()快近20倍。 如果使用自己的構造函數擴展對象,並希望這些創建被視為“對象”,那麼這不起作用,否則其方式會更快。 typeof與構造函數方法一樣快,但typeof [] =='object'返回true,這通常是不可取的。 http://jsperf.com/constructor-vs-tostring
有一件事要注意的是,null.constructor會拋出一個錯誤,所以如果你可能正在檢查空值,你將不得不首先做(testThing!== null){}
有各種各樣的怪癖的解決方案。 本頁面提供了一個很好的概述。 一個可能的解決方案是
function isArray(o) {
return Object.prototype.toString.call(o) === '[object Array]';
}
由於.length屬性對於JavaScript中的數組是特殊的,因此您可以簡單地說
obj.length === +obj.length // true if obj is an array
Underscorejs和其他一些庫使用這個簡單而簡單的技巧。
當我發布這個問題時,我使用的JQuery版本沒有包含isArray
函數。 如果它有,我可能只是用它相信這個實現是執行這個特定類型檢查的最佳瀏覽器獨立方式。
既然JQuery現在提供了這個功能,我會一直使用它...
$.isArray(obj);
(從版本1.6.2開始)它仍然使用表單中字符串的比較來實現
toString.call(obj) === "[object Array]"
通用解決方案如下:
Object.prototype.toString.call(obj)=='[object Array]'
從ECMAScript 5開始,一個正式的解決方案是:
Array.isArray(arr)
另外,對於舊的JavaScript庫,你可以找到下面的解決方案,雖然它不夠準確:
var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};
解決方案來自http://www.pixelstech.net/topic/85-How-to-check-whether-an-object-is-an-array-or-not-in-JavaScript
通過Crockford :
function typeOf(value) {
var s = typeof value;
if (s === 'object') {
if (value) {
if (value instanceof Array) {
s = 'array';
}
} else {
s = 'null';
}
}
return s;
}
Crockford提到的主要失敗是無法正確確定在不同的上下文中創建的數組,例如window
。 如果這個頁面不夠完善,那麼這個頁面會有更複雜的版本。