Javascript - 使对象中的函数成为全局函数
Javascript - make function in object global
假设我有一个对象 obj
,其函数 f1
接受两个参数 a
和 b
。函数调用如下:
obj.f1(a,b);
现在我想在不调用 obj
的情况下使 f1
可访问,如下所示:
f1(a,b);
这可能吗?如果可以,我该如何实现?
编辑:如果是,有没有办法在不知道具体函数的情况下,使对象中的所有函数成为全局函数?
虽然这样做不是最好的主意,但您可以向全局 window
对象添加属性(如果 运行 在浏览器中使用 node,那么您可以参考 global
- 这里我使用 globalThis
所以这在两种环境下都有效),然后调用它们而不需要前缀 obj
。向 window
添加属性(即:globalThis)通常不是一个好主意,因为您最终可能会覆盖 window 上预先存在的属性。话虽如此,您可以按照以下方式进行操作:
const obj = {x: 1, y: function() {
console.log("hello");
}}
Object.entries(obj).forEach(([key, val]) => {
if(typeof val === "function")
globalThis[key] = val;
});
y();
请记住,如果您的对象的方法引用 this
,那么在调用您的方法时,this
将绑定到全局对象(即:window
),或者,如果你在严格模式下 运行 ,那么它将是 undefined
.
以下是上述一些注意事项的一些示例:
修改预先存在的属性:window 对象有一些预先存在的属性。其中一个 属性 是 name
属性,JS 将其强制为字符串。这意味着如果你的对象中有一个名为 name
的方法,一旦它被添加到 window
:
中,它将被转换为一个字符串
const obj = {x: 1, name: function() {
console.log("hello");
}}
Object.entries(obj).forEach(([key, val]) => {
if(typeof val === "function")
globalThis[key] = val;
});
console.log(typeof name); // string
name(); // Crash: "Uncaught TypeError: name is not a function"
在你的方法中丢失 this
:如果你的方法引用了 this
,那么你可以预期你的方法不再有效,因为它失去其 this
绑定:
const obj = {x: 1, y: function() {
console.log(this.x); // undefined (as `this` now refers to window)
}, z: function() {
'use strict';
console.log(this.x); // Crashes, because this is undefined when in strict-mode
}}
Object.entries(obj).forEach(([key, val]) => {
if(typeof val === "function")
globalThis[key] = val;
});
y(); // undefined
z(); // "Uncaught TypeError: Cannot read property 'x' of undefined"
为了帮助纠正 this
的上述问题,您可以考虑在将方法分配给 window 时绑定您的方法,以便预定义其上下文:
const obj = {x: 1, y: function() {
console.log(this.x); // this is bound to `obj` (via the .bind() method)
}, z: function() {
'use strict';
console.log(this.x); // this is bound to `obj` (via the .bind() method)
}}
Object.entries(obj).forEach(([key, val]) => {
if(typeof val === "function")
globalThis[key] = val.bind(obj);
});
y(); // 1
z(); // 1
您可以 destructure 像这样的对象的属性:
const someObject = {
f1: (a, b) => a + b,
f2: (a, b) => a * b,
defaultParams: [1, 1],
}
const {f1, f2, defaultParams} = someObject;
console.log(f1(defaultParams[0], 15) * f2(...defaultParams));
或者从对象中检索条目并将它们分配给全局范围(此处window
,即not advisable)。
const someObject = {
f1: (a, b) => a + b,
f2: (a, b) => a * b,
defaultParams: [1, 1],
}
Object.entries(someObject).forEach( ([key, entry]) => window[key] = entry );
console.log(f1(defaultParams[0], 15) * f2(...defaultParams));
您可以创建匿名范围。在下一个代码片段中,this
应该绑定到对象,因此使用 [function].apply
包装方法。此外,还使用了另一种解构方法。
// this syntax creates an anonymous scope
// so f1/f2/defaultParams are *not* window properties
(() => {
const someObject = {
b: 42,
f1(a) { return a + this.b; },
f2(a) { return a * this.b; },
defaultParams: [1, 1],
}
// another way of destructuring ...
const [f1, f2, defaultParams] = [
(...params) => someObject.f1.apply(someObject, params),
(...params) => someObject.f2.apply(someObject, params),
someObject.defaultParams,
];
// or use the shorter *bind* syntax, e.g.
const f3 = someObject.f1.bind(someObject);
console.log(f1(defaultParams[0]), f2(2));
console.log(f3(defaultParams[0]));
// still NOT advisable, but coming to think of it ...
window.f2FromWithin = someObject.f2.bind(someObject);
})();
console.log(f2FromWithin(42));
这是使用两个 'deprecated' 命令:with
和 eval
:)
// assuming this is in the node.js
with (obj) {
for (i in obj) {
eval('global.'+i+'='+i);
}
}
假设我有一个对象 obj
,其函数 f1
接受两个参数 a
和 b
。函数调用如下:
obj.f1(a,b);
现在我想在不调用 obj
的情况下使 f1
可访问,如下所示:
f1(a,b);
这可能吗?如果可以,我该如何实现?
编辑:如果是,有没有办法在不知道具体函数的情况下,使对象中的所有函数成为全局函数?
虽然这样做不是最好的主意,但您可以向全局 window
对象添加属性(如果 运行 在浏览器中使用 node,那么您可以参考 global
- 这里我使用 globalThis
所以这在两种环境下都有效),然后调用它们而不需要前缀 obj
。向 window
添加属性(即:globalThis)通常不是一个好主意,因为您最终可能会覆盖 window 上预先存在的属性。话虽如此,您可以按照以下方式进行操作:
const obj = {x: 1, y: function() {
console.log("hello");
}}
Object.entries(obj).forEach(([key, val]) => {
if(typeof val === "function")
globalThis[key] = val;
});
y();
请记住,如果您的对象的方法引用 this
,那么在调用您的方法时,this
将绑定到全局对象(即:window
),或者,如果你在严格模式下 运行 ,那么它将是 undefined
.
以下是上述一些注意事项的一些示例:
修改预先存在的属性:window 对象有一些预先存在的属性。其中一个 属性 是 name
属性,JS 将其强制为字符串。这意味着如果你的对象中有一个名为 name
的方法,一旦它被添加到 window
:
const obj = {x: 1, name: function() {
console.log("hello");
}}
Object.entries(obj).forEach(([key, val]) => {
if(typeof val === "function")
globalThis[key] = val;
});
console.log(typeof name); // string
name(); // Crash: "Uncaught TypeError: name is not a function"
在你的方法中丢失 this
:如果你的方法引用了 this
,那么你可以预期你的方法不再有效,因为它失去其 this
绑定:
const obj = {x: 1, y: function() {
console.log(this.x); // undefined (as `this` now refers to window)
}, z: function() {
'use strict';
console.log(this.x); // Crashes, because this is undefined when in strict-mode
}}
Object.entries(obj).forEach(([key, val]) => {
if(typeof val === "function")
globalThis[key] = val;
});
y(); // undefined
z(); // "Uncaught TypeError: Cannot read property 'x' of undefined"
为了帮助纠正 this
的上述问题,您可以考虑在将方法分配给 window 时绑定您的方法,以便预定义其上下文:
const obj = {x: 1, y: function() {
console.log(this.x); // this is bound to `obj` (via the .bind() method)
}, z: function() {
'use strict';
console.log(this.x); // this is bound to `obj` (via the .bind() method)
}}
Object.entries(obj).forEach(([key, val]) => {
if(typeof val === "function")
globalThis[key] = val.bind(obj);
});
y(); // 1
z(); // 1
您可以 destructure 像这样的对象的属性:
const someObject = {
f1: (a, b) => a + b,
f2: (a, b) => a * b,
defaultParams: [1, 1],
}
const {f1, f2, defaultParams} = someObject;
console.log(f1(defaultParams[0], 15) * f2(...defaultParams));
或者从对象中检索条目并将它们分配给全局范围(此处window
,即not advisable)。
const someObject = {
f1: (a, b) => a + b,
f2: (a, b) => a * b,
defaultParams: [1, 1],
}
Object.entries(someObject).forEach( ([key, entry]) => window[key] = entry );
console.log(f1(defaultParams[0], 15) * f2(...defaultParams));
您可以创建匿名范围。在下一个代码片段中,this
应该绑定到对象,因此使用 [function].apply
包装方法。此外,还使用了另一种解构方法。
// this syntax creates an anonymous scope
// so f1/f2/defaultParams are *not* window properties
(() => {
const someObject = {
b: 42,
f1(a) { return a + this.b; },
f2(a) { return a * this.b; },
defaultParams: [1, 1],
}
// another way of destructuring ...
const [f1, f2, defaultParams] = [
(...params) => someObject.f1.apply(someObject, params),
(...params) => someObject.f2.apply(someObject, params),
someObject.defaultParams,
];
// or use the shorter *bind* syntax, e.g.
const f3 = someObject.f1.bind(someObject);
console.log(f1(defaultParams[0]), f2(2));
console.log(f3(defaultParams[0]));
// still NOT advisable, but coming to think of it ...
window.f2FromWithin = someObject.f2.bind(someObject);
})();
console.log(f2FromWithin(42));
这是使用两个 'deprecated' 命令:with
和 eval
:)
// assuming this is in the node.js
with (obj) {
for (i in obj) {
eval('global.'+i+'='+i);
}
}