2017-02-28 83 views
2

我想了解爲什麼無法使用ES6創建「通用」正向代理。 「通用」我的意思是代理目標可能是任何類型的非原始值(包括函數)與相同的代理聲明(構造函數+處理程序)。ES6「通用」代理

殼體1:

var o = function myCtor() {} 

var p = new Proxy({}, { 
    construct: function(target, ...args) { 
     return Reflect.construct(o, ...args); 
    } 
}); 

console.log(new p); // TypeError: p2 is not a constructor 

殼體2:

var o = {} 

var p = new Proxy(function() {}, { 
    ownKeys: function(target) { 
     return Reflect.ownKeys(o); 
    } 
}); 

console.log(Object.keys(p)); // TypeError: 'ownKeys' on proxy: trap result did not include 'arguments' 

案例1個工作正常,當我使用功能(){}作爲代理目標(而不是{}),但是然後,殼體2不再工作了。

感謝您的幫助。

+0

函數具有以下屬性:'length','name''',arguments'''''''''''''''''''''''',看來一個封裝函數的代理需要將'arguments'包含在密鑰列表中。可能有其他的,但解決這個問題就像'return ['arguments',... Reflect.ownKeys(o)]'一樣簡單。 –

+0

@FelixKling騙子! :) –

+2

請參閱https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys#Invariants:*「結果列表必須包含所有不可配置的鍵「* –

回答

1

代理實例是一個目標,所以要比較(代理instanceof == target.constructor)將始終返回true.so對代理的操作必須與目標對象類型相同。

  1. 的情況下,1,代理返回對象的實例,是一個實例,但不是is-a的功能實例,這樣不能new被稱爲keyword.so你可以通過測試通過通過一個實例的函數。

    var o = function myCtor() {} 
    
        var p = new Proxy(function(){}, { 
         construct: function(target, ...args) { 
          return Reflect.construct(o, ...args); 
         } 
        }); 
    
        console.log(new p); 
    
  2. 在情況2中,因爲該函數具有一個未配置prototype屬性和代理必須是-一個功能instance.so由通過測試的handler.ownKeys()必須存在於prototype屬性名.and任何屬性定義爲Object.defineProperty(foo, 'foo', {configurable: false}) handler.ownkeys()必須存在it.eg:必須包含枚舉名稱包括foo

    var o = {prototype:{}} 
    
    var p = new Proxy(function() {}, { 
        ownKeys: function(target) { 
         return Reflect.ownKeys(o); 
        } 
    }); 
    
    console.log(Object.keys(p)); 
    

有很多代理例如here的,你可以品嚐這些例子yourself.after嚐到你也可以看到代理文檔中的深度。

+0

代理可以攔截任何對象,並且該函數也是一個實例函數對象。但它們有一些不同的用法。在代理創建的函數方式中必須調用作爲函數,以代理必須用作對象的對象方式調用。等等。 –

+0

功能是對象。你也可以[編輯]你的答案。 –