如何拦截JavaScript中的函数调用来抓取函数调用名
How to intercept a function call in JavaScript to grab the function call name
我不确定如何用标题来表达,所以我会更详细地介绍。
我想做的是有一些 object 叫做 car。
object car 包含两个 object 称为 tire 和 engine.
我想发生的事情是可以说,
car.start();
然后我希望汽车 object 能够同时检查 tire 和 engine 以查看它是否包含使用该名称的函数然后调用它。
综上所述
我希望能够调用 object 并让调用的 object 将其传递给实现该函数调用的任何人。
我查看了代理模式,但看不到如何动态地将函数调用从 object 传递到嵌套的 object。
如有任何想法,我们将不胜感激。谢谢!
示例代码
function engine() {
return {
start: () => console.log('start')
}
}
function tire() {
return {
getWidth: () => console.log('get width')
}
}
function car() {
this.tire = new tire();
this.engine = new engine();
// Pass on function calls made to car over to tire or engine depending on who implemented that function call.
}
// This should print start.
car.start();
**PS。 ** 我知道我可以对函数调用进行硬编码并让它通过,但我正在尝试动态执行此操作,因此我不必声明可以调用的每个函数。所以我想动态地做这个。
将它们转换为实际的 类 然后从它们的原型复制属性:
class Engine {
start() {
console.log("start");
}
}
class Tire {
getWidth() {
console.log("get width");
}
}
class Car {
constructor() {
this.tire = new Tire();
this.engine = new Engine();
}
}
for (const key of Object.getOwnPropertyNames(Engine.prototype)) {
if (key !== "constructor") {
Car.prototype[key] = function(...args) { return this.engine[key](...args); };
}
}
for (const key of Object.getOwnPropertyNames(Tire.prototype)) {
if (key !== "constructor") {
Car.prototype[key] = function(...args) { return this.tire[key](...args); };
}
}
const car = new Car();
car.start();
car.getWidth();
解决这个问题:“我查看了代理模式,但我不知道如何动态地将函数调用从对象传递到嵌套对象。”。 =12=]
您可能错过了对代理 class 的 'undefined' 方法的检查。在下面的代码中注意 target[prop] === undefined
- 此检查确定目标上是否存在 dynamic 方法。如果没有,则查看prop,从嵌入对象中调用方法。
如果您不想从嵌入对象中枚举方法,您可以内省它们以找到包含该方法的对象(此处未显示)。
这应该证明 Proxy 对象确实可以用来实现您的目标。
function Engine() {
this.start = () => {
console.log('started');
}
}
function Tire() {
this.getWidth = () => {
console.log('got width');
}
}
function Car() {
this.tire = new Tire();
this.engine = new Engine();
}
const carProxy = {
get: function(target, prop, receiver) {
if (target[prop] === undefined) {
if (prop === "getWidth") {
console.log('getting tire width');
return target.tire.getWidth;
} else if (prop === "start") {
console.log('starting');
return target.engine.start;
} else {
return () => {
console.log('Undefined function');
}
}
}
}
};
const target = new Car()
const car = new Proxy(target, carProxy);
car.start();
car.getWidth();
我不确定如何用标题来表达,所以我会更详细地介绍。
我想做的是有一些 object 叫做 car。
object car 包含两个 object 称为 tire 和 engine.
我想发生的事情是可以说,
car.start();
然后我希望汽车 object 能够同时检查 tire 和 engine 以查看它是否包含使用该名称的函数然后调用它。
综上所述
我希望能够调用 object 并让调用的 object 将其传递给实现该函数调用的任何人。
我查看了代理模式,但看不到如何动态地将函数调用从 object 传递到嵌套的 object。
如有任何想法,我们将不胜感激。谢谢!
示例代码
function engine() {
return {
start: () => console.log('start')
}
}
function tire() {
return {
getWidth: () => console.log('get width')
}
}
function car() {
this.tire = new tire();
this.engine = new engine();
// Pass on function calls made to car over to tire or engine depending on who implemented that function call.
}
// This should print start.
car.start();
**PS。 ** 我知道我可以对函数调用进行硬编码并让它通过,但我正在尝试动态执行此操作,因此我不必声明可以调用的每个函数。所以我想动态地做这个。
将它们转换为实际的 类 然后从它们的原型复制属性:
class Engine {
start() {
console.log("start");
}
}
class Tire {
getWidth() {
console.log("get width");
}
}
class Car {
constructor() {
this.tire = new Tire();
this.engine = new Engine();
}
}
for (const key of Object.getOwnPropertyNames(Engine.prototype)) {
if (key !== "constructor") {
Car.prototype[key] = function(...args) { return this.engine[key](...args); };
}
}
for (const key of Object.getOwnPropertyNames(Tire.prototype)) {
if (key !== "constructor") {
Car.prototype[key] = function(...args) { return this.tire[key](...args); };
}
}
const car = new Car();
car.start();
car.getWidth();
解决这个问题:“我查看了代理模式,但我不知道如何动态地将函数调用从对象传递到嵌套对象。”。 =12=]
您可能错过了对代理 class 的 'undefined' 方法的检查。在下面的代码中注意 target[prop] === undefined
- 此检查确定目标上是否存在 dynamic 方法。如果没有,则查看prop,从嵌入对象中调用方法。
如果您不想从嵌入对象中枚举方法,您可以内省它们以找到包含该方法的对象(此处未显示)。
这应该证明 Proxy 对象确实可以用来实现您的目标。
function Engine() {
this.start = () => {
console.log('started');
}
}
function Tire() {
this.getWidth = () => {
console.log('got width');
}
}
function Car() {
this.tire = new Tire();
this.engine = new Engine();
}
const carProxy = {
get: function(target, prop, receiver) {
if (target[prop] === undefined) {
if (prop === "getWidth") {
console.log('getting tire width');
return target.tire.getWidth;
} else if (prop === "start") {
console.log('starting');
return target.engine.start;
} else {
return () => {
console.log('Undefined function');
}
}
}
}
};
const target = new Car()
const car = new Proxy(target, carProxy);
car.start();
car.getWidth();