为什么我不能使用左手赋值来修改函数结果的值?
Why can't I use left hand assignment to modify value of function result?
我正在尝试为函数 return 赋值。我知道这乍一看可能听起来很愚蠢,但我正在完成的是直接引用警报(在 C++ 中,这称为左值)并修改它。
function foo() {
return alert;
}
foo() = "zoo"
嗯,
var name = "alert";
var ref = (reference) => reference.split('.').reduce((o,i)=>o[i], window)
ref(name) = new Proxy(ref(name), {
apply: (target, thisArg, args) => {
console.log(thisArg)
console.log(args)
return "Alert called";
}
});
我现在可以,
var name = "alert";
window[name] = new Proxy(window[name], window), {
apply: (target, thisArg, args) => {
console.log(thisArg)
console.log(args)
return "Alert called";
}
});
但是像 "HTMLCollection.prototype"
这样的复杂对象会变得复杂
即使使用 eval,它也不起作用
var name = "alert";
eval(name) = new Proxy(eval(name), {
apply: (target, thisArg, args) => {
console.log(thisArg)
console.log(args)
return "Alert called";
}
});
您几乎是在要求 可变变量 ,即通过名称解析变量以进行赋值,而这仅在 Javascript 的能力非常有限的情况下才有可能。唯一可以使用它的时间是在分配对象 属性 时,其中 属性 名称是动态的:
foo[bar] = baz;
函数return值,不是引用也不是变量,所以分配给函数的return值是完全不可能的。
你有点在正确的轨道上:
(reference) => reference.split('.').reduce((o,i)=>o[i], window)
它将一个带点的名称解析为一个值,但同样,您不能分配到该解析值。当一个函数执行 return alert
时,它 returns 值 alert
引用 ,类似于 function () { ... }
。所以你要做的相当于:
function () { ... } = new Proxy(...)
那是行不通的。您不能 return
一个“名称”,您只能 return 名称所指的值。
您的函数必须 return 您正在查找的对象的 parent 对象,然后您可以分配给 属性它,例如:
ref(foo)[bar] = baz;
这相当于,例如:
window['alert'] = new Proxy(...)
即在window
所指的对象上设置一个属性alert
。这显然工作得很好。
由于上述 ref
函数的使用有些笨拙,您最好将其包装成这样的函数:
assign(foo, baz)
可能看起来像这样:
function assign(name, obj) {
const path = name.split('.');
const parent = path.slice(0, -1).reduce((o, i) => o[i], window);
parent[path[path.length - 1]] = obj;
}
const name = 'foo.bar.baz';
assign(name, new Proxy(ref(name), { ... }));
请注意,所讨论的对象必须在 window
上作为 属性 可用(或者您可以传递给 assign
的其他根对象);没有(理智的)方式以这种方式分配给 let
或 const
或任何局部函数变量。
例如这可能有效:
let foo = { bar: {} };
assign('bar', new Proxy(...), foo);
这并没有发生:
let foo = {};
assign('foo', new Proxy(...));
我正在尝试为函数 return 赋值。我知道这乍一看可能听起来很愚蠢,但我正在完成的是直接引用警报(在 C++ 中,这称为左值)并修改它。
function foo() {
return alert;
}
foo() = "zoo"
嗯,
var name = "alert";
var ref = (reference) => reference.split('.').reduce((o,i)=>o[i], window)
ref(name) = new Proxy(ref(name), {
apply: (target, thisArg, args) => {
console.log(thisArg)
console.log(args)
return "Alert called";
}
});
我现在可以,
var name = "alert";
window[name] = new Proxy(window[name], window), {
apply: (target, thisArg, args) => {
console.log(thisArg)
console.log(args)
return "Alert called";
}
});
但是像 "HTMLCollection.prototype"
即使使用 eval,它也不起作用
var name = "alert";
eval(name) = new Proxy(eval(name), {
apply: (target, thisArg, args) => {
console.log(thisArg)
console.log(args)
return "Alert called";
}
});
您几乎是在要求 可变变量 ,即通过名称解析变量以进行赋值,而这仅在 Javascript 的能力非常有限的情况下才有可能。唯一可以使用它的时间是在分配对象 属性 时,其中 属性 名称是动态的:
foo[bar] = baz;
函数return值,不是引用也不是变量,所以分配给函数的return值是完全不可能的。
你有点在正确的轨道上:
(reference) => reference.split('.').reduce((o,i)=>o[i], window)
它将一个带点的名称解析为一个值,但同样,您不能分配到该解析值。当一个函数执行 return alert
时,它 returns 值 alert
引用 ,类似于 function () { ... }
。所以你要做的相当于:
function () { ... } = new Proxy(...)
那是行不通的。您不能 return
一个“名称”,您只能 return 名称所指的值。
您的函数必须 return 您正在查找的对象的 parent 对象,然后您可以分配给 属性它,例如:
ref(foo)[bar] = baz;
这相当于,例如:
window['alert'] = new Proxy(...)
即在window
所指的对象上设置一个属性alert
。这显然工作得很好。
由于上述 ref
函数的使用有些笨拙,您最好将其包装成这样的函数:
assign(foo, baz)
可能看起来像这样:
function assign(name, obj) {
const path = name.split('.');
const parent = path.slice(0, -1).reduce((o, i) => o[i], window);
parent[path[path.length - 1]] = obj;
}
const name = 'foo.bar.baz';
assign(name, new Proxy(ref(name), { ... }));
请注意,所讨论的对象必须在 window
上作为 属性 可用(或者您可以传递给 assign
的其他根对象);没有(理智的)方式以这种方式分配给 let
或 const
或任何局部函数变量。
例如这可能有效:
let foo = { bar: {} };
assign('bar', new Proxy(...), foo);
这并没有发生:
let foo = {};
assign('foo', new Proxy(...));