请参阅对象中的常用值

时间:2015-04-09 20:20:45

标签: javascript

我有一个嵌套对象的对象,这些对象在这些嵌套对象属性中具有相同的变量。我试图通过将公共变量合并到该嵌套对象的属性中来使我的代码更加干燥,但我不确定这是正确的还是写它的最佳方式。有人有什么想法吗?

用法

我将各种函数称为jQuery每个/ onclick语句的回调。

$('#foo').each(foo.part1.begin);
$('.bar a').on('click', foo.part1.middle);

在我使用.each的情况下,我在分析工具中附加用于跟踪的数据属性,即当用户点击链接时,它会与这些属性一起发送。在我与某个事件绑定的情况下,我会为自定义事件发送一个特殊的分析标记。

我已更新begin对象中的第一个属性foo,以说明我正在做的事情。我有一个带有$this和一个对象的函数的实用程序库,该函数循环遍历该对象并设置锚标记上的所有atttributes等。

当前实施:

var foo = {
    part1: {
        begin: function () {
            var $this = jQuery(this),
                name = 'the beginning of time',
                color = 'blue',
                type = 'blackberries';

            utility.loopThroughAndSetAttributes($this, {
                name: name,
                color: color,
                type: type
            });
        },

        middle: function () {
            var name = 'the beginning of time',
                color = 'blue',
                type = 'strawberries';

            console.log(name + color + type);
        },

        end: function () {
            var name = 'the beginning of time',
                color = 'blue',
                type = 'raspberries';

            console.log(name + color + type);
        }
    },
    part2: {
        begin: function () {
            var name = 'the middle of the city',
                color = 'green',
                type = 'pluto';

            console.log(name + color + type);
        },

        middle: function () {
            var name = 'the middle of the city',
                color = 'green',
                type = 'mars';

            console.log(name + color + type);
        },

        end: function () {
            var name = 'the middle of the city',
                color = 'green',
                type = 'earth';

            console.log(name + color + type);
        },
    }
};

建议的解决方案:创建嵌套对象的新属性并引用该函数中的该属性。

var foo = {
    part1: {

        name: 'the beginning of time',
        color: 'blue',

        begin: function () {
            var name = foo.part1.name,
                color = foo.part1.color,
                type = 'blackberries';

            console.log(name + color + type);
        },

        middle: function () {
            var name = foo.part1.name,
                color = foo.part1.color,
                type = 'strawberries';

            console.log(name + color + type);
        },

        end: function () {
            var name = foo.part1.name,
                color = foo.part1.color,
                type = 'raspberries';

            console.log(name + color + type);
        }
    },
    part2: {

        name: 'the middle of the city',
        color: 'green',

        begin: function () {
            var name = foo.part1.name,
                color = foo.part1.color,
                type = 'pluto';

            console.log(name + color + type);
        },

        middle: function () {
            var name = foo.part1.name,
                color = foo.part1.color,
                type = 'mars';

            console.log(name + color + type);
        },

        end: function () {
            var name = foo.part1.name,
                color = foo.part1.color,
                type = 'earth';

            console.log(name + color + type);
        },
    }
};

3 个答案:

答案 0 :(得分:3)

您错过了this关键字:

part1: {
   name: 'the beginning of time',
   color: 'blue',
   begin: function () {
       var name = this.name,
       // ...         
   },

您还可以创建构造函数并避免重复代码片段。

var Foo = function(params) {
   this.name = params.name;
   this.color = params.color;
   // ...
}

Foo.prototype.begin = function() {
    // this.name...
};

var foo = {};
foo.part1 = new Foo({
    name: 'the beginning of time',
    color: 'red'
});

foo.part2 = new Foo({
   name: 'bar',
   color: 'baz'
});

编辑:我不确定您到底想要实现的目标,但有些要点可能相关。

jQuery on方法将传递函数的this值设置为单击的元素。要覆盖this值以引用该实例,您可以使用Function.prototype.bind或jQuery $.proxy方法:

$('.bar a').on('click', foo.part1.middle.bind(foo.part1));

Foo.prototype.middle = function(event) {
    var clickedElement  = event.currentTarget;
    // `this` here refers to the instance
};

另一个选择是使用jQuery .data()方法将实例附加到元素:

$('element').data('foo', foo.part1);

然后,为了获取数据,您可以使用data方法作为getter:

var foo = $('element').data('foo');

建议使用D3库进行分析!

答案 1 :(得分:1)

看起来大部分功能都存在于#34;部分"中,所以让我们创建一个封装该功能的函数对象:

function Part(name, color, types) {
    this.name = name;
    this.color = color;
    this.types = types;
    this.begin = function() {
        console.log(this.name + this.color + this.types.begin);  
    };
    this.middle = function() {
        console.log(this.name + this.color + this.types.middle);  
    };
    this.end = function() {
        console.log(this.name + this.color + this.types.end);  
    };
}

现在您可以构建foo,删除常用功能,但每个参数所需的部分定义除外:

var foo = {
    part1: new Part('the beginning of time', 'blue', 
        { begin: 'blackberries', middle: 'strawberries', end: 'raspberries' }),
    part2: new Part('the middle of the city', 'green', 
        { begin: 'pluto', middle: 'mars', end: 'earth'})
};

这里的用法是:

foo.part1.begin();
foo.part1.middle();
foo.part1.end();

foo.part2.begin();
foo.part2.middle();
foo.part2.end();

你可以更进一步,但我现在就把它留在这里。

答案 2 :(得分:1)

我喜欢将函数工厂用于这些“几乎相同”的函数。

function fooFunc(name, color, type) {
  return function() {
    console.log(name + color + type);
  };
}

var foo = {
  part1: {
    begin: fooFunc('the beginning of time', 'blue', 'blackberries'),
    middle: fooFunc('the beginning of time', 'blue', 'strawberries'), 
    end: fooFunc('the beginning of time', 'blue', 'raspberries')
  },
  part2: {
    begin: fooFunc('the middle of the city', 'green', 'pluto'),
    middle: fooFunc('the middle of the city', 'green', 'mars'), 
    end: fooFunc('the middle of the city', 'green', 'earth')
  }
};