JavaScript中可调用对象的构造函数
如何在JavaScript中为可调用对象创建构造函数 我尝试过各种方法,比如下面。这里的示例只是实际对象的简化示例JavaScript中可调用对象的构造函数,javascript,constructor,callable,Javascript,Constructor,Callable,如何在JavaScript中为可调用对象创建构造函数 我尝试过各种方法,比如下面。这里的示例只是实际对象的简化示例 function CallablePoint(x, y) { function point() { // Complex calculations at this point return point } point.x = x point.y = y return point } 这在一开始是可行的,但它创
function CallablePoint(x, y) {
function point() {
// Complex calculations at this point
return point
}
point.x = x
point.y = y
return point
}
这在一开始是可行的,但它创建的对象不是
CallablePoint
的实例,因此它不会从CallablePoint.prototype
复制属性,并在CallablePoint
实例上显示false
。是否可以为可调用对象创建工作构造函数?如果希望CallablePoint()
构造函数返回CallablePoint类型的对象,则可以执行如下操作,其中CallablePoint对象包含一个点作为对象的属性,但仍然是CallablePoint对象:
function CallablePoint(x, y) {
this.point = {};
this.point.x = x
this.point.y = y
}
或者,如果您真正想要做的是创建一个返回CallablePoint对象的函数,那么您可以创建一个factor函数:
function CallablePoint(x, y) {
this.point = {};
this.point.x = x
this.point.y = y
}
function makeCallablePoint(x, y) {
return new CallablePoint(x,y);
}
如果使用
new
关键字,我不确定您是否知道您的对象将仅是CallablePoint
的实例。通过将它命名为“callable”,你让我觉得你不想使用new
。无论如何,有一种方法可以强制返回实例(谢谢提示,):
这将返回CallablePoint
的实例,无论它是如何调用的:
var obj1 = CallablePoint(1,2);
console.log(obj1 instanceof CallablePoint); // true
var obj2 = new CallablePoint(1,2);
console.log(obj2 instanceof CallablePoint); // true
我将编写我的答案,假设您在使用Python中可用的、通常被称为“可调用对象”的
\uuu call\uuu
功能。“可调用对象”在JavaScript上下文中听起来很陌生
我已经尝试了几个JavaScript引擎,但我尝试过的这些引擎都不允许调用对象,即使您从函数继承。例如:
function Callable(x) {
... "use strict";
... this.__proto__ = Function.prototype;
... this.toString = function() { return x; };
... }
undefined
> var c = new Callable(42);
var c = new Callable(42);
undefined
> c;
c;
{ toString: [function] }
> c(42);
c(42);
TypeError: Property 'c' of object #<Object> is not a function
at repl:1:1
at REPLServer.eval (repl.js:80:21)
at repl.js:190:20
at REPLServer.eval (repl.js:87:5)
at Interface.<anonymous> (repl.js:182:12)
at Interface.emit (events.js:67:17)
at Interface._onLine (readline.js:162:10)
at Interface._line (readline.js:426:8)
at Interface._ttyWrite (readline.js:603:14)
at ReadStream.<anonymous> (readline.js:82:12)
> c instanceof Function;
c instanceof Function;
true
c.apply(null, [43]);
TypeError: Function.prototype.apply was called on 43, which is a object and not a function
at Function.APPLY_PREPARE (native)
at repl:1:3
at REPLServer.eval (repl.js:80:21)
at repl.js:190:20
at REPLServer.eval (repl.js:87:5)
at Interface.<anonymous> (repl.js:182:12)
at Interface.emit (events.js:67:17)
at Interface._onLine (readline.js:162:10)
at Interface._line (readline.js:426:8)
at Interface._ttyWrite (readline.js:603:14)
>
函数可调用(x){
…“严格使用”;
…这._proto__=Function.prototype;
…this.toString=function(){return x;};
... }
未定义
>var c=新的可赎回资产(42);
var c=新的可赎回资产(42);
未定义
>c;
C
{toString:[函数]}
>c(42);
c(42);
TypeError:对象#的属性“c”不是函数
回复:1:1
在REPLServer.eval(repl.js:80:21)
回复js:190:20
在REPLServer.eval(repl.js:87:5)
在接口处。(回复js:182:12)
在Interface.emit(events.js:67:17)
在接口处在线(readline.js:162:10)
在接口处。\u行(readline.js:426:8)
在接口处写入(readline.js:603:14)
在ReadStream。(readline.js:82:12)
>c函数实例;
c函数实例;
真的
c、 应用(空[43]);
TypeError:Function.prototype.apply在43上被调用,43是一个对象而不是函数
在Function.APPLY\u PREPARE(本机)
回复:1:3
在REPLServer.eval(repl.js:80:21)
回复js:190:20
在REPLServer.eval(repl.js:87:5)
在接口处。(回复js:182:12)
在Interface.emit(events.js:67:17)
在接口处在线(readline.js:162:10)
在接口处。\u行(readline.js:426:8)
在接口处写入(readline.js:603:14)
>
这是V8(Node.js)。也就是说,您可能有一个从函数正式继承的对象,但它是不可调用的,并且我无法找到一种方法来说服运行时可以调用它。我在Mozilla的JavaScrip实现中也有类似的结果,所以我认为它一定是通用的
然而,JavaScript中自定义类型的作用非常小,所以我认为您不会错过太多。但是,正如您已经发现的,您可以在函数上创建属性,与在对象上创建属性的方式相同。所以,你可以用一种不太方便的方式来做这件事。事实证明这是可能的。当使用function
语法或function
构造函数创建函数时,它会获得内部[[Call]]
属性。它不是函数本身的属性,而是任何函数在构造时所获得的属性
虽然这仅仅意味着任何带有[[Call]]
的东西在构造时只能是函数
(当然,有一个例外–函数。prototype
本身不是从函数
继承的),但这并不意味着它以后不能成为其他东西,同时保留[/Call]]
属性。如果你的浏览器不是IE<11
允许改变这种魔力的东西是ES6中的\uuuu proto\uuuu
,它已经在许多浏览器中实现了\uuuu proto\uuuu
是一个包含当前原型的神奇属性。通过更改它,我可以使函数继承非函数的内容
function CallablePoint(x, y) {
function point() {
// Complex calculations at this point
return point
}
point.__proto__ = CallablePoint.prototype
point.x = x
point.y = y
return point
}
// CallablePoint should inherit from Function, just so you could use
// various function methods. This is not a requirement, but it's
// useful.
CallablePoint.prototype = Object.create(Function.prototype)
首先,CallablePoint
的构造函数生成了一个函数
(只有函数
可以以[[Call]]]
属性开头。接下来,我更改了它的原型,这样它就继承了CallablePoint
。在这一点上,我有一个函数不是从函数
继承的(有点混乱)
在我为CallablePoint
s定义了构造函数之后,我将CallablePoint
的原型设置为Function
,因此我有了继承自Function
的CallablePoint
function CallablePoint(x, y) {
function point() {
// Complex calculations at this point
return point
}
point.__proto__ = CallablePoint.prototype
point.x = x
point.y = y
return point
}
// CallablePoint should inherit from Function, just so you could use
// various function methods. This is not a requirement, but it's
// useful.
CallablePoint.prototype = Object.create(Function.prototype)
这样,CallablePoint
实例就有了原型链:CallablePoint->Function->Object
,同时仍然是可调用的。而且,因为对象是可调用的,所以根据规范,typeof
等于“Function”,我认为希望返回值是一个函数。然而,我不明白为什么。@Pointy-我同意OP到底想做什么还不清楚。我添加了另一个选项。你的point.x
不是你刚刚在中创建的。point
@Alnitak-拼写错误已修复。我真想知道为什么OP没有提供任何关于他们真正问什么或这些答案的反馈。您知道,function point(){return point}
只会返回函数本身吗?您打算用它做什么?它会允许您这样做