当前位置: 首页 > 知识库问答 >
问题:

在javascript中是否有有效的方法使用'__proto__'或'set的原型()'?

汪德寿
2023-03-14

MDN 有一个关于修改代码原型的巨大可怕警告:

根据现代JavaScript引擎如何优化属性访问的性质,更改对象的[[原型]]在每个浏览器和JavaScript引擎中都是非常缓慢的操作。更改继承对性能的影响是微妙而广泛的,并且不仅限于在Object.set原型(…)语句中花费的时间,而是可以扩展到任何可以访问其[[原型]]已更改的任何对象的代码。如果您关心性能,您应该避免设置对象的[[原型]]。相反,使用Object.create()创建一个具有所需[[原型]]的新对象。

-MDN

我想知道是否有任何情况可以修改对象的原型,而不会引起级联优化效果,从而降低程序的性能。好像应该有。例如,如果您仅在创建对象后(以及其他任何对象使用对象之前)修改原型。但我想这非常依赖于引擎。

那么有谁知道是否有有效的方法来修改对象的原型呢?

编辑:这个问题的动机来自于创建实际继承Function的对象的愿望。我知道的唯一方法是修改函数的原型。请看下面Raynos的答案:javascript类继承自Function类

共有1个答案

郭琦
2023-03-14

这个问题的动机来自于创建实际继承自Function的对象的愿望。

看来你想做的是:

  • 创建新对象
  • 设置这些对象的原型(或__proto_属性)以引用Function。原型,以便它们从<code>Function继承属性。原型,例如:
    • <代码>。应用
    • <代码>。调用
    • <代码>。绑定

    只要在创建对象时能够正确地将其设置为所需的引用,就不需要更改任何对象的原型。

    您可以使用< code>Object.create()在创建时设置任何对象的原型。请注意,将任何对象的原型赋给< code>Function.prototype都不会导致该对象成为可调用的函数。但是,如果您仍然希望将原型指定为引用< code>Function.prototype或其他某个对象,您可以执行以下操作:

    var obj1 = Object.create(Function.prototype);
    

    这将:

    • 创建一个新对象,
    • 设置其原型(或__proto__属性)以引用Function.prototype或您作为参数传入的任何对象
      • 即,它将通过原型链将失败的属性查找委托给Function.prototype(这就是JavaScript原型和__proto__所指的:委托失败的属性查找的地方)

      这不需要您使用 Object.setPrototypeOf() 来更改现有对象的原型,因为它在创建对象的那一刻分配原型。有关更多示例和信息,请参阅 Object.create() 的 MDN 文档 - 这不像 setPrototypeOf() 那样带有可怕的警告。您可以使用 Object.create() 来设置任何新对象的原型。

      也就是说,如果你想要一个行为像函数的对象,你可以简单地创建一个函数。函数仍然是一个对象,但是有额外的特定于函数的属性和行为;你仍然可以通过给它分配属性来把它当成一个对象。如果你想创建一个也像对象一样的函数,或者一个也可以像函数一样做同样的事情的对象,那么一个函数已经这样做了。你可以这样做:

      var func = function() { return 'hello world'; }; // func is a function
      func.property1 = 'foo'; // func is also an object
      func.property2 = 'bar';
      

      解决您问题的最佳方法可能是利用这样一个事实,即函数实际上已经是具有附加功能能力的对象。

 类似资料:
  • 在这部分内容的第一章中,我们提到了设置原型的现代方法。 __proto__ 被认为是过时且不推荐使用的(deprecated),这里的不推荐使用是指 JavaScript 规范中规定,proto 必须仅在浏览器环境下才能得到支持。 现代的方法有: Object.create(proto, [descriptors]) —— 利用给定的 proto 作为 [[Prototype]] 和可选的属性描述

  • 问题内容: 我正在将一些Java代码转换为C#,并发现了一些标记为“ break”的语句(例如) C#是否存在等效项(当前读数不建议使用),如果没有,则除了(例如)具有布尔标志以指示是否在每个循环结束时中断以外,没有任何转换(例如) 我对C#为什么没有这个很感兴趣,因为它似乎并不十分邪恶。 问题答案: 您可以使用直接跳转到标签。 在类似C的语言中,通常可以更轻松地打破嵌套循环,而不是跟踪布尔变量并

  • 问题内容: Java具有格式字符串的概念,与其他语言的格式字符串非常相似。它用于诸如输出转换之类的JDK方法中。 我想知道在Java中是否有类似于C的输入转换方法? 问题答案: 看一下该站点,它解释了两种使用java中的控制台读取的方法,使用或使用System.in中的经典方法。 以下代码摘自引用的网站: - 问候。

  • 请注意,我使用以下代码得到了相同的结果: 所以问题是,fooObservable直到订阅了PublishSubject之后才订阅PublishSubject, 是否有一种方法可以在第一次订阅FooObservable之后立即运行代码? 如果请求与已经订阅的请求匹配,那么observable应该在订阅时立即提供最新的匹配值。 当没有订阅者时,我需要取消我包装的服务的订阅。

  • 问题内容: 来自C和C ++背景,我发现明智地使用typedef会带来极大帮助。您是否知道在Java中实现类似功能的方法,无论是Java机制,模式还是您使用的其他有效方法? 问题答案: Java具有原始类型,对象和数组,仅此而已。没有typedef。

  • 问题内容: 我的问题是,此代码是否能证明/否定/否定这样的假设,即在拆解方法中使成员变量无效是有用的?我用JUnit4.8.1测试了它。 JUnit为4个测试中的每一个创建测试类的新实例。每个实例都包含一个对象obj。该obj也作为静态WeakHashMap的键插入。如果并且当JUnit释放其对测试实例的引用时,关联的obj值将被弱引用,因此有资格使用gc。该测试尝试强制使用gc。WeakHash