最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

构造函数调用绑定函数的代理

IT培训 admin 6浏览 0评论

构造函数调用绑定函数的代理

假设我有一个函数Foo,我希望从它构造的对象具有bar属性:

function Foo() {}
Foo.prototype.bar = 'baz'
console.log('new Foo().bar: ' + new Foo().bar)

new Foo().bar: baz

现在假设我以某种方式bind Foo。绑定函数仍可用于构造函数调用,并且忽略绑定的this

const Bound = Foo.bind(42)
console.log('new Bound().bar: ' + new Bound().bar)

new Bound().bar: baz

Proxies应该是一般的和透明的。然而...

const PFoo = new Proxy(Foo, { })
console.log('new PFoo().bar: ' + new PFoo().bar)

const PBound = new Proxy(Bound, { })
console.log('new PBound().bar: ' + new PBound().bar)

new PFoo().bar: baz
new PBound().bar: undefined

我希望第二个代理行为与Bound完全一样,因为我使用的是空处理程序。换句话说,我希望最后的输出是baz

为什么不是这样?

(完整的片段如下)

function Foo() {}
Foo.prototype.bar = 'baz'
console.log('new Foo().bar: ' + new Foo().bar)

const Bound = Foo.bind(42)
console.log('new Bound().bar: ' + new Bound().bar)

const PFoo = new Proxy(Foo, { })
console.log('new PFoo().bar: ' + new PFoo().bar)

const PBound = new Proxy(Bound, { })
console.log('new PBound().bar: ' + new PBound().bar)
回答如下:

tl;dr

当使用new F时,new.target被设置为F,除非F是一个约束函数,在这种情况下new.target成为原始函数。代理不会发生这种情况。

Long answer

好的,我想我明白了。 This comment是一个很好的起点。主要成分:

  • new.target
  • [[Prototype]]内部插槽
  • 构造函数prototype属性

注意:在构造函数调用中,新对象的原型设置为new.target.prototype。这是this specification的第5步。

起点:当做new F()时,new.target is initially set to F(关注链接)。但是,这可能会在施工过程中发生变化......

new Foo()

这里没什么奇怪的,new.targetFoo,新创建的对象原型是Foo.prototype

new Bound()

这是有趣的。一开始,new.targetBound。但是,bound functions [[Construct]] internal method的第5步执行以下操作:如果将new.target设置为绑定函数,则将其更改为目标函数,即Foo。因此,再次使用Foo.prototype

new PFoo()

new.target总是PFoo,但它是Foo的代理,所以当PFoo.prototype被要求Foo.prototype再次给出。

new PBound()

new.target将被设置为PBound。这次,当调用绑定函数的[[Construct]]内部方法时,new.target不等于绑定函数,所以它不会改变,我们最终使用PBound.prototype,它转发到Bound.prototype。确实...

function Foo() { }
Foo.prototype.iAm = 'Foo'
const Bound = Foo.bind(42)
Bound.prototype = {iAm: 'Bound'}
const Proxied = new Proxy(Bound, { })
console.log(new Proxied().iAm)

构造函数调用绑定函数的代理

假设我有一个函数Foo,我希望从它构造的对象具有bar属性:

function Foo() {}
Foo.prototype.bar = 'baz'
console.log('new Foo().bar: ' + new Foo().bar)

new Foo().bar: baz

现在假设我以某种方式bind Foo。绑定函数仍可用于构造函数调用,并且忽略绑定的this

const Bound = Foo.bind(42)
console.log('new Bound().bar: ' + new Bound().bar)

new Bound().bar: baz

Proxies应该是一般的和透明的。然而...

const PFoo = new Proxy(Foo, { })
console.log('new PFoo().bar: ' + new PFoo().bar)

const PBound = new Proxy(Bound, { })
console.log('new PBound().bar: ' + new PBound().bar)

new PFoo().bar: baz
new PBound().bar: undefined

我希望第二个代理行为与Bound完全一样,因为我使用的是空处理程序。换句话说,我希望最后的输出是baz

为什么不是这样?

(完整的片段如下)

function Foo() {}
Foo.prototype.bar = 'baz'
console.log('new Foo().bar: ' + new Foo().bar)

const Bound = Foo.bind(42)
console.log('new Bound().bar: ' + new Bound().bar)

const PFoo = new Proxy(Foo, { })
console.log('new PFoo().bar: ' + new PFoo().bar)

const PBound = new Proxy(Bound, { })
console.log('new PBound().bar: ' + new PBound().bar)
回答如下:

tl;dr

当使用new F时,new.target被设置为F,除非F是一个约束函数,在这种情况下new.target成为原始函数。代理不会发生这种情况。

Long answer

好的,我想我明白了。 This comment是一个很好的起点。主要成分:

  • new.target
  • [[Prototype]]内部插槽
  • 构造函数prototype属性

注意:在构造函数调用中,新对象的原型设置为new.target.prototype。这是this specification的第5步。

起点:当做new F()时,new.target is initially set to F(关注链接)。但是,这可能会在施工过程中发生变化......

new Foo()

这里没什么奇怪的,new.targetFoo,新创建的对象原型是Foo.prototype

new Bound()

这是有趣的。一开始,new.targetBound。但是,bound functions [[Construct]] internal method的第5步执行以下操作:如果将new.target设置为绑定函数,则将其更改为目标函数,即Foo。因此,再次使用Foo.prototype

new PFoo()

new.target总是PFoo,但它是Foo的代理,所以当PFoo.prototype被要求Foo.prototype再次给出。

new PBound()

new.target将被设置为PBound。这次,当调用绑定函数的[[Construct]]内部方法时,new.target不等于绑定函数,所以它不会改变,我们最终使用PBound.prototype,它转发到Bound.prototype。确实...

function Foo() { }
Foo.prototype.iAm = 'Foo'
const Bound = Foo.bind(42)
Bound.prototype = {iAm: 'Bound'}
const Proxied = new Proxy(Bound, { })
console.log(new Proxied().iAm)

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论