2017-02-10 76 views
1

我想用d3.js製作一個可重複使用的圖表。代碼正在工作,但它們非常冗餘。如何簡化getter-setter函數

我試圖簡化代碼如下:

function myChart(){ 
    // default properties 
    var svgWidth = 1000, 
     svgHeight = 250; 

    function chart(selection){ 
     // do something with the previous properties .... 
    } 

    // define setter-getter functions 
    chart.svgWidth = function(_){ 
     if(!arguments.length) return svgWidth; 
     svgWidth = _; 
     return chart; 
    }; 
    chart.svgHeight = function(_){ 
     if(!arguments.length) return svgHeight; 
     svgHeight = _; 
     return chart; 
    }; 

    return chart; 
} 

正如你所看到的,所有的setter的getter功能非常相似。如果有很多屬性需要設置,比如說10,那麼setter-getter函數會堆疊得很長。

那麼有人能夠簡化它嗎?

回答

1

KISS:定義一個defaults對象,並遍歷它的鍵,以便創造新的屬性:

function myChart(){ 
    // default properties 
    var defaults = { 
     svgWidth: 1000, 
     svgHeight: 250 
    } 

    function chart(selection){ 
     // do something with the previous properties .... 
    } 

    Object.keys(defaults).forEach((key) => { 
     chart[key] = function(_) { 
     if(!arguments.length) return defaults[key]; 
     defaults[key] = _; 
     return chart; 
     }; 
    }); 

    return chart; 
} 
1

我相信這getSet.js功能正是你想要什麼:https://gist.github.com/gneatgeek/5892586

據它的創造者,它可以:

動態創建的getter/setter功能部件D3

由於鏈路只答案是不建議在S.O. (因爲鏈接可以改變或無法訪問)這裏是一個簡短的解釋。

這是說功能:

function getSet(option, component) { 
    return function(_) { 
     if (!arguments.length) { 
      return this[option]; 
     } 

     this[option] = _; 

     return component; 
    }; 
} 

讓我們來看看如何使用它。首先,你必須保存在一個對象的變量(這是函數的缺點之一,見上面的鏈接),像這樣:

var opts = { 
    width: 200, 
    height: 50, 
    color: '#000' 
}; 

之後,你使用這個for...in循環:

for (var key in opts) { 
    chart[key] = getSet(key, chart).bind(opts); 
} 

這樣,你就可以動態地生成你的setter/getters。

這裏是一個演示,使用干將:

function getSet(option, component) { 
 
    return function(_) { 
 
     if (!arguments.length) { 
 
      return this[option]; 
 
     } 
 

 
     this[option] = _; 
 

 
     return component; 
 
    }; 
 
} 
 

 
function chart() { 
 
    // do something 
 
}; 
 

 
var opts = { 
 
    width: 200, 
 
    height: 50, 
 
    color: '#000' 
 
}; 
 

 
for (var key in opts) { 
 
    chart[key] = getSet(key, chart).bind(opts); 
 
} 
 

 
//using the getters 
 
console.log(chart.height()) 
 
console.log(chart.width()) 
 
console.log(chart.color())
<script src="https://d3js.org/d3.v4.min.js"></script>

現在讓我們用setter方法設置一些值,之後,使用干將讓他們:

function getSet(option, component) { 
 
    return function(_) { 
 
     if (!arguments.length) { 
 
      return this[option]; 
 
     } 
 

 
     this[option] = _; 
 

 
     return component; 
 
    }; 
 
} 
 

 
function chart() { 
 
    // do something 
 
}; 
 

 
var opts = { 
 
    width: 200, 
 
    height: 50, 
 
    color: '#000' 
 
}; 
 

 
for (var key in opts) { 
 
    chart[key] = getSet(key, chart).bind(opts); 
 
} 
 

 
//using the setters... 
 
chart.width(42) 
 
chart.height(3.14) 
 
chart.color("foo") 
 

 
//...and then the getters 
 
console.log(chart.width()) 
 
console.log(chart.height()) 
 
console.log(chart.color())
<script src="https://d3js.org/d3.v4.min.js"></script>