首页 > 其他分享 >练习2:Object.prototype.toString()

练习2:Object.prototype.toString()

时间:2022-08-19 15:58:15浏览次数:60  
标签:object Symbol Object toStringTag toString prototype

对于 Object.prototype.toString() 方法,会返回一个形如 "[object XXX]" 的字符串。

如果对象的 toString 方法没有被重写,就会返回如上面形式的字符串。

({}).toString();  // => "[object Object]"
Math.toString();  // => "[object Math]"

但是,大部分对象的 toString 方法被重写了,这时,需要用 call() 或者 Reflect.apply() 等方法来调用。

// 验证是否是数组
function isArray(obj) {
  return Object.prototype.toString.call(obj) === '[object Array]'
}
isArray([1,2,3]) // true
isArray('1')  // false

Object.prototype.toString 原理

对于 Object.prototype.toString.call(arg),若参数为 nullundefined,直接返回结果。

Object.prototype.toString.call(null);       // => "[object Null]"

Object.prototype.toString.call(undefined);  // => "[object Undefined]"

若参数不为 nullundefined ,则将参数转为对象,再做判断。

转为对象后,取得该对象的 [Symbol.toStringTag] 属性值(可能会遍历原型链)作为 tag ,如无该属性,或该属性不为基本类型,则按照下面规则 取 tag值,然后返回 [object,tag]类型的字符串。

注意: Symbol.toStringTag 的作用是可以指定 toString方法的tag值,具体在基础9:元编程里面有说明。

// Boolean 类型,tag 为 "Boolean"
Object.prototype.toString.call(true);            // => "[object Boolean]"

// Number 类型,tag 为 "Number"
Object.prototype.toString.call(1);               // => "[object Number]"

// String 类型,tag 为 "String"
Object.prototype.toString.call("");              // => "[object String]"

// Array 类型,tag 为 "String"
Object.prototype.toString.call([]);              // => "[object Array]"

// Arguments 类型,tag 为 "Arguments"
Object.prototype.toString.call((function() {
  return arguments;
})());                                           // => "[object Arguments]"

// Function 类型, tag 为 "Function"
Object.prototype.toString.call(function(){});    // => "[object Function]"

// Error 类型(包含子类型),tag 为 "Error"
Object.prototype.toString.call(new Error());     // => "[object Error]"

// RegExp 类型,tag 为 "RegExp"
Object.prototype.toString.call(/\d+/);           // => "[object RegExp]"

// Date 类型,tag 为 "Date"
Object.prototype.toString.call(new Date());      // => "[object Date]"

// 其他类型,tag 为 "Object"
Object.prototype.toString.call(new class {});    // => "[object Object]"

下面为部署了 Symbol.toStringTag 的例子。可以看出,属性值期望是一个字符串,否则会被忽略。

var o1 = { [Symbol.toStringTag]: "A" };
var o2 = { [Symbol.toStringTag]: null };

Object.prototype.toString.call(o1);      // => "[object A]"
Object.prototype.toString.call(o2);      // => "[object Object]"

Symbol.toStringTag 也可以部署在原型链上:

class A {}
A.prototype[Symbol.toStringTag] = "A";
a = new A()
Object.prototype.toString.call(a);   // => "[object A]"

部署了 Symbol.toStringTag 属性的内置对象

以下,是部署了此属性的内置对象。

1. 三个容器对象

JSON[Symbol.toStringTag];         // => "JSON"
Math[Symbol.toStringTag];         // => "Math"
Atomics[Symbol.toStringTag];      // => "Atomic"

JSON.toString();         // => "[object JSON]"
Math.toString();         // => "[object Math]"
Atomics.toString();      // => "[object Atomics]"

2. BigInt 和 Symbol

BigInt.prototype[Symbol.toStringTag];      // => "BigInt"
Symbol.prototype[Symbol.toStringTag];      // => "Symbol"

3. 四个集合(Collection)对象

Set.prototype[Symbol.toStringTag];         // => "Set"

Map.prototype[Symbol.toStringTag];         // => "Map"

WeakSet.prototype[Symbol.toStringTag];     // => "WeakSet"

WeakMap.prototype[Symbol.toStringTag];     // => "WeakMap"

4. ArrayBuffer 及其视图对象

ArrayBuffer.prototype[Symbol.toStringTag];       // => "ArrayBuffer"

SharedArrayBuffer.prototype[Symbol.toStringTag]; // => "SharedArrayBuffer"

DataView.prototype[Symbol.toStringTag];          // => "DataView"

5. 模块命名空间对象(Module Namespace Object)

import * as module from "./export.js";

module[Symbol.toStringTag];        // => "Moduel"

6. 其他

浏览器中:

Window.prototype[Symbol.toStringTag];       // => "Window"

HTMLElement.prototype[Symbol.toStringTag];  // => "HTMLElement"

Blob.prototype[Symbol.toStringTag];         // => "Blob"

node中:

global[Symbol.toStringTag];                 // => "global"

检测数组的优化

优化前:

// 验证是否是数组
function isArray(obj) {
  return Object.prototype.toString.call(obj) === '[object Array]'
}
isArray([1,2,3]) // true
isArray('1')  // false

优化后:

var toStr = Function.prototype.call.bind(Object.prototype.toString)
function isArray(obj) {
  return toStr(obj) === '[object Array]'
}
isArray([1,2,3]) // true
isArray('1')  // false

toStr([1, 2, 3]); 	// "[object Array]"
toStr("123"); 		// "[object String]"
toStr(123); 		// "[object Number]"
toStr(Object(123)); // "[object Number]"

其实,Function.prototype.call.bind(Object.prototype.toString) 就相当于,Object.prototype.toString.call() ,其中 toStr 的方法的第一个参数为传入的参数。

标签:object,Symbol,Object,toStringTag,toString,prototype
From: https://www.cnblogs.com/xuweikang/p/16602233.html

相关文章