Skip to content

javascript_in_depth_7

kyusung edited this page Apr 19, 2017 · 1 revision

๋””์ž์ธ ํŒจํ„ด ์‹ค์šฉ - ํ”„๋ฝ์‹œ ํŒจํ„ด

ํ•˜๋‚˜์˜ ๊ฐ์ฒด๊ฐ€ ํ”„๋ฝ์‹œ(๋Œ€๋ฆฌ์ž) ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ƒํ™ฉ์— ๋”ฐ๋ฅธ ๋‹ค๋ฅธ ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๊ฒŒ ํ•ด์ฃผ๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ํŒจํ„ด์ด๋‹ค.

ํ™œ์šฉ

๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด์— ์ค‘๊ฐ„์ž ์—ญํ• ๋กœ ์ž์ฃผ ์‚ฌ์šฉ๋œ๋‹ค. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ์ง์ ‘ ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๋„๋ก, ํ•œ ๋‹จ๊ณ„ ๊ฐ€์ƒํ™” ๋˜๋Š” ์บก์Аํ™”ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. ์ด๋กœ์จ ์„œ๋ฒ„์˜ ๊ธฐ๋Šฅ๋“ค์ด ํด๋ผ์ด์–ธํŠธ์— ์ง์ ‘ ๋…ธ์ถœ๋˜์ง€ ์•Š๊ฒŒํ•œ๋‹ค.
ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์‚ฌ์ด์— ์ ์šฉํ•˜๋ฉด ์š”์ฒญ์— ํ๋ฆ„์„ ์ œ์–ดํ• ์ˆ˜ ์žˆ์–ด์„œ ์„œ๋ฒ„์— ๊ณผ๋ถ€ํ•˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ์ œ

// ํ”„๋ฝ์‹œ ํŒจํ„ด๊ณผ ์บ์‹œ ๊ธฐ๋Šฅ ๊ตฌํ˜„
<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>

Example

// ํ”„๋ฝ์‹œ ํŒจํ„ด์„ ์ด์šฉํ•œ ๋น„๋™๊ธฐ ์š”์ฒญ/์‘๋‹ต ์ฒ˜๋ฆฌ ์ด์Šˆ ํ•ด์†Œ
<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>

Example

ํ”„๋ฝ์‹œ๋ฅผ ํ™œ์šฉํ•œ ๋ž˜ํผ ๊ธฐ๋Šฅ ๊ตฌํ˜„

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์œ ๋™์ ์œผ๋กœ ๋ณ€์ˆ˜, ํ•จ์ˆ˜์— ๋Œ€ํ•˜์—ฌ ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•˜๊ณ  ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ธฐ์กด์— ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ๋Š” ๋ž˜ํผ(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");

Example

// ๊ธฐ์กด ํ•จ์ˆ˜๋ฅผ ๋ฐฑ์—…ํ•˜์—ฌ ํ™œ์šฉํ•˜๋Š” ๋ž˜ํผ ์˜ˆ
(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();
}());

Example

Clone this wiki locally