Contenu connexe Similaire à Functional JavaScript with Lo-Dash.js (20) Plus de Shogo Sensui (17) Functional JavaScript with Lo-Dash.js14. 猫をOOPで表現する
var Animal = function(word) {
this.word = word;
};
Animal.prototype.cry = function() {
console.log(this.word);
};
!
var Cat = function() {
Animal.call(this, "Nya-");
};
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Animal;
!
new Cat().cry();
//=>Nya-
15. jQueryもOOP?
var $headline = $(".headline");
$headline.css({
"font-size": "24px"
});
var $paragraph = $("p");
$paragraph.css({
"background": "#000",
"color": "#fff"
}).addClass("breakAll");
!
var $button = $("button");
$button.on("click", function() {
console.log("button is clicked!");
});
24. This is bad...
var sortedString = function(array) {
array.sort();
!
return array.join();
};
!
var array1 = [1, 6, 8, 4, 9, 0, 3, 5, 2, 7];
!
console.log(sortedString(array1));
//=>0,1,2,3,4,5,6,7,8,9
!
console.log(array1);
//=>[0,1,2,3,4,5,6,7,8,9]
//引数が変更されてしまっている…。
25. This is better !!!
var sortedString = function(array) {
var buffer = array.slice();
buffer.sort();
return buffer.join();
};
!
var array1 = [1, 6, 8, 4, 9, 0, 3, 5, 2, 7];
!
console.log(sortedString(array1));
//=>0,1,2,3,4,5,6,7,8,9
!
console.log(array1);
//=>[1,6,8,4,9,0,3,5,2,7]
//OK!
27. This is bad...
var setElement = function() {
$(".hoge").addClass("decorationClass").animate({...});
};
var initMainPage = function() {
window.scrollTo(1, 0);
setElement();
};
window.onload = function() {
initMainPage();
};
28. This is better !!!
var setElement = function(element) {
$(element).addClass("decorationClass").animate({...});
};
var hideAddressBar = function() {
window.scrollTo(1, 0);
};
window.onload = function() {
hideAddressBar();
setElement(document.getElementsByClassName(".hoge"));
};
30. jQueryっぽいサンプル実装
var $ = function(selector) {
return {
list: document.querySelectorAll(selector),
each: function(callback) {
for(var i = 0, l = this.list.length;i < l;i++) {
callback(this.list[i]);
}
return this;
},
addClass: function(className) {
return this.each(function(element) {
element.classList.add(className);
});
}
};
};
33. Functionalに書き直す
var _ = {};
!
_.qsa = function(selector) {
return document.querySelectorAll(selector);
};
!
_.each = function(targetObject, callback) {
for(var i = 0, len = targetObject.length;i < len;i++) {
callback(targetObject[i]);
}
};
!
_.addClass = function(targetElementList, className) {
_.each(targetElementList, function(element) {
element.classList.add(className);
});
};
50. - John-David Dalton
at StackOverflow
œš‘“›⁸better overall performance and
optimizations for large arrays/object
iteration, and more flexibility with
custom builds and template pre-
compilation utilities.’”⁹
http://stackoverflow.com/questions/13789618/differences-between-
lodash-and-underscore
58. _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (iterator.call(context, obj[i], i, obj) ===
breaker) return;
}
} else {
for (var key in obj) {
if (_.has(obj, key)) {
if (iterator.call(context, obj[key], key,
obj) === breaker) return;
}
}
}
};
59. _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (iterator.call(context, obj[i], i, obj) ===
breaker) return;
}
} else {
for (var key in obj) {
if (_.has(obj, key)) {
if (iterator.call(context, obj[key], key,
obj) === breaker) return;
}
}
}
};
60. _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (iterator.call(context, obj[i], i, obj) ===
breaker) return;
}
} else {
for (var key in obj) {
if (_.has(obj, key)) {
if (iterator.call(context, obj[key], key,
obj) === breaker) return;
}
}
}
};
ネイティブのforEachが使える場
合はそれを実行している
62. function forEach(collection, callback, thisArg) {
var index = -1,
length = collection ? collection.length : 0;
callback = callback && typeof thisArg == 'undefined' ?
callback : lodash.createCallback(callback, thisArg);
if (typeof length == 'number') {
while (++index < length) {
if (callback(collection[index], index,
collection) === false) {
break;
}
}
} else {
forOwn(collection, callback);
}
return collection;
}
63. function forEach(collection, callback, thisArg) {
var index = -1,
length = collection ? collection.length : 0;
callback = callback && typeof thisArg == 'undefined' ?
callback : lodash.createCallback(callback, thisArg);
if (typeof length == 'number') {
while (++index < length) {
if (callback(collection[index], index,
collection) === false) {
break;
}
}
} else {
forOwn(collection, callback);
}
return collection;
}
64. function forEach(collection, callback, thisArg) {
var index = -1,
length = collection ? collection.length : 0;
callback = callback && typeof thisArg == 'undefined' ?
callback : lodash.createCallback(callback, thisArg);
if (typeof length == 'number') {
while (++index < length) {
if (callback(collection[index], index,
collection) === false) {
break;
}
}
} else {
forOwn(collection, callback);
}
return collection;
}
基本的にwhile文を使っている
69. Modern build モダンブラウザ向けのビルド。
Legacy build レガシーブラウザ対応がなされている。
Mobile build 関数のコンパイルがされていない
Strict build
読み取り専用プロパティを上書きしよう
としたときにエラーを投げる。
Underscore build Underscore.jsにAPIを合わせてある。
Backbone build Backbone.jsに必要なAPIのみ備える。
70. Modern build モダンブラウザ向けのビルド。
Legacy build レガシーブラウザ対応がなされている。
Mobile build 関数のコンパイルがされていない
Strict build
読み取り専用プロパティを上書きしよう
としたときにエラーを投げる。
Underscore build Underscore.jsにAPIを合わせてある。
Backbone build Backbone.jsに必要なAPIのみ備える。
76. var stooges = [
{name : 'moe', age : 40},
{name : 'larry', age : 50},
{name : 'curly', age : 60}
];
!
_.pluck(stooges, 'name');
//=> ["moe", "larry", "curly"]
79. _.compose = function(/*, funs */) {
var functions = arguments;
return function() {
var args = arguments;
for (var i = functions.length - 1; i >= 0; i--) {
args = [functions[i].apply(this, args)];
}
return args[0];
};
};
80. var plusFive = function(num) {
return num + 5;
};
var multiplyThree = function(num) {
return num * 3;
};
var plus5_multiply3 = _.compose(multiplyThree, plusFive);
plus5_multiply3(4);
//=>27
83. _.pipeline = function(/*, funs */){
var functions = arguments;
!
return function(seed) {
return _.reduce(functions, function(l, r) {
return r(l);
}, seed);
};
};
84. var plusFive = function(num) {
return num + 5;
};
var multiplyThree = function(num) {
return num * 3;
};
var multiply3_plus5 = _.pipeline(multiplyThree, plusFive);
multiply3_plus5(4);
//=>17
86. function square(x) {
return x * x;
}
function inc(x) {
return x + 1;
}
function isEven(x) {
return x % 2 === 0;
}
!
var result = _.chain(array)
.map(square).map(inc)
.filter(isEven).take(5).value();
!
var result = Lazy(array)
.map(square).map(inc)
.filter(isEven).take(5);