如何使这个数组在参数列表中工作,就像匿名属性一样

How to make this array work in the parameter list just like the anonymous attributes?

本文关键字:属性 一样 数组 何使这 参数 工作 列表      更新时间:2023-09-26

我想创建一个数组发送到这个条形图的构造函数。对我来说,参数看起来像是分配给canvasID、data等的匿名属性。是否有一种方法可以将这些作为数组发送到构造函数中,并让它们映射它们的特定字段?

我知道在构造函数中每个数据元素都是通过config访问的。canvasID和config。数据和配置。颜色等。

代码:

                var barvalues = ["myCanvas",data,"yellow",50,0,20,2]
                /*
                new BarChart({
                    canvasId: "myCanvas",
                    data: data,
                    color: "blue",
                    barWidth: 50,
                    minValue: 0,
                    maxValue: 20,
                    gridLineIncrement: 2
                });
                */
                new BarChart(barvalues);
Constructor:
function BarChart(config){
                // user defined properties
                this.canvas = document.getElementById(config.canvasId);
                this.data = config.data;
                this.color = config.color;
                this.barWidth = config.barWidth;
                this.gridLineIncrement = config.gridLineIncrement;
                /*
                 * adjust max value to highest possible value divisible
                 * by the grid line increment value and less than
                 * the requested max value
                 */
                this.maxValue = config.maxValue - Math.floor(config.maxValue % this.gridLineIncrement);
                this.minValue = config.minValue;
                // constants
                this.font = "12pt Calibri";
                this.axisColor = "#555";
                this.gridColor = "#aaa";
                this.padding = 10;
                // relationships
                this.context = this.canvas.getContext("2d");
                this.range = this.maxValue - this.minValue;
                this.numGridLines = this.numGridLines = Math.round(this.range / this.gridLineIncrement);
                this.longestValueWidth = this.getLongestValueWidth();
                this.x = this.padding + this.longestValueWidth;
                this.y = this.padding * 2;
                this.width = this.canvas.width - (this.longestValueWidth + this.padding * 2);
                this.height = this.canvas.height - (this.getLabelAreaHeight() + this.padding * 4);
                // draw bar chart
                this.drawGridlines();
                this.drawYAxis();
                this.drawXAxis();
                this.drawBars();
                this.drawYVAlues();
                this.drawXLabels();
            }

制作一个小包装器来调用它:

function myChart(id, data, color, bar, min, max, grid){
  return  new BarChart({
                    canvasId: id,
                    data: data,
                    color: color,
                    barWidth: bar,
                    minValue: min,
                    maxValue: max,
                    gridLineIncrement: grid
                });
}

usage: chart1=myChart("myCanvas",data,"yellow",50,0,20,2)

你可以先使用"new ",但是直接调用myChart()也不会有什么坏处。

这个函数将原始数组转换为构造函数所期望的格式:

var barvalues = ["myCanvas",data,"yellow",50,0,20,2];
function convertValues(vals) {
  var fields = ['canvasId','data','color','barWidth','minValue','maxValue','gridLineIncrement'];
  var ret = {};
  //TODO check equality of fields.length and vals.length
  //loop through defined fields
  for (var i = 0; i < fields.length; i++) {
    //set field in object ret
    ret[fields[i]] = vals[i];
  }
  return ret;
}
//call constructor with converted array
new BarChart(convertValues(barvalues));

BarChart存在后,您可以对其添加阴影;

BarChart = (function (original) { // shadowing IIFE
    function BarChart(p1) { // the new version
        var o = {},
            a = ["canvasId", "data", "color", "barWidth", "minValue", "maxValue", "gridLineIncrement"],
            i;
        if (p1 && p1.constructor === Array) { // if given an array
            for (i = 0; i < a.length; ++i) { // loop over it
                o[a[i]] = p1[i]; // and set up object
            }
            return original.call(this, o); // then invoke that
        } else { // otherwise
            return original.apply(this, arguments); // invoke as before
        }
    }
    BarChart.prototype = Object.create(original.prototype); // set up inheritance
    return BarChart; // pass out new fn
}(BarChart)); // keep reference to original version

那么这个新函数是做什么的呢?

  1. 这是旧功能的影子;这意味着新的引用都将指向这个新版本,而不是旧版本,但同时它在自己内部保持旧版本的活动
  2. 如果给它一个数组,它会假设你正在缩短预期的对象,因此在用它调用旧版本之前转换数组
  3. 如果没有给定数组,它的行为是透明的
  4. 调用旧版本时,使用callapply,使this从新版本延续;这意味着如果你使用new,那么它将应用于new
  5. 创建的实例
  6. 继承的设置使得原型中的任何内容都被继承,并且instanceof测试将给出与前一个函数相同的结果,这意味着新的函数是有效透明的

为什么使用IIFE?(function (/* params */) {/* body *}(/* args */));

    这意味着我们获得了一个新的闭包,允许我们保持对函数原始版本的引用,即使我们使用与它相同的变量名