2 First-Class Functions and Applicative Programming
Functions as First-Class Things
var fortytwo = function() { return 42 };
var fortytwos = [42, function() { return 42 }];
var fortytwos = {number: 42, fun: function() { return 42 }};
42 + (function() { return 42 })();
//=> 84
function weirdAdd(n, f) { return n + f() }
weirdAdd(42, function() { return 42 });
//=> 84
return 42;
return function() { return 42 };
_.each(['whiskey', 'tango', 'foxtrot'], function(word) {
console.log(word.charAt(0).toUpperCase() + word.substr(1));
});
// (console) Whiskey
// (console) Tango
// (console) Foxtrot
JavaScript's Multiple Paradigms
Imperative programming Programming based around describing actions in detail Prototype-based object-oriented programming Programming based around prototypical objects and instances of them Metaprogramming Programming manipulating the basis of JavaScript's execution model
Imperative programming
var lyrics = [];
for (var bottles = 99; bottles > 0; bottles--) {
lyrics.push(bottles + " bottles of beer on the wall");
lyrics.push(bottles + " bottles of beer");
lyrics.push("Take one down, pass it around");
if (bottles > 1) {
lyrics.push((bottles - 1) + " bottles of beer on the wall.");
}
else {
lyrics.push("No more bottles of beer on the wall!");
}
}
function lyricsSegment(n) {
return _.chain([])
.push(n + "bottles of beer on the wall")
.push(n + "bottles of beer")
.push("Take one down, pass it around")
.tap(function(lyrics) {
if(n > 1)
lyrics.push((n - 1) + "bottles of beer on the wall.");
else
lyrics.push("No more bottles of beer on the wall!");
})
.value();
}
Prototype-based object-oriented programming
var a = {name: "a", fun: function () { return this; }};
a.fun();
//=> {name: "a", fun: ...};
var bFunc = function () { return this };
var b = {name: "b", fun: bFunc};
b.fun();
//=> some global object, probably Window
Metaprogramming
function Point2D(x, y) {
this._x = x;
this._y = y;
}
new Point2D(0, 1);
//=> {_x: 0, _y: 1}
function Point3D(x, y, z) {
Point2D.call(this, x, y);
this._z = z;
}
new Point3D(10, -1, 100);
//=> {_x: 10, _y: -1, _z: 100}
Applicative Programming var nums = [1,2,3,4,5];
function doubleAll(array) {
return _.map(array, function(n) {return n*2});
}
doubleAll(nums);
//=> [2, 4, 6, 8, 10]
function average(array) {
var sum = _.reduce(array, function(a, b) {return a+b});
return sum / _.size(array);
}
average(nums);
//=> 3
/* grab only even numbers in nums */
function onlyEven(array) {
return _.filter(array, function(n) {
return (n%2) === 0;
});
}
onlyEven(nums);
//=> [2, 4]
var nums = [1,2,3,4,5];
function doubleAll(array) {
return _.map(array, function(n) {return n*2});
}
doubleAll(nums);
//=> [2, 4, 6, 8, 10]
function average(array) {
var sum = _.reduce(array, function(a, b) {return a+b});
return sum / _.size(array);
}
average(nums);
//=> 3
/* grab only even numbers in nums */
function onlyEven(array) {
return _.filter(array, function(n) {
return (n%2) === 0;
});
}
onlyEven(nums);
//=> [2, 4]
Collection-Centric Programming
_.map({a: 1, b: 2}, _.identity);
//=> [1,2]
_.map({a: 1, b: 2}, function(v, k) {
return [k,v];
});
//=> [['a', 1], ['b', 2]]
_.map({a: 1, b: 2}, function(v,k,coll) {
return [k, v, _.keys(coll)];
});
//=> [['a', 1, ['a', 'b']], ['b', 2, ['a', 'b']]]
Other Examples of Applicative Programming
reduceRight
var nums = [100,2,25];
function div(x,y) {return x/y};
_.reduce(nums, div);
//=> 2
_.reduceRight(nums, div);
//=> 0.125
function allOf(/* funs */) {
return _.reduceRight(arguments, function(truth, f) {
return truth && f();
}, true);
}
function anyOf(/* funs */) {
return _.reduceRight(arguments, function(truth, f) {
return truth || f();
}, false);
}
function T() { return true }
function F() { return false }
allOf();
//=> true
allOf(T, T);
//=> true
allOf(T, T, T , T , F);
//=> false
anyOf(T, T, F);
//=> true
anyOf(F, F, F, F);
//=> false
anyOf();
//=> false
find
_.find(['a', 'b', '3', 'd'], _.isNumber);
//=> 3
reject
_.reject(['a', 'b', 3, 'd'], _.isNumber);
//=> ['a', 'b', 'd']
all
_.all([1, 2, 3, 4], _.isNumber);
//=> true
any
_.any([1, 2, 'c', 4], _.isString);
//=> true
sortBy, groupBy, and countBy
var people = [{name: "Rick", age: 30}, {name: "Jaka", age: 24}];
_.sortBy(people, function(p) { return p.age });
//=> [{name: "Jaka", age: 24}, {name: "Rick", age: 30}]
var albums = [{title: "Sabbath Bloody Sabbath", genre: "Metal"},
{title: "Scientist", genre: "Dub"},
{title: "Undertow", genre: "Metal"}];
_.groupBy(albums, function(a) { return a.genre });
//=> {Metal:[{title:"Sabbath Bloody Sabbath", genre:"Metal"},
// {title:"Undertow", genre:"Metal"}],
// Dub: [{title:"Scientist", genre:"Dub"}]}
_.countBy(albums, function(a) {return a.genre});
//=> {Metal: 2, Dub: 1}
Defining a Few Applicative Functions
function cat() {
var head = _.first(arguments);
if (existy(head))
return head.concat.apply(head, _.rest(arguments));
else
return [];
}
cat([1,2,3], [4,5], [6,7,8]);
//=> [1, 2, 3, 4, 5, 6, 7, 8]
function construct(head, tail) {
return cat([head], _.toArray(tail));
}
construct(42, [1,2,3]);
//=> [42, 1, 2, 3]
Data Thinking var zombie = {name: "Bub", film: "Day of the Dead"};
_.keys(zombie);
//=> ["name", "film"]
_.values(zombie);
//=> ["Bub", "Day of the Dead"]
_.pluck([{title: "Chthon", author: "Anthony"},
{title: "Grendel", author: "Gardner"},
{title: "After Dark"}],
'author');
//=> ["Anthony", "Gardner", undefined]
Summary
var zombie = {name: "Bub", film: "Day of the Dead"};
_.keys(zombie);
//=> ["name", "film"]
_.values(zombie);
//=> ["Bub", "Day of the Dead"]
_.pluck([{title: "Chthon", author: "Anthony"},
{title: "Grendel", author: "Gardner"},
{title: "After Dark"}],
'author');
//=> ["Anthony", "Gardner", undefined]
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.