【问题标题】:Method is returning __proto__ in a modern browser? How to remove it?方法在现代浏览器中返回 __proto__?如何删除它?
【发布时间】:2019-05-27 02:19:36
【问题描述】:

这是一个纯Javascript的方法,返回一个简单的对象,

MyClass.retObj = function() {
  return {
    x: {a:1, b:this.b}
    ,y: this.y
  };
}

document.addEventListener('DOMContentLoaded', function(){ // ONLOAD:

  console.log( MyClass.retObj().x ) // good...
  console.log( MyClass.retObj() ) // BAD! show __proto__

}, false);  // \ONLOAD

为什么它在现代浏览器中返回__proto__如何在当今(2019 年)禁用这种丑陋的行为

MDN 说this feature "is no longer recommended"


PS:是not a duplicate of this question,因为这里是最简单直接的上下文,我需要一个简单的答案……而且是关于“现在”的。

【问题讨论】:

  • "curisilly" -> 好奇地?
  • 尽管如此,其余部分仍然没有多大意义。例如,“谁” 是什么意思?无需对投票发表评论:meta.stackoverflow.com/questions/357436/…
  • 这是因为所有的对象都有这个,总是。枚举属性时,您必须忽略垃圾属性。奇怪的 JS 东西。
  • 嗨@MarkMeyer,我用console.log() 编辑过,这就是我看到的。
  • @trognanders,谢谢...我在其他网站上看到了很少的 cmets(也许未来的浏览器版本会起飞)...但是没有问题吗?返回一个不是我定义的对象?强迫我的方法的用户摄入这么多垃圾?没有干净的 JSON?

标签: javascript prototype


【解决方案1】:

为什么[显示]__proto__

如果你想了解一个对象为什么以某种方式表现,原型链是非常重要的。是否显示为__proto__[[Prototype]]<prototype> 并不真正相关,是吗? ...

如何禁用这个丑陋的[对象可视化]?

如果这真的让您感到困扰,请使用其他浏览器。

奇怪的是 MyClass.retObj().x [似乎没有]__proto__

确实很有趣,可能控制台认为Prototype与观众无关,因此将其隐藏起来,但这两种情况都不是。但另一方面,这种可视化事物的动态行为有点误导,因为人们可能认为__proto__ 不存在于一个对象上,而存在于另一个对象上(它确实存在于两个对象上)。

MDN 说 [__proto__] “不再推荐”。 如何禁用这个丑陋的[__proto__属性]?

而且我不建议使用var,向后兼容是丑陋的,但却是强制性的。删除所有这些糟糕的设计决策会“破坏互联网”,因此保留它们肯定更好。

但是没有问题吗?

是的,__proto__ 对性能优化有问题,但是……它是 JavaScript,浏览器知道如何优化不确定性。

返回一个不是我定义的对象?

您还没有定义{}.toString()。如果您确实需要一个完全空白的对象,请使用

 Object.create(null)

强迫使用我的方法的用户摄入这么多垃圾?

__proto__ 不可枚举和继承,如果您不主动搜索,您不会通过编程意外找到它。

没有干净的 JSON?

 JSON.stringify({}) // {} ?!?

【讨论】:

  • 嗨,感谢所有解释(!)。只有一点 cmets:JSON.stringify() 我只用于我的 Javascript 代码的“外部世界”,就像在 HTTP 输出中一样,对于内部,我将丢失所有预解析的对象。关于Object.create(null),我从没用过……你能举一个不返回__proto__的例子吗?
  • @PeterKrauss Object.create(null) 只是将其内部 [[prototype]] 设置为 null。没有没有内部原型链接的对象。所有开发工具都向您展示用于调试的原型链不是问题。他们使用名称__proto__ 来标记它是令人困惑的,但不是问题。您没有在任何地方使用已弃用的__proto__ setter/getter“功能”。
  • 修改原型至少在 V8 中是优化毒药。
【解决方案2】:

我的回答可能听起来比事实更多,但我会试一试。引用的文章here 指出不推荐使用 __proto__ ——即避免自己直接将其放入代码中。

也就是说,不要这样做:

function Person() {
   this.Name = "";
}
Person.prototype.setName = function(name) {
   this.Name = name;
};
Person.prototype.getName = function() {
   return this.Name;
};

var john = new Person();
console.log( john.__proto__ );

因为已建议从浏览器中删除 proto,所以您不应直接在代码中使用它,因为未来的浏览器更新可能会完全删除它,然后您的代码将因这些更新而中断。

【讨论】:

    猜你喜欢
    • 2011-12-14
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多