如何通过引用传递或模拟它

时间:2017-09-28 19:02:16

标签: javascript reference

我有两个IFFE:

var Helper = (function () {
    return {
        number: null,
        init: function (num) {
            number = num;
        }
    }
})();

var Helper2 = (function () {
    return {
        options: {
            number: [],
        },
        init: function(num){
            this.options.number = num;
        },
        getData: function () {
            return this.options.number;
        }
  }
})();


Helper2.init(Helper.number);
console.log(Helper2.getData());
Helper.init(5);
console.log(Helper2.getData());

我想要的是

Helper2.init(Helper.number);
console.log(Helper2.getData()); // null
Helper.init(5);
console.log(Helper2.getData()); // 5

我得到的是

Helper2.init(Helper.number);
console.log(Helper2.getData()); // null
Helper.init(5);
console.log(Helper2.getData()); // null

如果可以的话,可以通过引用传递哪些技术?

JSBIN:https://jsbin.com/gomakubeka/1/edit?js,console

编辑:在很多人开始采用不同的方式来获得Helper2 depend on Helper之前,Helper的实际实现是未知的,并且可能有100个方法来实现数字,因此Helper2需要内存地址。

编辑2:我认为我希望得到一些开端的路径是知道数组/对象确实通过引用传递,我如何以这样的方式包装这个原始类型,我可以通过引用

3 个答案:

答案 0 :(得分:1)

在JavaScript中通过引用传递只能发生在对象上。 您在JavaScript中唯一可以通过值传递的是原始数据类型。

如果你的第一个对象改变了"数字:null"要嵌套在选项对象中,就像它在第二个对象中那样,您可以将该对象的引用传递给另一个对象。诀窍是,如果您需要通过引用传递使用对象而不是原始数据类型。而是将原始数据类型嵌套在对象中并使用对象。

我改变了你的代码,但我认为这适用于你想要实现的目标。



var Helper = function (num) { 
    return {
        options: {
            number: num
        },
        update: function (options) {
            this.options = options;
        }
    }
};

var Helper2 = function (num) {
    return {
        options: {
            number: num,
        },
        update: function(options){
            this.options = options;
        },
        getData: function () {
            return this.options.number;
        }
  }
};

var tempHelp = new Helper();
var tempHelp2 = new Helper2();
tempHelp2.update(tempHelp.options);
tempHelp.options.number = 5;
console.log(tempHelp2.getData());




答案 1 :(得分:0)

首先,为什么它不起作用:

helper是一个返回对象的自激活函数。调用init时,它会为Helper对象设置一个数字。

然后在Helper2中将整数(Helper.number)传递给init,将对象设置为null。因此,您未将参考传递给Helper.number。只有设置的值。

您需要将整个对象传递给它并将其读出来。

一个例子:



var Helper = (function () {
    return {
        number: null,
        init: function (num) {
            this.number = num; //add this
        }
    }
})();

var Helper2 = (function () {
    return {
        options: {
            number: [],
        },
        init: function(obj){
            
            this.options = obj; //save a reference to the helper obj.
        },
        getData: function () {
            if (this.options.number)
            {
                return this.options.number;
            }
        }
  }
})();


Helper2.init(Helper);  //store the helper object
console.log(Helper2.getData());
Helper.init(5);
console.log(Helper2.getData());




答案 2 :(得分:0)

我认为你无法准确得到你想要的东西。但是,在你的一条评论中,你说:

  

不幸的是,接口不是javascript中的东西

这不完全正确。是的,没有强大的输入,如果您说某个功能需要特定类型的对象,您的代码用户可以完全忽略您的建议。

但是,您仍然可以创建一个您希望用户扩展的各种界面,以便与您自己的代码一起使用。例如,您可以告诉用户他们必须从extendValuable提供一种机制来访问value计算属性,该属性将是可以封装的Reference实例一个原语(解决了无法通过引用传递原语的问题)。

由于这使用了计算属性,因此也可以利用.value表示法。问题是.value将是Reference而不是实际值。

// Intermediary class that can be passed around and hold primitives
class Reference {
  constructor(val) {
    this.val = val;
  }
}

// Interface that dictates "value"
class Valuable {
  constructor() {
    this._value = new Reference();
  }
  get value() {
    return this._value;
  }
  set value(v) {
    this._value.val = v;
  }
}

// "Concrete" class that implements the Valuable interface
class ValuableHelper extends Valuable {
  constructor() {
    super();
  }
}

// Class that will deal with a ValuableHelper
class Helper {
  constructor(n) {
    this.options = {
      number: n
    }
  }
  getData() {
    return this.options.number;
  }
  setData(n) {
    this.options.number = n;
  }
}

// Create our instances
const vh = new ValuableHelper(),
  hh = new Helper(vh.value);

// Do our stuff
console.log(hh.getData().val);
vh.value = 5;
console.log(hh.getData().val);
hh.setData(vh.value);
vh.value = 5;