2015-04-17 53 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; 
};