【问题标题】:Is there away to change the internal [[Class]] property of a JavaScript Object?是否可以更改 JavaScript 对象的内部 [[Class]] 属性?
【发布时间】:2016-06-24 08:34:09
【问题描述】:

假设我已经创建了一个函数构造函数比如

    function Bar(){
    }
    var obj = new Bar();

有没有办法让Object.prototype.toString.call(obj) 返回类似[object Date] 的东西?

【问题讨论】:

  • 你在找这个吗? obj.constructor.name
  • 您是否尝试使用new Bar() 拨打new Date()
  • 你为什么要这样做?

标签: javascript


【解决方案1】:

ECMAScript5 没有提供任何修改 [[Class]] 的方法:

本规范未定义 ECMAScript 语言运算符或 允许程序修改对象的内置函数 [[Class]] 或 [[Prototype]] 内部属性或更改值 [[Extensible]] 从假到真。具体实施 修改 [[Class]]、[[Prototype]] 或 [[Extensible]] 的扩展必须 不违反上一段中定义的不变量。

ECMAScript6 移除了 [[Class]] 内部槽,但您可以使用 @@toStringTag Well-Known Symbol

  • 规范名称
    @@toStringTag
  • [[描述]]
    "Symbol.toStringTag"
  • 价值和目的
    用于创建对象的默认字符串描述的字符串值属性。通过内置方法Object.prototype.toString访问。
Bar.prototype[Symbol.toStringTag] = 'Date';
Object.prototype.toString.call(new Bar()); // "[object Date]"

【讨论】:

  • 我很确定当 ES6 成为一个选项时,class Bar extends Date 是任何 OP 尝试做的更好的方法:-)
  • @Bergi 没错,这可能就是 OP 想要的。仅仅改变{}.toString 的结果似乎并没有多大用处。
  • 很遗憾,在这种情况下,'Symbol.toStringTag' 和 'extends' 都不是选项。
  • 如果你不能使用 ES6 的特性,你将无法单独使用 ES5 来做到这一点,除非你的实现提供了一个扩展来做到这一点。
  • @Taurus 是的,但它仍然不是具有各自内部插槽的原生 Date 对象。这才是最重要的。
【解决方案2】:

如果您想要数据对象 - 创建它,那么您可以将其扩展为您自己的目的,但整体想法“有味道”。

            Bar.prototype.test = function () {
                return 'test';
            };
            function Bar(){
                var resultObject = new Date();
                Object.setPrototypeOf(resultObject, Object.assign(Object.create(Date.prototype), Bar.prototype));
                return resultObject;
            }
            var obj = new Bar();
            obj.test() === 'test';

            Object.prototype.toString.call(obj) === '[object Date]'

【讨论】:

    猜你喜欢
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 2021-08-22
    相关资源
    最近更新 更多