文章出處

前面的話

  對于確定某個對象是不是數組,一直是數組的一個經典問題。本文專門將該問題擇出來,介紹什么才是正確的javascript數組檢測方式 

 

typeof

  首先,使用最常用的類型檢測工具——typeof運算符

var arr = [1,2,3];
console.log(typeof arr);//'object'

  前面已經介紹過,數組的本質是一種特殊的對象,所以返回'object'。typeof運算符只能用來區分原始類型和對象類型,對于更具體的對象類型是無法鑒別出來的

 

instanceof

  這時,該instanceof運算符出場了,instanceof運算符用來判斷一個對象是否是特定構造函數的實例

var arr = [1,2,3];
console.log(arr instanceof Array);//true

var str = '123';
console.log(str instanceof Array);//false

  看上去很實用。但,這時就引出了數組檢測的經典場景——網頁中包含多個框架

  【1】先創建一個父網頁box.html和子網頁in.html,其中父網頁通過iframe包含子網頁

//子網頁為空
//父網頁
<iframe name="child" src="in.html"></iframe>

  【2】測試父網頁和子網頁的通信,注意一定要在服務器環境下測試

//子網頁
var arr = [1,2,3];

//父網頁
window.onload = function(){
    console.log(child.window.arr);// [1,2,3]
}

  【3】測試成功,這時進行數組檢測

//子網頁
var arr = [1,2,3];

//父網頁
function test(arr){
    return arr instanceof Array;
}
window.onload = function(){
    console.log(child.window.arr);// [1,2,3]
    console.log(test(child.window.arr));//false
}

  測試后發現,數組檢測的結果是false。這是因為網頁中包含多個框架,那實際上就存在多個不同的全局環境,從而存在不同版本的Array構造函數。如果從一個框架向另一個框架傳入一個數組,那么傳入的數組與在第二個框架中原生創建的數組分別具有各自不同的構造函數

 

toString

  typeof操作符在這里幫不上忙,而instanceof操作符只能用于簡單的情形,這時就需要祭出大殺器——toString(),通過引用Object的toString()方法來檢查對象的類屬性,對數組而言該屬性的值總是"Array"

var arr = [1,2,3];
console.log(Object.prototype.toString.call(arr) === '[object Array]');//true

  或者,可以自定義類型識別函數

function type(obj){
    return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
}
var arr = [1,2,3];
console.log(type(arr));//'array'

  在多框架環境中測試,同樣返回'array'

//子網頁
var arr = [1,2,3];

//父網頁
function test(arr){
    return arr instanceof Array;
}
function type(obj){
    return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
}
window.onload = function(){
    console.log(child.window.arr);// [1,2,3]
    console.log(test(child.window.arr));//false
    console.log(type(child.window.arr));//'array'
}

 

isArray

  為了讓數組檢測更方便,ECMAScript5新增了Array.isArray()方法。該方法的目的是最終確定某個值到底是不是數組,而不管它在哪個全局環境中創建的 

var arr = [1,2,3];
console.log(Array.isArray([]));//true
console.log(Array.isArray({}));//false
console.log(Array.isArray(arr));//true

  在多框架環境中測試,同樣返回true

//子網頁
var arr = [1,2,3];

//父網頁
console.log(Array.isArray(child.window.arr));//true

 

完整測試代碼

【子網頁(in.html)】

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script>
var arr = [1,2,3];
</script>    
</body>
</html>

【父網頁(box.html)】

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<iframe name="child" src="in.html"></iframe>
<script>
function test(arr){
    return arr instanceof Array;
}
function type(obj){
    return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
}
window.onload = function(){
    console.log(child.window.arr);// [1,2,3]
    console.log(test(child.window.arr));//false
    console.log(type(child.window.arr));//'array'
    console.log(Array.isArray(child.window.arr));//true
}
</script>    
</body>
</html>

  


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()