簡體   English   中英

具有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

(僅有1個實例不是那么有用的例子)

以下方法不適用於應用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

我一直在玩基於http://tobyho.com/2010/11/22/javascript-constructors-and的 Fetch.prototype.constructor以及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;
};

現在你可以使用或不使用new **來調用Fetch ,它沒有什么區別:

var a = Fetch(host, username);
// same as
var a = new Fetch(host, username);

請注意,我改變this.usernamefetch.username在上面的例子。 每個函數都有自己的this值,默認情況下不會引用函數實例本身,所以this.username不起作用。

這將允許在創建后通過a.username = 'something else';更改主機或用戶名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 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM