자바스크립트로 구조적인 프로그래밍을 하려면??

tyolee83의 이미지

자바 스크립트로

처음 프로그램을 짜보는데요,

자바 스크립트가 OOP용은 아닌걸로 알고 있는데,

좀 구조적인 프로그램을 짜야 합니다.

개인적인 용도가 아니라, 회사에서 하는 거라서요

혹시 자바 스크립트 코딩 스타일이나

어떻게 하면 구조적으로 할수 있는지에 대해

조언좀 부탁드립니다.

죠커의 이미지

OOP와 SP(구조적 프로그래밍)은 전혀 다른 개념입니다. 어떤 것을 원하는 것인지 질문을 통해서 알기 힘들군요.

tyolee83의 이미지

OOP에 대한 언급은 그냥 사족처럼 썼던건데

질문이 좀 애매해졌네요

뭐 그러니까

자바 스크립트로 소스를 보기좋고 깔끔하게

하고 싶은데

팁같은게 있나 질문 드린 것입니다 ^^

//TODO

lazycoder의 이미지

제가 현재 웹프로그래머이긴 하나 html이나 script 코딩 능력이 너무 부족하여 언제나 주먹구구식 코딩을 하거나 server에서 처리해버리지요.

비록 javascript 고수는 아닙니다만 아래에 제가 사용하는 코드들의 일부를 보여드리겠습니다.
어렵지 않으리라 생각되는데 클래스화, 오버라이딩과 유사한 기존 클래스에 메서드 추가, 사용자 정의 예외클래스등의 예제입니다.
소스를 이해하시면 아이디어를 떠올리는데 도움이 될 것 같습니다.
그리고 미리 밝혀드리지만 거의 대부분 남의 소스를 참고한 것들입니다.

명료한 해답은 아니겠지만,, 솔직히 괜찮은 javascript 소스나 예제는 서로 공유했으면 하는 바램에 이 글을 썼습니다. :)

// 클래스화 예제
// Class
function cgiRequest(EXECUTE_CGI_URL)
{
    // set some default variables
    this.parms = new Array();
    this.parmsIndex = 0;

    // set the server url
    this.server = EXECUTE_CGI_URL;

    // methods
    this.execute = cgiRequestExecute;
    this.add = cgiRequestAdd;
	this.addById = cgiRequestAddById;
}

// method
function cgiRequestAdd(name, value)
{
    // add a new pair object to the params
    this.parms[this.parmsIndex] = new Pair(name, value);
    this.parmsIndex++;
}

function cgiRequestAddById(id)
{
	this.parms[this.parmsIndex] = new PairById(id);
	this.parmsIndex++;
}

function cgiRequestExecute()
{
	// set the server to a local variable
    var targetURL = this.server;

    // try to create our XMLHttpRequest Object
    try
    {
        //var httpRequest = new XMLHttpRequest();
		var httpRequest = new ActiveXObject("MSXML2.XMLHTTP.3.0");
    }
    catch(e)
    {
        alert("Error creating the connection!\n\n" + e.description);
		return false;
    }

    // make the connection and send our data
    try
    {
        var txt = "";

        for(var i in this.parms)
        {
		/*
            if(txt.length)
            {
                txt = txt + '&';
            }
         
            txt = txt + this.parms[i].name + '=' + this.parms[i].value;
		*/
			if(i == 0)
			{
				txt += this.parms[i].name + "=" + this.parms[i].value;
			}
			else
			{
				txt += "&" + this.parms[i].name + "=" + this.parms[i].value;
			}
		/*	} */
        }

        // GET
//        alert(targetURL + '?' + txt);
		httpRequest.open("GET", targetURL + '?' + txt, false, null, null);
        httpRequest.send('');

        // POST
//        httpRequest.open("POST", targetURL, false, null, null);
//				httpRequest.setRequestHeader("Accept-Language","ko");
//        httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//        httpRequest.setRequestHeader("Content-Type", "text/html; charset=euc-kr");
//        httpRequest.setRequestHeader("Content-Length", txt.length);
//        httpRequest.send(txt);
    }
    catch(e)
    {
        alert("An error has occured calling the external site: " + e);
        return false;
    }

    // make sure we received a valid response
    switch(httpRequest.readyState)
    {
        case 1,2,3:
            alert("Bad ready state: " + httpRequest.status);
            return false;
            break;

        case 4:
            if(httpRequest.status != 200)
            {
                alert("The server respond with a bad status code: " + httpRequest.status);
                return false;
            }
            else
            {
                var response = httpRequest.responseText;
                
				/*
                try
				{
					var s = new XMLSerializer();
					var response = httpRequest.responseXML;
					var str = s.serializeToString(response);
                }
				catch(e)
				{
					alert(e); return;
				}
                alert(str);
				*/
            }
            break;

		default:
			alert("Unknown error.");
			break;
    }

    return response;
	//return str;
}

// utility Pair class
function Pair(name, value)
{
    this.name = name;
    this.value = value;

	//alert("name: " + this.name + "\n\nvalue: <" + this.value + ">");
}

function PairById(id)
{
	this.name = id;
	//alert(id);
//
	this.value = document.getElementById(id).value;
	if(document.getElementById(id).value)
		this.value = document.getElementById(id).value;
	else
		this.value = " ";
//
	//alert("name: " + this.name + "\n\nvalue: <" + this.value + ">");
}

// 기존 클래스에 메서드 추가
String.prototype.trim = function() {
	// Use a regular expression to replace leading and trailing
	// spaces with the empty string
	return this.replace(/(^\s*)|(\s*$)/g, "");
}

// 사용자 정의 예외클래스
function createException(msgNum, msgText)
{
	this.messageNumber = msgNum;
	this.messageText = msgText;
}

// 사용예
function fpIsValidDateRpt(spr, src, col)
{
	var desc = spr.GetValue(spr.ActiveRow, col);

	var yymm = src.replace(/-/g, "").substring(0, 6);
	var yymm1 = desc.replace(/-/g, "").substring(0, 6);	

	if(yymm != yymm1)
	{
		fpInvalidCol(spr, 1, col);
		throw new createException(1, "입력하신 날짜는 보고기간에 포함되지 않습니다. 보고기간내 일자를 입력하십시오.");
	}

	fpInvalidCol(spr, 0, col);
}

// 위 함수의 사용예

try
{
    fpfpIsValidDateRpt(...);
}
catch(e)
{
    alert(e.messaageNumber + ':' + e.messageText);
}
finally
{
    ...
}
tyolee83의 이미지

아직 실행해 보지는 않았습니다다만....

맨 위에부터 this가 나오는데요

선언하지 않고도 바로 this.~~ 에다가

저장을 할수가 있는건가요?

자바스크립트 문법은 문외인이라;;

//TODO

mykldp의 이미지

좋은 코드는 아니지만 여러가지 가능성을 공부해보시라고...

function ClassEx(prop1, prop2)
{
	this.__proto__ = 
	{
		//public methods
	
		"method1" : function()
		{
			alert(this.prop1);
		},
		
		"method2" : function()
		{
			method5(this.prop2);
		},
		
		"method3" : function()
		{
			method5(prop2);
		},
		
		//public fields
		
		"prop1" : prop1,
		"prop2" : prop2
	};
	
	//public methods
	
	this.method4 =  function()
	{
		method5(this.prop3);
	};
	
	this.method6 = method6;
	
	
	//mimic private methods.
	
	method5 = function(msg)
	{
		alert(msg);
	};
	
	//public fields
	
	this.prop3 = "prop3";
	
	//public getter and setter. but not public access to field
	
	var prop4 = "Korea";
	
	this.getProp4 = function()
	{
		return prop4;
	}
	
	this.setProp4 = function(val)
	{
		prop4 = val;
	}
}

function method6()
{
	alert(this.prop1);
}

var ex = new ClassEx("hello", "world");

ex.method1();//"hello"
ex.method2();//"world"
ex.method3();//"world"
ex.method4();//"prop3"
ex.method6();//"hello"

ex.prop2 = "javascript";

ex.method2();//"javascript" !!
ex.method3();//"world" !!

try
{
	ex.method5();// ERROR. It's private method
}
catch(e)
{
	alert(e);
}

alert(ex.getProp4());//Korea
alert(ex.prop4);//undefined
ex.setProp4("Corea");
alert(ex.getProp4());//Corea
7339989b62a014c4ce6e31b3540bc7b5f06455024f22753f6235c935e8e5의 이미지

function 내에서 바로 메소드를 선언하면 메모리 낭비가 많다고 하더군요.
그래서 이렇게 쓰는게 나을 것 같습니다.

function Counter(count) {
  this.count = count;
}

Counter.prototype.increase = function () {
  this.count++;
}
Counter.prototype.decrease = function () {
  this.count--;
}
Counter.prototype.getCount = function () {
  return this.count;
}

counter = new Counter(10);
counter.increase();
counter.increase();
counter.increase();
counter.decrease();

window.alert(counter.getCount()); // 12
prolinko의 이미지

저도 javascript를 잘 모르지만 javascript가 원래 netscape에서 나온거다보니 netscape나 mozilla쪽을 보시면 좋은 자료가 많이 있습니다.

http://developer.mozilla.org/en/docs/JavaScript
http://www.mozilla.org/js
http://www.mozilla.org/docs/web-developer/#scripting

특히 firefox 같은 mozilla product들은 웹페이지에서 사용하듯이 어플리케이션 자체의 행동을 많은 부분은 javascript등으로 scripting 하므로 script 개발에 유용한 툴들을 많이 제공하고, 소스를 들여다 보셔도 도움이 될 부분이 많이 있을 겁니다.

juneaftn의 이미지

프로토타입 기반 언어의 특성을 활용하면 좋은 설계의 코드가 가능합니다.

http://www.crockford.com/javascript/javascript.html
http://en.wikipedia.org/wiki/Prototype-oriented

superwisdom의 이미지

prototype을 사용하면 메서드 코드 영역을 공유하므로 메모리 사용은 줄어들겠지만, public method가 되잖아요?
encapsulation의 실현을 위하여 private method를 구현하기 위해서는, 결국 (위의 ditto님이 단점이라고 지적하시기는 했지만)
함수 내에 method 코드를 삽입할 수 밖에 없지 않나요?

실제로 크록포드씨가 YUI에 구현한 방식을 보면 메모리가 낭비되더라도 확실하게 encapsulation을 해주고 있는 듯 합니다.
아래 사이트에서는 여러가지 방식의 코딩 방식을 설명하고 있습니다.
http://www.wait-till-i.com/2007/08/22/again-with-the-module-pattern-reveal-something-to-the-world/

그래서, 저는 인스턴스를 많이 만들어야 하는 경우에는 prototype을 사용하고 (네이밍 규칙으로 private vs public을 구분),
그렇지 않은 경우는 함수 내에서 바로 method를 구현합니다.

그런데 함수 내에서 바로 method를 구현할 경우 메모리를 많이 사용할텐데, 메모리가 충분하다고 가정할 경우(즉 자바스크립트 해석
엔진 입장에서만 생각해보면) 퍼포먼스에 어떤 영향을 미칠까요? 자바스크립트의 scope chain 방식을 보면, 단순히 객체가 많다고 느려질
이유는 없어보이는데요...

평양선봉의 이미지

http://kangcom.com/sub/view.asp?topid=1&sku=200809180003
이 책이 도움이 되실것 같습니다.

----
웹페이지 : http://bzpalm.net/

----
웹페이지 : http://bzpalm.net/

gamdora의 이미지

제이쿼리

훌륭한 라이브러리를 쓰는 것도 좋은 방법입니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.