是否可以更改JavaScript函数的`prototype`属性的名称?

时间:2017-01-23 08:10:14

标签: javascript

首先,我知道对于大多数实用的JS应用程序来说,这是非常不可取的。我正在构建一个DSL,而我正在测试JavaScript的限制(似乎正在通过proxiesreflection等新功能进行扩展。

假设我创建了一个新函数:var a = function(){}但是由于某些疯狂的原因,我确实想要使用prototype的{​​{1}}属性来存储一些任意数据(a)。

a.prototype = "blah"的{​​{3}}就是:

Function.prototype

因此很容易覆盖它,但是这会混淆功能的功能。呼叫configurable: false enumerable: false writable: true 不会表现得如此。理想情况下,有一种方法可以将其重命名为new a()或类似的东西,并让构造函数在创建新实例时引用该属性而不是__prototype

我怀疑这是不可能的,但我不确定ES6是否添加了任何可能使这个可行的代理(代理)?如果能够了解幕后内容的JavaScript专家可以帮助解决这个问题,那就太棒了。

P.S。我也想对prototype做同样的事情,但这可能是一个单独的问题,因为Function.arguments不是argumentsconfigurable。有什么意见吗?

1 个答案:

答案 0 :(得分:3)

  

是否可以更改JavaScript函数的prototype属性的名称?

如果您的意思是,是否可以更新new运算符的行为,以便在您使用a.prototype时使用其他属性来分配新对象的原型而不是new a不,不是。但您可以为a创建代理(例如pa),以便new pa为新对象设置不同的原型。

示例(我使用了APA,因为这是一个构造函数),请参阅注释:

// Our original constructor
function A(name) {
  this.name = name;
}
// A different property to use as a prototype
A.objectPrototype = {
  sayName() {
    console.log(`My name is ${this.name}`);
  }
};
// Make the prototype property something else entirely
A.prototype = 42;

// Construct our proxy
const PA = new Proxy(A, {
  construct(target, args, newTarget) {
    let o = Reflect.construct(target, args, newTarget);
    // Replace the object's prototype
    Object.setPrototypeOf(o, A.objectPrototype);
    return o;
  }
});

// Demonstrate that the new object gets its prototype from our custom prop
const o = new PA("foo");
o.sayName();

new A仍然不会这样做,并且PA无法正常继承,我会强烈建议不要这样做,但是,是的,Proxies是强大。 : - )

  

因此覆盖它很容易,但这会使功能的功能变得混乱。

仅当您将此功能与new运算符一起使用时。如果不这样做,您可以使用prototype属性执行任何操作,因为它不会用于任何操作。 (我不会,但你可以。)