2015-03-05 2 views
3

Я знаю, что мы можем обнаружить тип переменной в JavaScript, как это:Почему Object.prototype.toString.call (foo) определяет тип foo?

Object.prototype.toString.call([]); // [object Array] 
Object.prototype.toString.call({}); // [object Object] 
Object.prototype.toString.call(''); // [object String] 
Object.prototype.toString.call(new Date()); // [object Date] 
Object.prototype.toString.call(1); // [object Number] 
Object.prototype.toString.call(function() {}); // [object Function] 
Object.prototype.toString.call(/test/i); // [object RegExp] 
Object.prototype.toString.call(true); // [object Boolean] 
Object.prototype.toString.call(null); // [object Null] 
Object.prototype.toString.call(); // [object Undefined] 

Но почему?

Каковы эти значения ([Object Array], [object String] ...), и что делает Object.prototype.toString?

+2

Такие вещи [документально] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString) [amply.] (Http: // www. ecma-international.org/ecma-262/5.1/#sec-15.2.4) – Pointy

ответ

4

Object.prototype.toString в основном возвращает [[Class]] (реализация подробно) внутреннее свойство объектов. Цитирование the section из ECMA Script 5.1 спецификации, где это определено

  1. Если значение this является undefined, возвращение "[object Undefined]".
  2. Если значение this равно null, возврат "[object Null]".
  3. Позвольте O быть результатом вызова ToObject, передающего значение this в качестве аргумента.
  4. класс является собственностью [[Class]] внутренняя недвижимость O.
  5. Верните значение строки, которое является результатом объединения трех строк "[object ", class и "]".

Кроме того,

Значения внутреннего свойства [[Class]] определяются данной спецификации для каждого вида встроенного объекта. Значение внутреннего свойства объекта хоста [[Class]] может иметь любое значение, за исключением строк одного из "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp" и "String". Значение внутреннего свойства [[Class]] используется внутри, чтобы различать различные типы объектов. Обратите внимание, что эта спецификация не предоставляет никаких средств для доступа к этому значению программы, кроме Object.prototype.toString.

Так, Object.prototype.toString является единственной функцией, которая может получить доступ к [[Class]] собственности.

0

Если вы используете ECMA 6 (например, в NodeJS или Newer tech tech), вы можете использовать следующую функцию, чтобы получить «имя класса».

// primitives 
var array = [], obj = {}, str = "", date = new Date(), 
      num = 1, flt = 1.0, reg = new RegExp(/woohoo/g), 
      bool = true, myType = new MyType(), udf = undefined, nul = null; 

// names of various types (primitive and not) 
var names = cName(array) + ", " + cName(obj) + ", " + cName(str) + ", " + 
      cName(num) + ", " + cName(flt) + ", " + cName(reg) + ", " + 
      cName(bool) + ", " + cName(date) + ", " + cName(myType) + ", " + 
      cName(MyType) + ", " + cName(udf) + ", " + cName(nul); 

// custom type 
function MyType(){} 

console.log(names); 
// output: 
// Array, Object, String, Number, Number, RegExp, Boolean, Date, MyType, MyType, undefined, null 

// implementation 
function cName(obj){ 
    // default to non-null value. 
    var ret = ''; 

    if(typeof obj === 'undefined') { ret = 'undefined'; } 
    else if(obj === null)   { ret = String(obj); } 

    else if(typeof obj.constructor !== 'undefined' && obj.constructor !== null){ 
     ret = obj.constructor.name 

     if(ret == 'Function')  { ret = obj.name; } 
    } 

    return ret; 
} 

Хотя на самом деле нет «классов», это помогает, когда передается что-то вроде Array, vs Object, vs. Null, и вы хотите знать, какой он есть.

, вызывающий typeof на любом из них, будет возвращен 'object'. Тогда есть предостережение от необходимости иметь дело с вещами вроде null и undefined.

Вызов Object.prototype.toString() тяжелее, чем доступ к constructor.name, поскольку нет никакого преобразования из какого-то типа в строку, и я считаю, что constructor и constructor.name являются переменными-членами, а не getter, а это значит, никаких дополнительные функции не называется в ВОССТАНОВЛЕНИИ сказали имя ,

Смежные вопросы