链定制javascript函数

时间:2016-01-27 00:23:48

标签: javascript chaining

经过一段时间的搜索,我仍然找不到我想要的东西。

有大量的例子需要创建一个新实例,或者只有不返回任何内容的函数(这意味着问题可以通过返回this来解决)。 / p>

我希望以下示例很好地说明了我的观点:

// Say I have these functions
function aNumber(){
    var max = 100, min = 0;
    return (Math.floor(Math.random() * (max - min + 1)) + min);
}
function divideBy(_number, _divider){
    return (_number / _divider);
}
function multiplyBy(_number, _multi){
    return (_number * _multi);
}
function add(_number, _add){
    return (_number + _add);
}
function subtract(_number, _sub){
    return (_number - _sub);
}

// #########################################################

// I can do this with them
var test = aNumber();
test = divideBy(aNumber, 2);
test = add(aNumber, 5);
test = multiplyBy(aNumber, 3);
test = subtract(aNumber, 10);

// I would like to do this however:
var test = aNumber().divideBy(2).add(5).multiplyBy(3).subtract(10);

使最后一行有效的最有效方法是什么?

我是否误以为如果不创建新的实例,这是可能的?

6 个答案:

答案 0 :(得分:4)

是的,这需要更改Prototype的{​​{1}}。对象是实例。所以你需要创建一个对象来做这种事情。

Object

使用以下方法初始化对象:

function MyNum(value) {
  this._val = value;      // Having _variable is for denoting it is a private variable.
}

现在使用它,定义这些:

var myNum = new MyNum(5);

不要忘记在这些功能中使用MyNum.prototype.divideBy = function () {} MyNum.prototype.multiplyBy = function () {}

答案 1 :(得分:3)

尝试使用以下方法创建没有实例和原型关键字。

  

此处还添加了一个方法,您可以默认设置数字或随机数。如果没有指定数字。

  var Calculator = {

setNumber: function(givenNumber) {
  var max = 100,
      min = 0;

  this.number = (givenNumber) ? givenNumber : (Math.floor(Math.random() * (max - min + 1)) + min);
  return this;
},

divideBy: function(_divider) {
  this.number = (this.number / _divider);
  return this;
},

multiplyBy: function(_multi) {
  this.number = (this.number * _multi);
  return this;
},

add: function(_add) {
  this.number = (this.number + _add);
  return this;
},

subtract: function(_sub) {
  this.number = (this.number - _sub);
  return this;
},

result: function () {
  return this.number;
}
  }

  document.write('<pre>');
  document.writeln(Calculator.setNumber(2).divideBy(2).add(5).multiplyBy(3).subtract(10).result());
  document.writeln(Calculator.setNumber(4).divideBy(2).add(5).multiplyBy(3).subtract(10).number);
  document.writeln(Calculator.setNumber().divideBy(2).add(5).multiplyBy(3).subtract(10).result());
  document.write('</pre>');

答案 2 :(得分:0)

是的,您确实需要创建某个实例。这可以是一个简单的对象文字,函数构造函数等......

这个想法是你的所有方法都存储在某个对象上,对吧?访问这些方法的唯一方法是通过该对象访问它们。考虑到这一点,每个函数必须返回包含所有这些方法的对象。

一个简单的例子

var myMethods = {
  one: function() {
    console.log('one');
    // You can return 'this' or reference the object by name
    return this;
    // or 
    // return myMethods;
  },

  two: function() {
    console.log('two');
    return this;
  }
};

myMethods.one().two().one().two();
//=> 'one', 'two', 'one', 'two'

请注意何时直接引用该方法,如此

var someMethod = myMethods.one;
someMethod() //=> undefined

这是因为&#39;这个&#39;现在正在引用全局对象,这是另一天的另一个故事。请注意以这种方式引用方法。

答案 3 :(得分:0)

虽然通常不建议将函数添加到JavaScript原语的原型中,但您可以通过这样做来实现您所需的功能。

function aNumber(){
    var max = 100, min = 0;
    return (Math.floor(Math.random() * (max - min + 1)) + min);
}

function divideBy(_number, _divider){
    return (_number / _divider);
}
function multiplyBy(_number, _multi){
    return (_number * _multi);
}
function add(_number, _add){
    return (_number + _add);
}
function subtract(_number, _sub){
    return (_number - _sub);
}

Number.prototype.divideBy = function(_divider){
	return divideBy(this, _divider);
};

Number.prototype.multiplyBy = function(_multi){
	return multiplyBy(this, _multi);
};

Number.prototype.add = function(_add){
	return add(this, _add);
};

Number.prototype.subtract = function(_sub){
	return subtract(this, _sub);
};

var test = aNumber().divideBy(2).add(5).multiplyBy(3).subtract(10);

答案 4 :(得分:0)

就像Praveen和Venkatraman所说的那样,我发现以下关于链接的帖子,但是在访问任何改变方法之前都必须声明一个新的实例 method-chaining-in-javascriptbeautiful-javascript-easily-create-chainable-cascading-methods-for-expressiveness

或者您可以使用此实施https://jsfiddle.net/ayinloya/zkys5dk6/

function aNumber() {
  var max = 100;
  var min = 0;
  this._number = (Math.floor(Math.random() * (max - min + 1)) + min);
  console.log("a init", this._number)
}

aNumber.prototype.divideBy = function(_divider) {
  this._number = (this._number / _divider)
  return this;
}

aNumber.prototype.multiplyBy = function(_multi) {
  this._number = (this._number * _multi);
  return this;
}

aNumber.prototype.add = function(_add) {
  this._number = (this._number + _add);
  return this;
}

aNumber.prototype.subtract = function(_sub) {
  this._number = (this._number - _sub);
  return this;
}
aNumber.prototype.ans = function() {
  return this._number;
}

var a = new aNumber()

alert(a.add(2).subtract(1).ans())

答案 5 :(得分:0)

如果您不想引入库并且想要具有可重用的功能(并且不绑定到特定的类,例如计算器)。您可以做的是将输入包装到数组中,然后通过一系列映射函数将其传递。最后,只需选择第一个元素,便会得到结果。

function aNumber(){
  var max = 100, min = 0;
  return (Math.floor(Math.random() * (max - min + 1)) + min);
}
function divideBy(_number, _divider){
  return (_number / _divider);
}
function multiplyBy(_number, _multi){
  return (_number * _multi);
}
function add(_number, _add){
  return (_number + _add);
}
function subtract(_number, _sub){
  return (_number - _sub);
}

// #########################################################

var result = [aNumber()]
  .map(item => divideBy(item, 2))
  .map(item => add(item, 5))
  .map(item => multiplyBy(item, 3))
  .map(item => subtract(item, 10))
  [0];

console.log(result);

这可能不是最有效的方法,但通常速度是“足够好”。