-
Notifications
You must be signed in to change notification settings - Fork 0
javascript_in_depth_8
ํธ์ถ ๋์์ด ๋๋ ๊ฐ์ฒด์ ์ถ๊ฐ ๊ธฐ๋ฅ๋ค์ ์์ ๋กญ๊ฒ ์ถ๊ฐํ๋ ํจํด์ด๋ค.
๋ฐ์ปค๋ ์ดํฐ ํจํด์ ์ ์ฉํ๊ฒ ์ด์ฉํ ์ ์๋ ๊ณณ์ ๋ฐ๋ก ๊ฒ์ฆ ๋๊ตฌ์ด๋ค. ๋ฐ์ปค๋ ์ดํฐ ํจํด์ ์ด์ฉํด ๊ฒ์ฆ ๋๊ตฌ๋ฅผ ๋ชจ๋ํํด์ ์ฌ์ฉํ๋ฉด ์ ๋ ฅ ์์์ด ์ฌ๋ฌ ์ข ๋ฅ๊ฐ ์๋ ํ์ด์ง์์๋ ๊ณตํต ๋ชจ๋๋ก ์ฌ์ฉํ ์ ์์ผ๋ฉฐ ์์ฝ๊ฒ ํ์ฅ์ด ๊ฐ๋ฅํ๋ค.
๋ฐ์ปค๋ ์ดํฐ ํจํด์ ์ฅ์ ์ ํ ๋ฒ ์ฒด๊ณ๋ฅผ ๋ง๋ค์ด๋๋ฉด ํ์ฉ๋๋ ๋ฒ์ ์์์๋ ํ์ฅํ๊ณ ์ผ์ฉํ๋ ๊ฒ์ด ๋งค์ฐ ํธ๋ฆฌํ๋ค๋ ์ ์ด๋ค. ํ์ง๋ง ๋ฐ๋๋ก ์ฒซ ๋ฒ์งธ ์ฒด๊ณ๋ฅผ ๋ง๋๋ ๊ฒ์ด ์ด๋ ค์ธ ์๋ ์๊ณ , ํ์ฉ ๊ฐ๋ฅํ ๋ฒ์๋ฅผ ๊ฒฐ์ ํ๊ณ ๋ ๋ค์, ํน์ ํ ์ํฉ์ ๋ฐ๋ผ ์กฐ๊ธ ๋ค๋ฅด๊ฒ ์ฒ๋ฆฌํ๊ณ ์ถ์ ๋ ์์ค๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉด์ ์์ ํ๋ ๊ฒ์ด ๋ค์ ์ด๋ ค์ธ ์๋ ์๋ค. ๊ทธ๋ผ์๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํ์ฌ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ํ ๋ ๋งค์ฐ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ ๋์์ธ ํจํด์ด๋ค.
// ํผ ๊ฒ์ฆ์ ์ํ ๋ฐ์ปค๋ ์ดํฐ ํจํด ์ค์ฉ
<html>
<body>
<form id="personalInformation">
<label>First name: <input type="text" class="validate" data-validate-rules="required alphabet" name="firstName"></input></label><br/>
<label>Last name: <input type="text" class="validate" data-validate-rules="required alphabet" name="lastName"></input></label><br/>
<label>Age: <input type="text" class="validate" data-validate-rules="number" name="age"></input></label><br/>
<label>Gender: <select class="validate" data-validate-rules="required">
<option>Male</option>
<option>Female</option>
</select></label><br/>
<input type="submit"></input>
</form>
<script>
(function () {
var formPersonalInformation = document.getElementById("personalInformation"),
validator = new Validator(formPersonalInformation);
function Validator (form) {
this.validatingForm = form;
form.addEventListener("submit", function () {
if (!validator.validate(this)) {
event.preventDefault();
event.returnValue = false;
return false;
}
alert("Success to validate");
return true;
});
}
Validator.prototype.ruleSet = {};
Validator.prototype.decorate = function (ruleName, ruleFunction) {
this.ruleSet[ruleName] = ruleFunction;
}
Validator.prototype.validate = function (form) {
var validatingForm = form || this.validatingForm,
inputs = validatingForm.getElementsByClassName("validate"),
length = inputs.length,
i, j,
input,
checkRules, rule, ruleLength;
for(i = 0 ; i < length ; i++) {
input = inputs[i];
if (input.dataset.validateRules) {
checkRules = input.dataset.validateRules.split(" ");
ruleLength = checkRules.length;
for (j = 0 ; j < ruleLength ; j++) {
rule = checkRules[j];
if (this.ruleSet.hasOwnProperty(rule)) {
if (!this.ruleSet[rule].call(null, input)) {
return false;
}
}
}
}
}
};
validator.decorate("required", function (input) {
if (!input.value) {
alert(input.name + " is required");
return false;
}
return true;
});
validator.decorate("alphabet", function (input) {
var regex = /^[a-zA-Z\s]*$/;
if (!regex.test(input.value)) {
alert(input.name + " has to be only alphabets");
return false;
}
return true;
});
validator.decorate("number", function (input) {
var regex = /^[0-9]*$/;
if (!regex.test(input.value)) {
alert(input.name + " has to be only numbers");
return false;
}
return true;
});
}());
</script>
</body>
</html>๋ฐ์ปค๋ ์ดํฐ ํจํด์ ๊ฒ์ฆ ๋๊ตฌ ์ธ์๋ ๊ฐ์ฒด์งํฅ ๊ฐ๋ ์ ์๋ฐ์คํฌ๋ฆฝํธ์ ์ ์ฉํ๋ ค๊ณ ํ ๋ ์ด์ฉํ ์ ์๋ค. ์ฆ, ํ๋์ ๊ฐ์ฒด์ ์ฌ๋ฌ ๊ฐ์ง ๊ธฐ๋ฅ๋ค์ ์ถ๊ฐํจ์ผ๋ก์จ ๊ธฐ์กด์ ๊ฐ์ฒด์ ์ถ๊ฐ๋ก ๊พธ๋ฉฐ์ง ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋ผ ์ ์๋ค. ๋ค์์ ๋ค์ํ ์ปดํจํฐ๋ฅผ ๋ฐ์ปค๋ ์ดํฐ ํจํด์ ์ด์ฉํด์ ๋ค๋ฅด๊ฒ ์์ฑํ๊ณ ๋ค๋ฅธ ๋ถํ์ ์ปดํจํฐ์ ์ถ๊ฐํ์ฌ ๊ฐ๊ฒฉ์ ์์๋ณด๋ ์์ด๋ค.
// ๊ฐ์ฒด๊ธฐ๋ฐ ๋ฐ์ปค๋ ์ดํฐ ํจํด
(function () {
function Computer(name) {
this.name = name;
this.price = 0;
this.parts = [];
}
Computer.prototype = {
showPrice: function () {
console.log(this.name + " costs $" + this.price);
},
showParts: function () {
var partString = "- Parts information\n",
length = this.parts.length,
i;
for (i = 0 ; i < length ; i++) {
partString += this.parts[i].name + ": $" + this.parts[i].price + "\n";
}
console.log(partString + "\n- Total: $" + this.price);
},
decorate: function (part) {
this.price += part.price;
this.parts.push(part);
}
};
function ComputerDecorator() {
this.decorateParts = {};
}
ComputerDecorator.prototype.decorateComputer = function (computer, partName) {
if (this.decorateParts.hasOwnProperty(partName)) {
computer.decorate(this.decorateParts[partName]);
console.log("Decorating " + computer.name + " with " + partName);
}
return computer;
};
ComputerDecorator.prototype.addDecoratePart = function (partName, price) {
this.decorateParts[partName] = {
name: partName,
price: price
};
};
var computerDecorator = new ComputerDecorator();
computerDecorator.addDecoratePart("CPU", 200);
computerDecorator.addDecoratePart("8GB memory", 100);
computerDecorator.addDecoratePart("4GB memory", 50);
console.log("1. Home computer");
var homeComputer = new Computer("Home computer");
homeComputer = computerDecorator.decorateComputer(homeComputer, "CPU");
homeComputer = computerDecorator.decorateComputer(homeComputer, "4GB memory");
homeComputer.showPrice();
homeComputer.showParts();
console.log("\n2. Work computer");
var workComputer = new Computer("Work computer");
workComputer = computerDecorator.decorateComputer(workComputer, "CPU");
workComputer = computerDecorator.decorateComputer(workComputer, "8GB memory");
homeComputer.showPrice();
workComputer.showParts();
}());ํจ์์๋ ์ถ๊ฐ ๊ธฐ๋ฅ์ ์ํํ๊ธฐ ์ํด ๋ฐ์ปค๋ ์ดํฐ ํจํด์ ์ ์ฉํ๊ธฐ๋ ํ๋ค. ํ๋ฝ์ ํจํด์ ๋ํผ ๊ธฐ๋ฅ์ ๋ฐ์ปค๋ ์ดํฐ ํจํด๊ณผ ํจ๊ป ์ฌ์ฉํ๋ฉด, ํด๋น ํจ์๊ฐ ํธ์ถ๋๊ธฐ ์ ์ ์ฌ๋ฌ ๊ฐ์ง ํจ์๊ฐ ํธ์ถ๋ ์ ์๋๋ก ์์ฉํ ์ ์๋ค.
// ๋ชจ๋ํฐ๋ง ๊ธฐ๋ฅ์ ์ํ ๋ฐ์ปค๋ ์ดํฐ ํจํด๊ณผ ํ๋ฝ์ ํจํด์ ์กฐํฉ
(function () {
var monitorTool,
car,
wrapperFunction;
monitorTool = (function () {
var functionSequence = [];
return {
decorate: function (name, func) {
functionSequence.push({
name: name,
func: func });
},
monitor: function (func) {
var length = functionSequence.length;
for (i = 0 ; i < length ; i++) {
functionSequence[i].func.apply(this, arguments);
}
}
};
}());
monitorTool.decorate("before", function (func) {
console.log(func.name + " function has started at " + Date.now());
});
monitorTool.decorate("decorated", function (func) {
func.apply(this, Array.prototype.slice(arguments, 1));
});
monitorTool.decorate("after", function (func) {
console.log(func.name + " function has finished at " + Date.now());
});
wrapperFunction = monitorTool.monitor;
car = {
beep: function beep() {
alert("BEEP"); },
brake: function brake() {
alert("STOP!");
},
accelerator: function accelerator() {
alert("GO");
}
};
function wrap(func, wrapper) {
return function() {
var args = [func].concat(Array.prototype.slice.call(arguments));
return wrapper.apply(this, args);
};
}
function wrapObject(obj, wrapper) {
var prop;
for(prop in obj) {
if (obj.hasOwnProperty(prop) && typeof obj[prop] === "function") {
obj[prop] = wrap(obj[prop], wrapper);
}
}
}
wrapObject(car, wrapperFunction);
console.log("A. car.accelerator() monitor");
car.accelerator();
console.log("\nB. car.beep() monitor");
car.beep();
console.log("\nC. car.brake() monitor");
car.brake();
}());