-
Notifications
You must be signed in to change notification settings - Fork 0
javascript_in_depth_7
ํ๋์ ๊ฐ์ฒด๊ฐ ํ๋ฝ์(๋๋ฆฌ์) ์ญํ ์ ์ํํ์ฌ ์ํฉ์ ๋ฐ๋ฅธ ๋ค๋ฅธ ๊ฐ์ฒด์ ์ ๊ทผํ๊ฒ ํด์ฃผ๊ฑฐ๋ ๋ค๋ฅธ ํจ์๋ฅผ ํธ์ถํ๊ฒ ํด์ฃผ๋ ํจํด์ด๋ค.
๋ํ์ ์ธ ์๋ก ์๋ฒ์ ํด๋ผ์ด์ธํธ ์ฌ์ด์ ์ค๊ฐ์ ์ญํ ๋ก ์์ฃผ ์ฌ์ฉ๋๋ค. ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์ง์ ์ ๊ทผํ์ง ๋ชปํ๋๋ก, ํ ๋จ๊ณ ๊ฐ์ํ ๋๋ ์บก์ํํ๋ ๊ธฐ๋ฅ์ด๋ค. ์ด๋ก์จ ์๋ฒ์ ๊ธฐ๋ฅ๋ค์ด ํด๋ผ์ด์ธํธ์ ์ง์ ๋
ธ์ถ๋์ง ์๊ฒํ๋ค.
ํด๋ผ์ด์ธํธ์ ์๋ฒ ์ฌ์ด์ ์ ์ฉํ๋ฉด ์์ฒญ์ ํ๋ฆ์ ์ ์ดํ ์ ์์ด์ ์๋ฒ์ ๊ณผ๋ถํ๋ฅผ ์ค์ผ ์ ์๋ค.
// ํ๋ฝ์ ํจํด๊ณผ ์บ์ ๊ธฐ๋ฅ ๊ตฌํ
<html>
<body>
<video style="width:240px" id="videoBunnySmall" src="http://media.w3.org/2010/05/bunny/movie.ogv"></video>
<video style="width:320px" id="videoBunnyMedium" src="http://media.w3.org/2010/05/bunny/movie.ogv"></video>
<video style="width:480px" id="videoBunnyLarge" src="http://media.w3.org/2010/05/bunny/movie.ogv"></video>
<div id="controlPanel">
<select id="controlVideo">
<option>videoBunnySmall</option>
<option>videoBunnyMedium</option>
<option>videoBunnyLarge</option>
</select>
<button id="play">Play</button>
<button id="pause">Pause</button>
<button id="volumeUp">Volume+</button>
<button id="volumeDown">Volume-</button>
</div>
<script>
(function () {
var divControlPanel = document.getElementById("controlPanel"),
selectControlVideo = document.getElementById("controlVideo"),
controlVideo = {
"play": function (video) {
video.play();
},
"pause": function (video) {
video.pause();
},
"volumeUp": function (video) {
if (video.volume <= 0.9) {
video.volume += 0.1;
} else {
video.volume = 1;
}
},
"volumeDown": function (video) {
if (video.volume >= 0.1) {
video.volume -= 0.1;
} else {
video.volume = 0;
}
},
"getVideoById": function (id) {
return document.getElementById(id);
}
},
proxyClickEventHandler = (function () {
var cache = {};
return function (command) {
var video;
if (controlVideo.hasOwnProperty(command)) {
if (cache.hasOwnProperty(selectControlVideo.value)) {
video = cache[selectControlVideo.value];
} else {
video = controlVideo.getVideoById(selectControlVideo.value);
cache[selectControlVideo.value] = video;
}
controlVideo[command].call(this, video);
}
};
}());
divControlPanel.addEventListener("click", function (e) {
var target = e.target || e.srcElement;
proxyClickEventHandler(target.id);
}, true);
}());
</script>
</body>
</html>// ํ๋ฝ์ ํจํด์ ์ด์ฉํ ๋น๋๊ธฐ ์์ฒญ/์๋ต ์ฒ๋ฆฌ ์ด์ ํด์
<html>
<head>
<style>
#chatLog {
border:1px solid black;
width: 200px;
height: 200px;
overflow-y: scroll;
}
</style>
</head>
<body>
<div id="chatLog"></div>
<form id="formChat">
<input type="text" id="inputChat"></input>
<input type="submit" value="send"></input>
</form>
<script>
(function () {
var divChatLog = document.getElementById("chatLog"),
formChat = document.getElementById("formChat"),
inputChat = document.getElementById("inputChat"),
isPending = false,
requestChat = [];
formChat.addEventListener("submit", function () {
proxySendChat(inputChat.value);
inputChat.value = "";
event.returnValue = false;
return false;
});
function proxySendChat(chat) {
if (isPending === true) {
requestChat.push(chat);
} else {
sendChatRequest([chat]);
}
}
function sendChatRequest(chats) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "./send_chat.php", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
isPending = true;
xhr.onload = function () {
var pChat = document.createElement("p");
pChat.innerHTML = xhr.responseText;
divChatLog.appendChild(pChat);
if (requestChat.length > 0) {
sendChatRequest(requestChat);
requestChat = [];
} else {
isPending = false;
}
};
xhr.send("chats=" + encodeURIComponent(JSON.stringify(chats)));
}
}());
</script>
</body>
</html>์๋ฐ์คํฌ๋ฆฝํธ๋ ์ ๋์ ์ผ๋ก ๋ณ์, ํจ์์ ๋ํ์ฌ ์ฝ๊ฒ ์ ๊ทผํ๊ณ ํธ์ถํ ์ ์๋ค. ๋ฐ๋ผ์ ๊ธฐ์กด์ ์๋ ํจ์๋ฅผ ๋ค๋ฅธ ํจ์๋ก ๊ฐ์ธ๋ ๋ํผ(wrapper) ํ์์ ๊ธฐ๋ฅ์ ์ฝ๊ฒ ์ ๊ณตํ ์ ์๋ค. ์ด๋ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ชจ๋์ ํจ์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ์ ์ฒ๋ฆฌ๋ฅผ ํธํ๊ฒ ํ ์ ์์์ ์๋ฏธํ๋ค.
// ํ๋ฝ์ ํจํด์ ์ด์ฉํ ๋ํผ ๊ตฌํ
function wrap(func, wrapper) {
return function() {
var args = [func].concat(Array.prototype.slice.call(arguments));
return wrapper.apply(this, args);
};
}
function existingFunction() {
console.log("Existing function is called with arguments");
console.log(arguments);
}
var wrappedFunction = wrap(existingFunction, function (func) {
console.log("Wrapper function is called with arguments");
console.log(arguments);
func.apply(this, Array.prototype.slice.call(arguments, 1));
});
console.log("1. Calling existing function");
existingFunction("First argument", "Second argument", "Third argument");
console.log("\n2. Calling wrapped function");
wrappedFunction("First argument", "Second argument", "Third argument");// ๊ธฐ์กด ํจ์๋ฅผ ๋ฐฑ์
ํ์ฌ ํ์ฉํ๋ ๋ํผ ์
(function () {
function wrap(func, wrapper) {
return function() {
var args = [func].concat(Array.prototype.slice.call(arguments));
return wrapper.apply(this, args);
};
}
var _existingFunction = existingFunction,
existingFunction = wrap(_existingFunction, function (func) {
console.log("Wrapper function is called with arguments");
console.log(arguments);
func.apply(this, Array.prototype.slice.call(arguments, 1));
});
function existingFunction() {
console.log("Existing function is called with arguments");
console.log(arguments);
}
// ๋ณ์ ์ ๊ทผ ์ฐ์ ์์์ ๋ฐ๋ผ ๋ณ์์ ๋จผ์ ์ ๊ทผํ๊ฒ ๋๋ค
console.log("1. Calling wrapped existing function");
existingFunction("First argument", "Second argument", "Third argument");
}());๋ชจ๋์ด๋ ๊ฐ์ฒด์ ์์ฑ์ผ๋ก ์๋ ํจ์๋ฅผ ํธ์ถํ๊ฒ ๋ ๋๋ ์์์ ์ด ์๋๋ผ ์๋์ผ๋ก ์ ์ฒด ํจ์์ ๋ํ ๋ํผํจ์๋ฅผ ์ค์ ํ ์ ์๋ค. ํจ์๋ฅผ ๊ฐ์ฒด๋ก ๊ด๋ฆฌํ๋ ๊ฒฝ์ฐ์ ์ผ๊ด์ ์ผ๋ก ํ๋ฝ์ ํจํด์ ์ ์ฉํด์ ์ถ๊ฐ์ ์ธ ์ ์ฒ๋ฆฌ ๋ก์ง์ ์ฝ์ ํ๊ฒ ๋๋ฉด ๋๋ฒ๊น ์ด๋ ์ฌ์ฉ์์ ํ๋ ํจํด ๋ถ์, ๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํ์ฉ๋๋ฅผ ํต๊ณ์ ์ผ๋ก ๋ถ์ํ๋ ์ฉ๋๋ก ํ์ฉํ ์ ์๋ค.
// ๋ก๊ทธ ๊ธฐ๋ก์ ์ํ ๋ํผ ์
(function () {
var 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, function (func) {
console.log(func.name + " has been invoked");
func.apply(this, Array.prototype.slice(arguments, 1));
});
car.accelerator();
car.beep();
car.brake();
}());