纯函数与面向对象的Javascript

时间:2016-06-24 16:13:05

标签: javascript

在阅读this article regarding pure functions之后,在我看来,当面向对象JavaScript工作时,纯函数的概念似乎并不像实现那么简单,除非你想最终用大量参数调用函数或者使用它们的数组。

假设我在Javascript对象中有以下功能。

function demo() {
    var self = this;

    //fixed in some other method
    self.order.owner = null;
    self.selectedEvent() = null;
    self.order.booking_id = null;
    self.order.order_id = null;
    self.details = null;
    self.notification = null;
    self.notifyDesk = null;
    self.additionalText = null;

    //WILL THIS FUNCTION BE PURE? 
    self.test = function() {
        if (self.order.owner && self.selectedEvent()) {
            return true;
        }
        else if(self.order.booking_id == '4000' || !self.isValid(self.order.order_id) ){
            return false;
        }
        return self.whatever;
    };

    return self;
}

var myDemo = new Demo();

//whatever other actions over the demo object here

console.log( myDemo.test() );

方法addOrder它在函数范围之外使用5个变量并属于对象范围。 这不是我所理解的纯粹"函数,但除非我们想用5个参数调用addOrder,或者用5个元素调用单个数组参数,否则在我看来我们不能从中获得纯Javascript函数。

在OO Javascript中经常发生这种情况并且访问对象属性是很常见的事情吗?

我错过了什么?请高兴我!

1 个答案:

答案 0 :(得分:1)

纯函数是指任何输入x将始终生成相同的输出y并且不会更改任何状态的函数。只要该功能不违反这些原则,它就是一个纯粹的功能。

这是一个展示纯函数和一些不纯函数之间差异的例子:

var rect = {
  width: 2,
  height: 4
};

function areaPure(rectangle) {
  return rectangle.width * rectangle.height;
}

function areaImpureMutate(rectangle) {
  rectangle.area = rectangle.width * rectangle.height;
}

function areaImpureOuterState() {
  // Uses variable declared outside of scope
  return rect.width * rect.height;
}

console.log('pure:', areaPure(rect)); // no side effects

// Mutates state
areaImpureMutate(rect);
console.log('mutated:', rect.area);

// Relies on mutable state
rect.height = 5;
console.log('mutable state:', areaImpureOuterState(rect));
rect.width = 5;
console.log('mutable state:', areaImpureOuterState(rect));

纯函数的硬性规则是,如果无论程序其余部分的状态如何都给出相同的输入,它将总是给我相同的输出并且< em> not 直接改变程序的状态。

所以你可以像这样重写你的test函数,使它几乎是纯粹的:

function test(obj) {
    if (obj.order.owner && obj.selectedEvent()) {
        return true;
    }
    else if(obj.order.booking_id == '4000' || !obj.isValid(obj.order.order_id) ){
        return false;
    }
    return obj.whatever;
};

它有一个问题:obj.selectedEvent()是一个不纯的函数,它会污染这个纯粹的函数。