eff*_*ffe 6 javascript constructor prototype node.js proxy-pattern
假设我有一个函数Foo,我希望从它构造的对象具有一个bar属性:
function Foo() {}
Foo.prototype.bar = 'baz'
console.log('new Foo().bar: ' + new Foo().bar)
Run Code Online (Sandbox Code Playgroud)
new Foo().bar: baz
Run Code Online (Sandbox Code Playgroud)
现在假设我以某种方式绑定 Foo.绑定函数仍可用于构造函数调用,并this忽略边界:
const Bound = Foo.bind(42)
console.log('new Bound().bar: ' + new Bound().bar)
Run Code Online (Sandbox Code Playgroud)
new Bound().bar: baz
Run Code Online (Sandbox Code Playgroud)
代理应该是一般的和透明的.然而...
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)
Run Code Online (Sandbox Code Playgroud)
new PFoo().bar: baz
new PBound().bar: undefined
Run Code Online (Sandbox Code Playgroud)
我希望第二个代理的行为完全如此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)Run Code Online (Sandbox Code Playgroud)
使用 时new F,new.target设置为F except F是绑定函数,在这种情况下new.target将成为原始函数。代理不会发生这种情况。
好吧,我想我明白了。这个评论是一个很好的起点。主要成分:
new.targetprototype属性注意:在构造函数调用中,新对象的原型设置为new.target.prototype。这是本规范的第 5 步。
起点:执行 时new F(),new.target最初设置为F(跟随链接)。然而,这可能会在施工过程中发生变化......
new Foo()这里没有什么奇怪的,new.target并且Foo新创建的对象原型是Foo.prototype。
new Bound()这很有趣。一开始,new.target是Bound. 然而,绑定函数[[Construct]]内部方法的第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)Run Code Online (Sandbox Code Playgroud)
个人观点:我理解,在构造绑定函数时,new.target需要进行更改,以便一切按预期工作。同样,我希望new.target在继续之前将代理对象的构造设置为代理函数。这是一个天真的想法,也许还有一些我没有考虑到的极端情况。
| 归档时间: |
|
| 查看次数: |
246 次 |
| 最近记录: |