2015-11-17 48 views
1
var d = []; 
console.log(typeof d); // weird! 
console.log(d.toString()); //Prints nothing since there are no elements in the array 
console.log(Object.prototype.toString.call(d)); // better! 

當我跑的第一印刷品的console.log對象,後者自陣列預計上面的代碼是一個對象和第二的console.log打印[對象陣列] 。我對Object.prototype.toString.call(d)如何工作有點困惑。陣列原型的toString()對對象的toString()

所以我知道數組原型上的toString方法只是試圖打印出數組內的元素。但是當你在基礎對象的原型上調用toString方法時,toString方法到底做了什麼?它是否嘗試打印出陣列的元素?基礎對象上的toString方法也使用關鍵字this,因爲我們使用的是.call,它會在調用函數時更改此關鍵字指向的內容。

回答

2

你能想到的Object.prototype.toString(或簡化版本),因爲這:

Object.prototype.toString = function() { 
    var myType = (typeof this)[0].toUpperCase() + (typeof this).substr(1); 
    return "[Object " + myType + "]"; 
} 

(無關:見注,答案是什麼(typeof運算本)[0]不解釋的底部,但假設對於現在的myType =「字符串」的字符串,「陣列」用於陣列等),因爲由於

和它的從[].toString()不同的陣列是一個對象的只是一個孩子,toString爲陣列只是覆蓋:

Array.prototype.toString = function() { 
    return this.join(','); 
} 

當您撥打Object.prototype.toString您指的是第一個功能,[].toString指的是第二個。這是沒有什麼不同,如果你這樣做:

function MyClass() {}; 
var x = new MyClass; 

x.toString(); // prints "[object Object]" 

MyClass.prototype.toString = function() { return 'hello!' } 
x.toString(); // prints "hello!" 

// and we can call Object's toString method instead 
Object.prototype.toString.call(x); // prints "[object Object]" 

第一次調用調用Object.prototype.toString因爲MyClassObject子類,並沒有自己的toString方法。然後當我們給MyClass a toString方法時,調用x.toStringMyClass上使用toString方法,最後我們可以再次調用我們的「超類」toString方法Object.prototype.toString.call(x)


這是什麼(typeof this)[0]做的?(typeof this)返回你的班級的名字。 typeof ""返回"string"typeof 5返回"number"等(注意,數組實際上有object,但[] instanceof Array是真的!)。但是這總是小寫的。 Object.prototype.toString返回一個字符串,如"Object String",其中對象的類型是大寫。 (typeof this)[0]「給我的字符串的第一個字符」(typeof this).substr(1)「給我的字符串的第一個字符」「以外的每個字符。同樣,這裏的字符串(typeof this)只是對象的小寫表示。呼叫toUpperCase確保第一個字符大寫。

+0

嗨!在這裏這行:var myType =(typeof this)[0] .toUpperCase()+(typeof this).substr(1);爲什麼你在[typeof this]之後有[0]?你可以走過變量myType將是什麼?像什麼將(打印此)[0] .toUpperCase()打印出來?陣列?和(typeof this).substr(1)。謝謝! – LP496

+1

當然,(typeof this)會返回你班級的名字。 typeof「」返回字符串,typeof []返回數組等。但是這總是小寫。 Object.prototype.toString返回一個字符串,比如「Object String」,其中對象的類型是大寫。 (typeof this)[0]說:「給我字符串的第一個字符,並且(typeof this).substr(1)說」給我字符串的第一個字符之外的所有字符「。這個)只是對象的小寫形式,toUpperCase調用確保第一個字符大寫 – Macmee

+0

Ohh ok!我不知道你可以使用[0]訪問字符串中的字符,所以在這種情況下( typeof這個)會返回一個小寫的數組a,並且你訪問一個並且使它成爲大寫。 – LP496

2

Object.prototype.toString.toString()的基本實現,即所有其他對象都繼承,除非它們專門覆蓋.toString()。它的默認實現是產生一個輸出看起來像這樣:

"[object Type]" 

其中type是像ObjectArray,等等......所以,對於一個普通的JS對象,它會產生:

"[object Object]" 

而且,對於一個陣列,它會產生:

"[object Array]" 

同時,Array類重寫.toString()以提供數組內容的串聯。

所以,如果你有一個數組或可能有一個數組對象,你想要的是第一種類型的.toString(),那麼你可以撥打:

Object.prototype.toString.call(obj) 

而且,這會告訴你你是否有數組對象與否。如果它是一個數組,你將獲得:

"[object Array]" 

除了新Array.isArray(),這通常被認爲是判斷你的對象是一個數組的最佳方式。


這裏有一個工作片斷說明:在JavaScript

var obj = {greeting: "hello"}; 
 
var arr = [1,2,3]; 
 

 
log(obj.toString()); 
 
log(Object.prototype.toString.call(obj)) 
 

 
log(arr.toString()); 
 
log(Object.prototype.toString.call(arr)) 
 

 
function log(x) { 
 
    var div = document.createElement("div") 
 
    div.innerHTML = x; 
 
    document.body.appendChild(div); 
 
}

+0

清除它!謝謝! – LP496

1

數據類型檢測可以改進。這是絕對可以的領域之一。但是,公平地說,這可能是因爲JavaScript在11天內被創建爲處理DOM的基本運行時;而且它確實!因此,只有在特殊情況下,我才需要這樣做。此外,JavaScript是圍繞非常簡化的類系統(稱爲原型)來進行的,這使得強制是一種典型的做法。因此,爲了向任何數據類型提供方法和屬性,它們暫時強制使用對象類型。這是該方法的基本方面之一。因此,主對象(如元素)沒有構造函數接口或標準的事實基本上解釋了數據類型的情況。 (當然,我們有內置插件和原生產品,例如Date,Math等)

同樣,JavaScript仍然做它開始要做的事情,特別是在很好的情況下,但是肯定可以改進!

我認爲它是這樣的:

  • typeof:元
  • Object.prototype.toString:對象(圖元)

這裏有一個很好的資源,解釋JavaScript的數據類型檢測:http://tobyho.com/2011/01/28/checking-types-in-javascript/

但是這裏有一個例程,我發現它適用於我需要的每種情況。所選操作和方法的順序已針對速度進行了專門優化。(僅供參考,您的使用情況可能會有所不同,所以一些訂單可能最好切換,但整體會工作得很好。):

type = type || 
( function detect(coerce) 
    { 
     if (typeof data === 'string') 
      return (coerce=document.getElementById(data)) ? (data=coerce,'element') : 'string'; 

     if (data.type && (data.srcElement||data.target)) 
      return 'event'; 

     if (data.nodeType != void 0) 
      return 'element'; 

     if (data[0] != void 0 && data[0].nodeType != void 0) 
      return 'elements'; 

     if (Object.prototype.call(data) === '[object Array]') 
      return 'array'; 

     if (data/1 === data) 
      return 'number'; 

     return 'object'; 
    } 
)(); 

既然你提Array Prototype,我的直覺是要告訴你: 「請不要修改數組原型。」 (它可能會導致環境在迭代和名稱空間中變得不穩定。)

其他人似乎也提供了大量信息!太好了!

+0

感謝您的信息! – LP496

+1

那麼,關於選擇的答案,'typeof'將以這種方式爲對象工作,但不是整體。也許他只是在展示事實。 – HTDE

+1

順便說一句,我只記得一個語法簡寫:'{} .toString.call'; (我相信這是正確的,儘管...創建一個可丟棄的對象) – HTDE

相關問題