Skip to content

Instantly share code, notes, and snippets.

@rtivital
Last active February 12, 2016 18:32
Show Gist options
  • Save rtivital/b2a6c9fc46b3f5faf408 to your computer and use it in GitHub Desktop.
Save rtivital/b2a6c9fc46b3f5faf408 to your computer and use it in GitHub Desktop.
Разбор решения к заданию №2 "Начинаем программировать"
'use strict';
function getMessage(a, b) {
var sum = function(x, y) {
return x + y;
};
var multiply = function(current, index) {
return current * b[index];
};
if (typeof a === 'boolean') {
return a ? 'Я попал в ' + b : 'Я никуда не попал';
}
if (typeof a === 'number') {
return 'Я прыгнул на ' + (a * 100) + ' сантиметров';
}
if (Array.isArray(a)) {
if (!Array.isArray(b)) {
return 'Я прошёл ' + a.reduce(sum) + ' шагов';
}
return 'Я прошёл ' + a.map(multiply).reduce(sum) + ' метров';
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body { font-family: sans-serif; margin: 0; padding: 0; }
.tests-container { max-width: 80%; background-color: #f7f7f7; padding: 2rem; margin: 0 auto; }
code {font-family: 'Consolas', monospace; background-color: #f0f0f0; padding: .2rem .5rem; border: 1px solid #ccc; border-radius: .2rem; }
</style>
</head>
<body>
<div class="tests-container">
<h3>Тестирование функции <code>getMessage</code></h3>
<ul id="tests"></ul>
</div>
<!-- Варианты для тестирования -->
<!-- 1. Исходный -->
<!-- <script src="initial.js"></script> -->
<!-- 2. Улучшенный -->
<!-- <script src="better.js"></script> -->
<!-- 3. Укороченный -->
<script src="better.js"></script>
<!-- Подключение тестов -->
<script src="tests.js"></script>
</body>
</html>
'use strict';
function getMessage(a, b) {
var message;
// Оператор typeof не обзательно обворачивать скобками
// typeof a === 'boolean' будет работать также хорошо
// Всегда (за очень редким исключением) следует использовать
// оператор строгого сравнения ===, а не ==
// Иногда это может привести к ошибкам
// http://learn.javascript.ru/comparison#сравнение-разных-типов
if ( (typeof a) == 'boolean' ) {
// При использовании тернарного оператора не обязательно заключать условие в скобки
// a ? (message = 'Я попал в ' + b) : (message = 'Я никуда не попал');
// Также следует избегать выполнения выражений с тернарным оператором
// Лучше записать вот так
// message = a ? 'Я попал в ' + b : 'Я никуда не попал';
// Полученное выражение можно сразу же вернуть, минуя запись в переменную
// return a ? 'Я попал в ' + b : 'Я никуда не попал';
(a) ? (message = 'Я попал в ' + b) : (message = 'Я никуда не попал');
return message;
}
if ( (typeof a) == 'number' ) {
message = 'Я прыгнул на ' + (a * 100) + ' сантиметров';
return message;
}
if ( Array.isArray(a) && !Array.isArray(b) ) {
// Функция function(x, y) { return x + y; } используется дважды
// Поэтому её лучше записать в переменную и не дублировать код
// var sum = function(x, y) { return x + y; };
// А потом использовать с методом reduce
// var sumArray = a.reduce(sum);
var sumArray = a.reduce(function(x, y) {
return x + y;
});
message = 'Я прошёл ' + sumArray + ' шагов';
return message;
}
// Две проверки массивов можно объеденить в одну конструкцию if
// if (Array.isArray(a)) {
// if (!Array.isArray(b)) { ... return 'Я прошёл ' + sumArray + ' шагов'; }
// return 'Я прошёл ' + length + ' метров';
// }
if ( Array.isArray(a) && Array.isArray(b) ) {
// Функцию можно объявить заранее, чтобы воспользоваться более
// коротким способом без промежуточных переменных
// var multiply = function(current, index) { return current * b[index]; };
// Вместе с написанной ранее функцией sum можно записать следующим образом
// var length = a.map(multiply).reduce(sum);
var multiply = a.map( function(currentValue, index) {
return currentValue * b[index];
});
var length = multiply.reduce(function(x, y) {
return x + y;
});
// Или можно сразу вернуть результат
// return 'Я прошёл ' + a.map(sum).reduce(multiply) + ' метров';
message = 'Я прошёл ' + length + ' метров';
return message;
}
// Подробный разбор перебирающих методов массивов можно посмотреть здесь
// http://jsraccoon.ru/fn-array-methods
}
'use strict';
function getMessage(a, b) {
var sum = function(x, y) {
return x + y;
};
var multiply = function(current, index) {
return current * b[index];
};
if (typeof a === 'boolean') {
return a ? 'Я попал в ' + b : 'Я никуда не попал';
}
if (typeof a === 'number') {
return 'Я прыгнул на ' + (a * 100) + ' сантиметров';
}
// Более короткий вариант с тернарным оператором
// Код становится менее читабельным
// Лучше использовать более длинный вариант
if (Array.isArray(a)) {
return Array.isArray(b)
? 'Я прошёл ' + a.map(multiply).reduce(sum) + ' метров'
: 'Я прошёл ' + a.reduce(sum) + ' шагов';
}
}
// Тесты для проверки функции getMessage
var test = function(expected, actually) {
var tested = 'Тест <b style="color:' + (expected === actually ? 'green">пройден' : 'red">провален') + '</b>.';
var result = '<b>Ожидалось:</b> ' + expected + ' | <b>Результат:</b> ' + actually + ' | ' + tested;
console.log(result);
return result;
};
var results = [];
var testsList = document.getElementById('tests');
var fragment = document.createDocumentFragment();
results.push(test('Я попал в Россию', getMessage(true, 'Россию')));
results.push(test('Я попал в Нарнию', getMessage(true, 'Нарнию')));
results.push(test('Я никуда не попал', getMessage(false, 'Россию')));
results.push(test('Я никуда не попал', getMessage(false, 'Нарнию')));
results.push(test('Я прыгнул на 300 сантиметров', getMessage(3)));
results.push(test('Я прыгнул на 4500 сантиметров', getMessage(45)));
results.push(test('Я прошёл 6 шагов', getMessage([1, 2, 3], {})));
results.push(test('Я прошёл 71 шагов', getMessage([14, 21, 36], '')));
results.push(test('Я прошёл 37 метров', getMessage([1, 2, 3], [4, 6, 7])));
results.forEach(function(item) {
var li = document.createElement('li');
li.innerHTML = item;
fragment.appendChild(li);
});
testsList.appendChild(fragment);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment