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
(仅有1个实例不是那么有用的例子)
以下方法不起作用,因为应用new
返回一个对象(所以get 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
我一直在根据http://tobyho.com/2010/11/22/javascript-constructors-and/和What it the significance of the Javascript constructor property?使用Fetch.prototype.constructor
,但必须承认我已开始质疑它是否可行。
你有什么好主意吗?
答案 0 :(得分:1)
如何与
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
继承的新创建的对象。
答案 1 :(得分:0)
如果您想要某种继承,则可以要求构造函数创建并返回一个新函数,该函数将因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