Skip to content

Instantly share code, notes, and snippets.

@cowboy
Created May 24, 2012 20:25
Show Gist options
  • Save cowboy/2784002 to your computer and use it in GitHub Desktop.
Save cowboy/2784002 to your computer and use it in GitHub Desktop.
A modern JavaScript if-elseif-else abstraction, because control flow statements are so 1995
/*
* Abstraction.js
*
* Copyright (c) 2012 "Cowboy" Ben Alman
* Licensed under the MIT license.
* http://benalman.com/about/license/
*/
var Abstraction = (function($) {
var _ = $.prototype;
_.then = function(_) {
this._[0] && !this._.slice(1).some(Boolean) && _();
return this;
};
_.if = _.$if = function(_) {
this._ = [_];
return this.then;
};
_.elseif = _.$elseif = function(_) {
this._.unshift(_);
return this.then;
};
_.else = _.$else = function(_) {
this._.some(Boolean) || _();
return this;
};
return $;
}(function() {
this.then = this.then.bind(this);
this.then.then = this.then;
}));
// Working on the "chain" gang
(new Abstraction)
.if(true).then(function() {
console.log('log 1');
})
.if(false).then(function() {
console.log('no log');
})
.if(true).then(function() {
console.log('log 2');
})
.else(function() {
console.log('no log');
})
.if(false).then(function() {
console.log('no log');
})
.else(function() {
console.log('log 3');
})
.if(true).then(function() {
console.log('log 4');
})
.elseif(true).then(function() {
console.log('no log');
})
.else(function() {
console.log('no log');
})
// You actually don't even need the .then!
.if (false) (function() {
console.log('no log');
})
.elseif (true) (function() {
console.log('log 5');
})
.else (function() {
console.log('no log');
});
// For the sake of this example looking totally insane, this function returns the
// console.log function with all arguments pre-applied, to be called at a later time.
function console$log() {
return Function.bind.apply(console.log, [console].concat([].slice.call(arguments)));
}
// Dolla dolla "with" y'all (aka WTF)
with (new Abstraction) {
$if (true) (
console$log('log 1')
)
$if (false) (
console$log('no log')
)
$if (true) (
console$log('log 2')
)
$else (
console$log('no log')
)
$if (false) (
console$log('no log')
)
$else (
console$log('log 3')
)
$if (true) (
console$log('log 4')
)
$elseif (true) (
console$log('no log')
)
$else (
console$log('no log')
)
$if (false) (
console$log('no log')
)
$elseif (true) (
console$log('log 5')
)
$else (
console$log('no log')
)
}
@cowboy
Copy link
Author

cowboy commented May 24, 2012

(I've clearly put a lot of thought into this)

@polotek
Copy link

polotek commented May 24, 2012

Too verbose. This should really be supported by syntax.

@cowboy
Copy link
Author

cowboy commented May 24, 2012

I'm pushing for ES.prev, a return to ECMAScript basics.

@brianewing
Copy link

Reminds me of io, where control structures aren't special at all.

Copy link

ghost commented May 24, 2012

👍. This really needs to be a jQuery plugin, though.

@mkuklis
Copy link

mkuklis commented May 24, 2012

this looks awesome :)

@ryanflorence
Copy link

At least you get scoping! (also, you're crazy).

@cowboy
Copy link
Author

cowboy commented May 25, 2012

Yeah, now you can have "block" scope in JavaScript without those disgusting IIFEs!

@Javlopez
Copy link

i like this code!

@iros
Copy link

iros commented May 25, 2012

This form resembles traditional ifs more... ;)

@cowboy
Copy link
Author

cowboy commented May 25, 2012

I've actually added support for 2 different syntaxes. Chaining and WTF.

@buger
Copy link

buger commented Aug 11, 2012

Looks nice, but i'm afraid not usable with CoffeeScript.

@cowboy
Copy link
Author

cowboy commented Aug 31, 2012

Also see the other version, Abstraction.js "Lite".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment