2015-04-17 52 views
4

是否可以定義將在實例級別在提案JavaScript的實例級裝飾

例如當前迭代中露出一個裝飾

function once(target, name, descriptor) { 
    let {get} = descriptor; 
    var called = false, result; 
    if (typeof get === "function") { 
    descriptor.get = function() { 
     console.log(called); 
     if (!called) { 
      result = get.apply(this, arguments); 
      called = true; 
     } 
     return result; 
    } 
    } 
    return descriptor; 
}; 

class X { 
    @once 
    get y() { 
     return Math.random(); 
    } 
} 

var x1 = new X; 
var x2 = new X; 


// Should be false 
console.log(x1.y !== x2.y) 

我想類似這樣的行爲

class X2 { 
    constructor() { 
    // Set descriptor manually for this instance 
    let descriptor = Object.getOwnPropertyDescriptor(X2.prototype, 'y'); 
    let d = Object.assign({}, descriptor); 
    once(X, "y", d); 
    Object.defineProperty(this, 'y', d); 
    } 
    get y() { 
    return Math.random(); 
    } 
} 

Babel REPL example

回答

2

裝飾s只在定義類時運行一次,但這並不意味着定義時邏輯不能設置函數來執行每個實例的東西。在這種情況下,您可以通過在prototye級別的getter中定義特定於實例的屬性來記憶該值;

function once(target, name, descriptor) { 
    let {get, writable, enumerable} = descriptor; 
    if (typeof get === "function") { 
    descriptor.get = function() { 
     const value = get.apply(this, arguments); 
     Object.defineProperty(this, name, { 
     value, 
     writable, 
     enumerable 
     }); 

     return value; 
    } 
    } 
    return descriptor; 
};