繁体   English   中英

仅通过传递属性来修改JS对象的属性?

[英]Modifying a JS object's properties by passing the properties only?

我正在构建一个接受两个参数的插件-高度和宽度。 此插件的使用者可能具有矩形对象,正方形对象或多边形对象等。其宽度/高度的名称可能不同:

var square = { 
   width: 200,
   height: 200
}

var rectangle = { 
   Width: 200,
   tall: 200
}

var polygon = { 
   w: 200,
   h: 200
}

我正在尝试构建一个接受宽度/高度参数并对其进行修改的函数,以便更新父对象。 像这样:

var alterStuff = function (width, height){
    width = 200;
    height = 200;
};

var obj = {width: "28", height: "34"};

alterStuff(obj.width, obj.height);

alert(obj.width);

目标是使用者可以传入两种原始类型,而alterStuff函数将在对象上更新它们。

可以使用什么模式来实现这一目标? 现在, obj属性尚未更新-我在警报中看到“ 28”,但我希望在不传递对象的情况下看到“ 200”,因为我不知道该对象的属性名称是什么在所有情况下。

简短的答案:你不能!

当您将某些东西传递给函数时,就传递了它的价值。 如果它是原始值,例如5,则将5传递给该函数。 如果是对象,则实际上是对对象的引用,您可以传递该引用。 这意味着,当您传递obj.width其值例如为45px ,仅将该字符串传递给函数,并且绝对没有与obj连接。

更新对象属性的唯一方法是传递对象本身和属性名称:

function change(obj, key, val) {
  obj[key] = val;
}

var obj = { width : 5 };
change(obj, 'width', 10);

在您的特定情况下,您可以尽最大努力从对象的键中“猜测”属性名称。 在以下示例中,widthKey和heightKey是可选的,因此,如果库函数的用户具有行为良好的对象,则无需传递它们。 否则,他应该通过。

function updateSize(object, width, height, opt_widthKey, opt_heightKey) {
  // potential width properties:
  var widths = ['width', 'Width', 'w'];
  // potential height properties:
  var heights = ['height', 'Height', 'h'];

  var widthKey = opt_widthKey || getPropertyName(object, widths);
  if (!widthKey) throw new Error('Can not guess width property');

  var heightKey = opt_heightKey || getPropertyName(object, heights);
  if (!heightKey) throw new Error('Can not guess height property');

  object[widthKey] = width;
  object[heightKey] = height;
}

function getPropertyName(object, properties) {
  for (var i=0; i<properties.length; i++) {
    if (object.hasOwnProperty(properties[i]))
      return properties[i];
  }
}

// usage:

var obj = { width : 5, Height : 10 };
var notGood = { tall : 20, wide : 40 };

updateSize(obj, 100, 200);
updateSize(notGood, 100, 200, 'wide', 'tall');

您必须传递对象本身而不是其属性:

var alterStuff = function (obj){
    obj.width = 200;
    obj.height = 200;
};

var obj = {width: "28", height: "34"};

alterStuff(obj);

您可能需要阅读这篇文章

我不认为没有传递对象的好方法。 也许您可以返回一个2成员数组,调用者将负责将其加载回正确的位置:

var alterStuff = function(width, height) {
    return [+width * 2, +height * 2];    // for example
}

var obj =  {width: "28", height: "34"};

var newValues = alterStuff(obj.width, obj.height);
obj.width = newValues[0];
obj.height = newValues[1];

或者,您可以让调用方提供一个回调函数:

var alterStuff = function(width, height, callback) {
    // note: you may want to include some checks for undefined and that callback is a function
    callback(+width *2, +height * 2);
}

alterStuff(obj.width, obj.height, function(width, height) {
   obj.width = width;
   obj.height = height;
});

所以现在如果我有:

var rectangle = { 
   Width: 200,
   tall: 200
}

我可以这样称呼alterStuff

alterStuff(rectangle.Width, rectangle.tall, function(Width, tall) {
    rectangle.Width = Width;
    rectangle.tall = tall;
});

我为“宽度”和“高度”之类的属性选择的名称是调用者的选择。

或Tibos的答案是另一种选择,您可以在调用函数时传递密钥。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM