具有object属性的函数的新实例
New instance of function with object property
函数是JavaScript中的第一类对象-但是如何与new
结合使用呢?
我知道如何创建一个既像函数又像对象的对象
fetch.proxy = '127.0.0.1'
fetch(url)
但是我想弄清楚如何将此与创建new
实例相结合,以便我可以按照以下方式做一些事情:
a = new Fetch(host, username)
a(path1) // fetches username@host/path1
a(path2) // fetches username@host/path2
(对于只有一个实例的例子不是很有用)
下面的方法不起作用,因为应用new
返回一个对象(所以得到TypeError: object is not a function
)。
var Fetch = function(a, b){
if ( (this instanceof arguments.callee) ){
//called as constructor
this.host = a
this.username = b;
this.host = 'localhost'
} else {
//called as function
console.log("Fetching "+this.username+'@'+this.host+a);
}
};
a = new Fetch('host', 'username')
a('/path1') // TypeError: object is not a function
a('/path2') // TypeError: object is not a function
我一直在玩Fetch.prototype.constructor
基于http://tobyho.com/2010/11/22/javascript-constructors-and/和它的Javascript构造函数属性的意义是什么?但我必须承认,我已经开始怀疑这是否可能。
如何与
new
结合使用?
那样做没有意义。new Foo
所做的就是创建一个继承Foo.prototype
的新对象。然而,目前不可能从Function.prototype
以外的原型继承一些函数,因此使用new Something
创建函数没有任何优势。
因为你没有在你的例子中使用prototype
,这并不重要。从Fetch
返回一个函数:
var Fetch = function(host, username){
function fetch(path) {
console.log("Fetching " + fetch.username + '@' + fetch.host + path);
}
fetch.username = username;
fetch.host = host;
return fetch;
};
现在你可以调用Fetch
,或者不调用new
**,这没有区别:
var a = Fetch(host, username);
// same as
var a = new Fetch(host, username);
注意,我在上面的例子中将this.username
更改为fetch.username
。每个函数都有自己的this
值,默认情况下不引用函数实例本身,所以this.username
不能工作。
允许在创建后通过a.username = 'something else';
等更改主机或用户名。如果你不想这样做,只需将fetch.username
更改为username
。
**:如果函数显式地返回一个对象,那么new
将返回该值,而不是继承Fetch.prototype
新创建的对象。
如果你想要某种继承,你可以要求你的构造函数创建并返回一个你将原型化的新函数,这要感谢setProtototypeOf
:
const Fetch = function (host, user)
{
var fetch // new instance of function, relay to model
fetch = function(path) {
// note we use the closure on instance 'fetch'
return Fetch.model.apply(fetch, arguments)
}
// 'setPrototypeOf' is not as borderline as '__proto__',
// but it has some caveats anyway. Check for example MDN
// about this.
Object.setPrototypeOf(fetch, Fetch.model)
if (host) fetch.host = host
if (user) fetch.username = user
return fetch
}
// we name 'model' here; it also works if we
// say 'prototype' instead.
// It would have been both more meaningful and more confusing at the
// same time, as the prototype would not get used the standard way.
Fetch.model = function (path)
{
console.log("Fetching " + this.username + '@' + this.host + path)
}
Fetch.model.host = 'localhost'
Fetch.model.username = 'peter'
var fetch = new Fetch // 'new' is not needed: can say '= Fetch()'
fetch.host = 'paradise'
fetch('/register')
See console output below
- ES6构造函数返回基类的实例
- Mongoose TypeError:实例化模式类型的对象时,对象不是函数
- 如何用javascript调用函数,然后在滚动事件中调用该函数的特定实例
- google在类内映射javascript directionsService.route请求:将类实例传递给回调函数
- 如何在事件函数中访问窗口实例
- Javascript:只有在代码中使用单个实例时,函数才能正常工作
- 调用函数和创建函数实例之间的Javascript差异
- setTimeout是否创建函数实例
- 在 JavaScript 中,当我们实例化派生对象时,原型的函数隐藏在哪里
- 挖空视图模型函数仅影响最后一个实例
- 在数组中的每个对象上调用实例函数
- 从 $scope 上的函数访问控制器内的实例函数
- 实例函数变量不会更改
- 如何在angularjs中获取实例函数
- Javascript——如何在不使用新运算符的情况下启用静态方法,同时防止使用实例函数
- 如何将实例函数传递给外部函数
- 如何比较两个不同的javascript对象相同的属性(不比较实例函数)
- 使用WinJS构造函数中的实例函数
- 使用tcomb,是我遗漏了什么,还是无法定义实例函数
- 使用jQuery时可以调用实例函数吗?