'자바스크립트'에 해당되는 글 14건

  1. 2007.07.06 js_string , 문자열 제어 함수, 프로토 타입 모음
  2. 2007.06.28 애플닷컴의 제품 슬라이더 자바스크립트 분석
  3. 2007.05.31 IE Memory Leaks
  4. 2007.04.17 Prototype base multi-Selection API
  5. 2007.04.16 Prototype기반 벡터 그래픽 프레임웍 - PGF
  6. 2007.04.13 자바스크립트가 그려낸 둥근 모서리 - Transcorners
  7. 2007.04.13 정확히 말하면 ECMA 스크립트의 특징이지만 뭐… ^^
  8. 2007.04.13 테이블 틀고정 스크롤
  9. 2007.04.13 IE/FF(Gecko,W3C) 이벤트 설명
  10. 2007.04.12 new Object() 와 {} 의 차이에 대한 댓글정리문서
2007.07.06 18:36

js_string , 문자열 제어 함수, 프로토 타입 모음

현재 구현된건
1. 숫자에 천단위 ,표 붙이기(프로토타입,함수)
2. 숫자를 한글로 출력(프로토타입,함수  )
3. 문자열에서 앞뒤(앞,뒤) 공백제거 (프로토타입,함수)
4. 문자열에서 문자열 제한(영어만, 또는 영어와 한글만 등등)

---------=-----------
그냥 안 올릴까.. 하다가
홈피 이사후 방문자수가 푸욱~~ 줄어서... 낚씨용?으로.

사용할 때 꼭 .JS파일 안을 열어보세요.
그안에 대부분의 설명이 다 되어있습니다.

http://www.mins01.com/20070305/m_board/tech.php?b_id=tech&type=read&b_idx=411&page=1&period=365
신고
Trackback 4 Comment 0
2007.06.28 08:53

애플닷컴의 제품 슬라이더 자바스크립트 분석



출처 :  파이어준
애플닷컴의 iTunes페이지에 자바스크립트로 구현 된 제품 슬라이더가 심상치 않아 보여서 파 보았다. 이 제품 슬라이더는 Prototype.jsScriptaculous의 Slider컨트롤러가 사용 되었으며, 주요한 기능은 특정영역으로의 스내핑과  가로 스크롤바를 통한 제품 내비게이션이다. 이런저런 쓰레기 코드를 제거하였더니 약 150라인정도로 구현된 것을 알 수 있었다. 흥미로운 것은 아이폰의 인터페이스처럼 던지기(?) 제스쳐를 스크롤바에 적용해 놓았다. 위 데모에서 스크롤바를 힘껏 던져보자. 내키면 컴포넌트화하는 작업도 진행해 볼 생각이다.

  /* PRODUCT BROWSER */ 
  Event.observe(window, 'load', function() {
    AC.ProductBrowser.init({
      categories: [ {id: 'pb-cat1', offset: 0},
                    {id: 'pb-cat2', offset: 0.155},
                    {id: 'pb-cat3', offset: 0.657} ], // default offsets
      imageOverlap: 0,
      sliderCentering: 187, // handler width
      initialCategory: 1,
      arrowScrollAmount: 0.44
    });
  });
신고
Trackback 0 Comment 0
2007.05.31 00:53

IE Memory Leaks

IE의 메모리 릭에 관한 글입니다. 번역한 거라서 그런지 좀 덜 매끄러운 부분이 있네요.

엄밀히 말해서 JavaScript와 JScript는 다른 언어입니다. JScript가 JavaScript 버전에 대응하기는하나 다른 언어이기 때문에 허용하는 것과 그렇지 않은 것, 그리고 가비지 컬렉터와 DOM을 다루는 방법 등이 다릅니다.

JavaScript를 다룸에 있어서 서로 다르다는 사실을 알고 작성하셔야 나중에 "분명히 되야하는데 안되는" 일이 발생해도 당황하지 않을 수 있습니다. JScript에서는 되는게 JavaScript에서는 안될 수도 있으며 반대로 JavaScript에서는 되는 것이 JScript에서는 안될 수도 있습니다. 인코딩, 쉼표 등 이런 문제가 될만한 소재는 매우 다양합니다.

아래에 소개해드리는 글도 JScript가 DOM과 결합할 때 메모리 릭이 있다는 글입니다. 글 중간쯤에 쓴 것과 마찬가지로 옛날에는 별 문제가 없었을지 모르지만 최근의 Ajax 처럼 DOM을 많이 다루게 되는 경우라면 메모리의 누적이 심각한 오류를 불러올 수도 있습니다. 이 외에도 IE의 버그에 관련된 여러가지 팁들이 있는데 차차 작성 혹은 번역해서 올릴 생각입니다.

아... 잠깐 광고. 드디어 팁 갯수가 90개가 되었네요. ^^
.
.
.
.

이 문서는 원본글 작성자인 Douglas Crockford 씨의 동의를 얻어 번역한 글입니다.
_____________________________________________________________________
시스템이 메모리 관리를 올바르게 하지 못한다면 그것을 메모리 릭이라 부른다. 메모리 릭은 일종의 버그이다. 증상으로는 퍼포먼스를 저하시키거나 오류가 발생하는 것 등이 있다.

Microsoft 사의 인터넷 익스플로러에는 많은 종류의 메모리 릭이 내재하고 있는데, 그 중에서 가장 악질은 JScript 와 연동할 때 발생하는 것이다. DOM 객체가 JavaScript 객체(이벤트 핸들링 함수같은)의 레퍼런스를 포함하고, JavaScript 객체가 해당 DOM 객체에 대한 레퍼런스를 포함할 때, 순환구조가 형성된다. 이것 자체로는 문제가 되지 않는다. DOM 객체와 이벤트 핸들러에 대한 다른 참조가 없을 때, 가비지 컬렉터garbage collector (자 동 리소스 관리자)는 그들을 교정하고 사용되었던 메모리 공간을 재할당이 가능하도록 한다. JavaScript의 가비지 컬렉터는 순환에 대해 잘 이해하기 때문에 그것으로 인한 혼란이 없다. 하지만, 안타깝게도 IE의 DOM은 JScript가 관리한다. JScript의 메모리 관리자는 순환에 대해 잘 이해하지 못하기 때문에 매우 많은 혼란을 겪는다. 그 결과, 순환이 발생할 때, 메모리 교정이 일어나지 않으며, 교정되지 않은 메모리를 가리켜 누수되었다leaked고 한다. 시간이 흐르면, 이런 누수현상이 메모리 자원부족memory starvation을 유발한다. 사용된 셀이 메모리를 가득 채우면 브라우저는 자원부족으로 죽어버릴 것이다.

위에서 언급한 현상을 시연해 볼 수 있다. 첫번째 프로그램인 queuetest1에 서 10000개의 DOM 엘리먼트(span)를 만들고 동시에 최근 10개를 제외한 나머지를 전부 삭제할 것이다. 프로그램을 실행할 때, 윈도우즈의 작업관리자의 성능탭을 이용하면 페이지 파일(PF = Page File) 사용량이 항상 일정한지 볼 수 있다. PF 사용량이 변한다면 이는 메모리 할당이 비효율적이라는 것을 의미한다.
다음으로 두번째 프로그램인 queuetest2를 실행해보자. queuetest1과 똑같은 동작을 하지만 각 엘리먼트에 click 핸들러를 추가했다. 모질라와 오페라에서는 PF 사용량이 거의 일정한 반면에 IE에서는 메모리 누수로 초당 1MB 정도의 비율로 사용량이 점점 증가하는 것을 알 수 있다. 종종 이러한 누수현상은 모른채 지나쳤다. 하지만 Ajax 기술이 더 유명해짐에 따라 각 페이지에서 더 오래 머무르게 되고 더 많은 변화와 실패가 일반적이게 되었다.

IE가 자기일이나 순환 교정을 제대로 못하기 때문에 그 일은 고스란히 우리 몫이 되었다. 명시적으로 순환을 해제한다면 IE도 메모리를 교정할 수 있다. Microsoft에 따르면, closures가 메모리 누수의 원인이 된다고 한다. 이건 물론 매우 틀린 말이지만, Microsoft가 자신들의 버그에 대해서 개발자들에게 아주 나쁜 조언을 하는 결과를 가져왔다. 순환구조는 DOM 쪽에서 끊는 것이 더 쉽다. 사실상 JScript 쪽에서 순환구조를 끊기란 불가능하다.

엘리먼트를 다룰 때는, 순환구조를 끊기 전에 반드시 모든 이벤트 핸들러를 null로 만들어야 한다. 모든 이벤트 핸들러 프로퍼티에 null값을 할당하기만 하면 된다. 이런 기능을 필요할 때마다 혹은 purge와 같은 일반적인 함수로 만들어 실행할 수도 있다.

purge 함수는 DOM 엘리먼트를 인자로 받는다. 엘리먼트의 어트리뷰트를 루프돌면서, 함수를 찾으면 null 로 만들어 순환구조를 끊고 메모리가 교정될 수 있도록 한다. 함수는 또한 모든 하위 엘리먼트들에도 같은 작용을 해서 순환구조가 잘 제거되도록 한다. purge 함수는 모질라와 오페라에는 아무런 해가 없으며 IE에만 작용한다. purge 함수는 엘리먼트가 removeChild 메소드나 innerHTML 속성으로 삭제되기 전에 호출되어야 한다.

function purge(d) {
  var a = d.attributes, i, l, n;
    if (a) {
      l = a.length;
      for (i = 0; i < l; i += 1) {
        n = a[i].name;
        if (typeof d[n] === 'function') {
        d[n] = null;
      }
    }
  }
  a = d.childNodes;
  if (a) {
    l = a.length;
    for (i = 0; i < l; i += 1) {
      purge(d.childNodes[i]);
    }
  }
}

끝으로 세번째 프로그램 queuetest3를 실행해보자. 여기서는 DOM 엘리먼트를 삭제하기 전에 purge 함수를 호출했다.

queuetest1 : http://www.crockford.com/javascript/memory/queuetest1.html
queuetest2 : http://www.crockford.com/javascript/memory/queuetest2.html
queuetest3 : http://www.crockford.com/javascript/memory/queuetest3.html

덧글 1 :
IE에서 사용되고 있는 것은 JavaScript 를 본따 만든 JScript 입니다. MS에서 만든 JavaScript 호환 언어입니다. 대부분의 경우에는 큰 고민없이 그냥 사용하셔도 되지만 일부 문제 혹은 특성이 있으니 그 부분만 주의하시면 됩니다.

http://en.wikipedia.org/wiki/JScript

덧글 2 :
이 글에서의 순환은....
메모리 관리가 잘 안되는 JScript 와 DOM 간의 순환구조를 말합니다. JScript 함수가 DOM의 이벤트 핸들러로서 참조되고 JScript 에서는 함수 내부에 이 DOM 객체에 대한 참조를 가지고 있는 겁니다. 자세한 것은 위 링크에서 queuetest2 번의 onclick 핸들러의 함수 코드를 한번 보세요. DOM 객체를 내부에 참조하고 있음을 알 수 있습니다.



출처  : 행복한고니
신고
Trackback 0 Comment 0
2007.04.17 07:50

Prototype base multi-Selection API

자바스크립트로 구현한 Prototype.js 프레임웍 기반 다중 선택기 API를 소개합니다.(API라고 하기에는 좀 부끄럽군요) 최초 올라로그 오픈베타 프로젝트에 사용되었습니다. 데스크탑 애플리케이션 못지않은 UI를 구현하겠다는 욕심에 조금은 억척 스럽게 만들어진 녀석입니다. 유저가 익숙하지 않다는 이유로 존속여부는 희박하지만, 라이브러리 형태로 공개하고 계속 발전시켜 나가볼 생각입니다. 조금더 다듬고 기능을 확장하여 여러환경에 적용할 수 있도록 손보았습니다. 웹 특성상 컨트롤 키를 조합하는 방식이 아닌 기본으로 활성화 되어 있는 상태입니다.(추가 예정)

토글 모드
  • 01
  • 02
  • 03
  • 04
  • 05
  • 06
  • 07
  • 08
  • 09
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
Selected : --


Width: 75px
드래그 다중선택 활성 모드
  • 01
  • 02
  • 03
  • 04
  • 05
  • 06
  • 07
  • 08
  • 09
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
Selected : --


download JS : http://firejune.com/javascripts/multiselect.js
download CSS : http://firejune.com/stylesheets/multiselect.css

사용방법


적용대상이 되는 엘리먼트는 리스트 아이템(UL)의 부모이며, 부모 엘리먼트는 다중선택 활성화 영역(parent)이 됩니다. 리스트 아이탬은 고유한 ID값를 지니고 있어야 합니다.(수정됨) 드래그 사용여부와 스타일 시트에서 지정한 스타일을 별도로 설정 할 수도 있습니다, 자세한 사용방법은 아래와 같습니다.(슬라이드 바는 포지션 리셋 테스트용 입니다.)
new MultiSelect('testElement');

// CSS 시각효과 설정
new MultiSelect('testElement', {
  dragSelect: false, // 드래그 사용 여부
  rectangleCN: 'MS-rectangle', // 선택영역 스타일 이름
  selectCN: 'MS-select', // 선택된 아이탬 스타일 이름
  unselectCN: 'MS-unselect', // 선택되지 않은 아이탬 스타일 이름
}});

// 예제에 사용한 코드
var selector = new MultiSelect('testElement', {
  // 변화가 생기면 이벤트 발생
  onChange: function(){
  var debug = $('debug2'), point = '';
  debug .innerHTML = 'Selected : ';
  selector.items.each(function(a){
    if(a.success) {
       debug .innerHTML += point + a.element.innerHTML;
       point = ', ';
    }
  });
}});

selector.setOffset(true); // 포지션 다시 계산하기
selector.selectAll(true); // 모두 선택하기
selector.selectAll(false); // 모두 선택 해제하기


추후 추가될 기능


- 윈도우 컨벤션을 따르는 UI 모드 추가(컨트롤 키 조합)
- 메모리 릭현상 제거
- 더블 클릭 이벤트 추가
- 아이템의 ID값 없이도 사용할 수 있도록 수정(수정됨)
- form 엘리먼트 지원


출처 : Fire Jun's
신고
Trackback 0 Comment 0
2007.04.16 08:40

Prototype기반 벡터 그래픽 프레임웍 - PGF

Prototype Window 컴포넌트를 만든 Sebastien Gruhier씨는 프로토타입 그래픽 프레임웍(PGF)이라는 매우 흥미로운 프로젝트를 진행합니다. 모든 브라우저에서 사용할 수 있는 Prototype.js 기반 벡터(vector) 그래픽 프레임웍을 구현하는 것입니다. 이 프레임웍은 SVG(Firefox, WebKit, Opera), VML(IE), Canvas (Firefox, Safari, WebKit, Opera)등 브라우저마다 서로다른 벡터기술을 통합 사용하여 크로스-브라우즈 한다는 이론입니다.(매우 훌륭합니다!)

// Create an SVG renderer
var renderer = new SVGRenderer("whiteboard");

// Create a rectangle with some attributes like color and bounds
var rect = new Graphic.Rectangle(renderer);
rect.setFill({r: 255, g: 0, b: 0, a: 128});
rect.setStroke({r: 255, g: 255, b: 0, a: 128, w: 5});
rect.setBounds(10, 20, 200, 300);
rect.setRoundCorner(10, 10);
rect.translate(10, 20);
rect.rotate(30);

renderer.add(rect);

주목할만한 프로젝트입니다. 플래시에 대적할만한 인터넷 그래픽 솔루션이 될지도 모를일입니다. 현재 공식으로 배포한 상태는 아니지만 서브버전 트렁크에서 다운로드 가능합니다. Sebastien씨는 dojo.gfx에서 아이디어를 얻었다고 말하고 있군요. 그의 최근 프로젝트인 neomeeting에 PGF을 실제로 사용한다니 이 또한 기대해볼만합니다.

출처 : 파이어준
신고
Trackback 0 Comment 0
2007.04.13 07:58

자바스크립트가 그려낸 둥근 모서리 - Transcorners

계속해서 미루어 오다가 이제서야 소개합니다. Transcorners는 대상 엘리먼트의 모서리에 라운드(또는 대각선) 효과를 부여하는 자바스크립트 효과입니다. 가볍기로 잘 알려진 mootools 자바스크립트 프레임웍을 기반으로 만들어 졌으며, 모든 브라우저에서 사용할 수 있도록 제작되었습니다. 아래는 Transcorners 사용해서 직접 그려본 라운드 효과와 예제입니다.
    예제1
    //모든 코너에 반지름(radius) 30
    new Transcorner( 'example1', { radius: 30 });
    //background:#fee; border:1px solid #a00; 스타일 속성을 지님


    예제2
    //모든 코너에 반지름 10 (기본값)
    new Transcorner( 'example2');
    //background:#4ff; border:2px solid #4bb; 스타일 속성을 지님

    예제3
    //상단 왼쪽 코너에만 반지름 20
    new Transcorner( 'example3', 'top left', { radius: 20 });

    예제4
    //상단 코너에만 반지름 10
    new Transcorner( 'example4', 'top');

    예제5
    //상단, 하단 오른쪽에 코너에 반지름 10 라인(cornerslinear transition)
    new Transcorner( 'example5', 'top, bottom right', { transition: Effect.Transitions.linear});

보시다시피 실시간에 가까운 라운딩이 가능하며 이미지로 디자인한 라운드에 버금가는 디테일을 보여줍니다. 무엇보다도 이미지의 로드를 줄여 한결 가벼운 웹사이트를 구축할 수 있다는 것이 가장 큰 장점이라 하겠습니다. 매우 탐나는 확장기능이라 Prototype.js에서 사용할 수 있도록 포팅하였으며, 손 댄 김에 기능을 조금 확장했습니다. 1픽셀 이상인 보더의 처리가 가능하도록 하였으며(예제2와 같은 결과), 투명한 라운드를 사용할 수 있도록 했고, 어설픈 그림자 효과도 만들어 보았습니다. 잘 응용하면 드래그앤 드롭이 가능한 멋진 다이얼로그 윈도우도 만들수도 있겠습니다. 참고로, 위에서 실행 된 예제는 Prototype.js기반으로 돌린 것 입니다.

윈도우 테스트

Download Prototype base Transcorners:
transcorners.js (5.5 KB)



출처 : 파이어준

신고
Trackback 0 Comment 0
2007.04.13 07:55

정확히 말하면 ECMA 스크립트의 특징이지만 뭐… ^^

정확히 말하면 ECMA 스크립트의 특징이지만 뭐… ^^

첫번째, 객체의 생성

var arr = [];
var obj = {};
var str = "";
var arr1 = [1,2,3];
var obj1 = {prop1 : 'value1', "prop2" : 'value2'};


Object는 {} 로, Array는 []로 생성할 수 있다. object 를 생성할 때 property 의 이름은 따옴표를 따로 해주지 않아도 prop1의 경우처럼 그냥 사용할 수 있다. 하지만, 혹시라도 있을지 모르는 문제점(prop1이 변수로 선언되어있다던가 하는…)을 미리 방지하기 위해서 따옴표를 붙여주도록 하는게 좋다. 단, 충돌이 없음이 확실하다면 생략해도 무방하다.

두번째, object property의 접근

var obj = { "prop1" : "value1", "prop2" : "value2" };
alert(obj.prop1);
alert(obj["prop1"]);


. 으로 호출하는 방법, 문자열로 인덱스를 지정하는 방법. 둘 다 사용가능하다. 따라서 다음과 같은 것도 가능하다.

var i=2;
alert(obj["prop"+i]);

세번째, or 의 사용

var val = predefined_value || "value";


or 연산자로 연결된 값을 처음부터 비교해서 false와 동등하게 처리되는 값이 아니라면 반환한다. false와 동등하게 처리되는 값에는 undefined, null, 숫자0, false가 있다. 위 코드에서는 predefined_value 라는 변수가 정의되어있지 않으면 “value”이라는 값을 val 이라는 변수에 할당한다. 보통 IE와 FF의 이벤트 처리가 다른데 그럴 경우에 다음과 같이 사용하기도 한다.

function eventHandler(e) {
  var evt = e || window.event;
// ... some code
}

네번째, 괄호()의 사용

(function(str){
  alert(str);
})("str");


괄 호는 괄호안의 내용을 해석/실행해서 결과값을 리턴하는 역할이다. (1+2) 라고 하면 괄호는 1+2를 계산해 3 이라는 값을 리턴하는 것과 마찬가지라는 뜻. 따라서 위처럼 anonymous 함수를 만들어놓고 바로 실행할 수도 있게된다(괄호를 통해 함수객체가 반환되었기 때문).
____________________________________________________
추가 - 2007.3.25


아래 코멘트들을 보고 혹시 헛갈려 하시는 분들이 있을까봐 정리해드립니다.
----------------------------------------
var obj = new Object; 와
var obj = {}; 은 같은 표현입니다.

{}을 이용하면 연관배열처럼 사용할 수는 있지만 여전히 Object 타입이며, 연관배열 타입이라는 것은 존재하지 않습니다. 보는 관점에 따라서 javascript에 객체란 없으며 모두 연관배열처럼 구성되어있다는 입장도 있습니다. 마치, PHP의 클래스들이 배열로 구성된 것과 같은 이치입니다. 하지만, {}가 Object 타입의 인스턴스라는 것에는 이의가 없습니다. 있다면, 다른 분들이 말씀해주실 것으로 압니다.

제 견해로는 아무리 느슨해도 객체는 객체입니다. 유연함이 가능한 스크립트언어의 특성일 뿐, 연관배열이 아닌 동적 프로퍼티 구성이 가능한 것으로 봐야 한다는게 제 의견입니다. 자바스크립트는 내장 함수도 재정의할 수 있을 정도로 유연한 언어입니다.

참고로, PHP에서도 연관배열이 따로 존재하지만,
$inst = new Klass;
$inst->a = "bc";
$inst->b = "de";

와 같이 동적으로 프로퍼티를 생성하는게 가능합니다.
----------------------------------------
var obj = {
  "a" : "bc",
  "b" : "de",
  "f" : function() {
      alert(this.a);
  }
};
obj.f();

{}이 Object 타입이 아니라 단순한 연관배열일 뿐이라면 this 는 window 객체가 되어야 하지만 결과는 그렇지 않습니다. 위 표현은 다음과 같이 변경할 수도 있습니다.

var obj = new Object;
obj.a = "bc";
obj.b = "de";
obj.f = "function() {
    alert(this.a);
}
obj.f();

완전히 같은 경우입니다. {}은 new Object 와 같은 결과이며, {프로퍼티이름:값}은 new Object를 만들고 프로퍼티와 값을 작성해준 경우입니다. 이는 ECMA-262 문서에 나와있는 내용입니다.

따라서, {}을 연관배열 표현이라고 부르는 것은 잘못된 견해라고 봅니다. 메소드가 없다면 연관배열 혹은 해시라고 부르는 것처럼 사용할 수도 있습니다만, 그렇다고 해서 {}이 연관배열의 표현인 것은 아닙니다.

{}은 Object의 인스턴스를 생성하는 Object literal 입니다.
혹시라도 오해없으시길 바랍니다.
______________________________________

참고로, 지금 Mozilla에서 준비하고 있는 Tamarin 프로젝트에서 ECMA4 엔진을 개발중이며 이 엔진의 결과로 Javascript2 가 나옵니다. Javascript2에는 class 가 생길거라고 하는군요.

Taramin 프로젝트에 대해서 쓰다가 좀 길어져서 별도의 글로 다시 작성합니다. ^^;;


출처 : 행복한고니
신고
Trackback 0 Comment 0
2007.04.13 07:51

테이블 틀고정 스크롤

링크 #1. 테스트 페이지 입니다.
테이블 소스는 엑셀에서 txt로 저장한걸 php에서 작업해서 테이블로 만든겁니다.
텍스트 뿐이고 td는 white-space:nowarp를 줘서 줄바꿈이 없게 했습니다.

업로드한 js 파일 보시면 대충이나마 주석 달았습니다.


조금 자세한 설명...

스크롤을 하려면 몇가지 방법이 있습니다.

div 하나에 원본 테이블과, 고정행(첫줄)과 고정열이 있다면
div의 크기는 고정이고 테이블의 크기는 그것보다 더 큽니다.
고로 스크롤이 발생하는데, 이때 스크롤되어 화면(div 시야 내)에서 사라지는 고정행과 고정열의 top과 left를 scrollTop과 scrollLeft 로 조절합니다.
처음에는 이렇게 했지만, 이 방식은 흔들림이 심하더군요.
(스크롤을 밑으로 하면 고정행이 위아래로 흔들리고, 옆으로 하면 고정열이 좌우로 흔들립니다.)


그리고 완전히 삽질한 방식이 있는데...
원본 테이블만으로 작업을 합니다.
고정행의 td(혹은 tr)과 고정열의 td에 전부 class를 주고
(어차피 테이블로 만드는건 php가...)
스크롤이 될 때마다 해당 클래스의 속성을 조절합니다.

document.styleSheets[0].cssRules[0].style.margin = xxx...

이런식으로 접근해서 일단 되기는 되는데 IE였나 FF였나 둘 중 하나는 조금 어긋났었고, 게다가 각 td별로 적용되다보니 스크롤 자체가 상당히 느려졌습니다.



지금 쓴 방식은

전체 div : #sortTable {position:relative}

이 안에

테이터 div : #dataDiv {position:relative ; width:700px ; height:500px ; overflow:scroll}
고정행/열 div : #keyDiv,#rowDiv,#colDiv {position:absolute ; top:0px ; overflow:hidden}

의 4개 div가 있는 상태.

dataDiv 안에는 원본 데이터 테이블이 있고, keyDiv/rowDiv/colDiv 에는 각각의 고정부분이 있습니다.

고정된 dataDiv 안에 그보다 더 큰 크기의 dataTable가 있기 때문에 스크롤이 발생하되, 이 스크롤은 dataDiv의 스크롤이므로 다른 고정부분 div/table에는 영향을 끼치지 않습니다.
그러므로 아무리 스크롤을 해도 그보다 위에 있는(코드상 뒤에 있으므로 z-index가 높은) 고정 부분 테이블은 움직이지 않습니다.

onscroll로 상하로 스크롤시 고정열(세로축)도 상하로 움직이면 되고, 좌우로 스크롤시 고정행(가로축)도 좌우로 움직이면 됩니다.

* 고정부분의 div들이 스크롤을 가리는 것을 막기 위해 각 div의 크기를 dataDiv의 clientWidth/Height로 적용합니다.
* 그리고 테이블의 경우 너비를 지정하지 않으면 모체의 크기로 전체가 잡혀버리므로 역시 원본 테이블의 너비를 가져와서 적용
* 제목 셀(thead)이 짧아도 밑의 내용 셀이 길기 때문에, 각 제목 셀의 너비를 원본 테이블 각 셀의 너비로 적용

* td에 nowrap를 줘서 모두 한줄로 적용되고 텍스트 뿐인 테이블이기 때문에 height는 손 대지 않아도 됩니다.




스크롤 자체는 위와 같은 방식입니다.

다만 고정행/열을 만드는 것도 문제인데...

db에서 뽑아오거나 해서 php에서 처리하는 경우

<div id="sortTable">

    <div id="dataDiv">
        <table id="dataTable">
            <?php 전체 자료 테이블 생성 ?>
        </table>
    </div>

    <div id="rowDiv">
        <table id="rowTable">
            <?php 생성 : 고정시킬 행 ?>
        </table>
    </div>

    <div id="colDiv">
        <table id="colTable">
            <?php 생성 : 고정시킬 열 ?>
        </table>
    </div>

    <div id="keyDiv">
        <table id="keyTable">
            <?php 생성 : 완전 고정시킬 왼쪽 상단 부분 ?>
        </table>
    </div>

</div>

이런식으로 생성하고 나서 각각의 너비/높이를 맞춰주면 됩니다.




참고//

링크 2번은...

php가 아닌 js로 정렬하게 만들어봤습니다.
데이터를 php로 가공해서 js의 이중배열로 만들고, 이걸 정렬 시킵니다.
그리고 그 결과를 바탕으로 html 코드를 만들고 innerHTML 로 집어넣기.

아래는 정렬 함수입니다.
test[0] = ["이완용","xx","123","Z",0];
test[1] = ["김구","백범","-23","Kim",1];
test[2] = ["최익현","면암","23","Chol",2];
test[3] = ["여운형","몽양","-93","Yeo",3];

sortKey = 2;
sortMode = 1;
// 1은 정렬, -1은 역순정렬
column = test[0].length;

test.sort(sortFunc);

function sortFunc(a,b) {
    var aS = a[sortKey].toString(10).toUpperCase();
    var bS = b[sortKey].toString(10).toUpperCase();
    if(aS == bS) return a[column-1]-b[column-1];

    while(aS || bS) {
        var aS = aS.replace(/^((\-?\d*)[^\d]*)/,"");
        var aT = RegExp.$1;
        var aN = RegExp.$2;

        var bS = bS.replace(/^((\-?\d*)[^\d]*)/,"");
        var bT = RegExp.$1;
        var bN = RegExp.$2;
    
        if(aN && bN && aN != bN) {
            return (Number(aN)-Number(bN))*sortMode;
        }
        else if(aT != bT) {
            var sort2 = new Array(aT,bT);
            sort2.sort();
            return ((sort2[0] == aT)?-1:1)*sortMode;
        }
    }
}

정렬하는 배열의 각 2차배열의 sortKey 인덱스 기준 정렬...

숫자와 문자를 구분하여 정렬하되, 숫자가 가장 앞에 나올 경우 음수까지 비교.
php 에서 이 함수를 적용하려 했는데 찾아보니 배열함수 natsort와 문자열 비교 함수 strnatcmp가 있더군요.
(그런데 이건 음수 구분을 안하네요.)

그리고 각 내부 배열의 마지막 값은 데이터가 아니라 정렬 순서를 저장하게 됩니다.
그래서 다른 인덱스로 정렬을 할 때 같은 값이 되면 이전 정렬 순서를 기준으로 정렬합니다.

링크 #1. 테스트 페이지 입니다.
테이블 소스는 엑셀에서 txt로 저장한걸 php에서 작업해서 테이블로 만든겁니다.
텍스트 뿐이고 td는 white-space:nowarp를 줘서 줄바꿈이 없게 했습니다.

업로드한 js 파일 보시면 대충이나마 주석 달았습니다.


조금 자세한 설명...

스크롤을 하려면 몇가지 방법이 있습니다.

div 하나에 원본 테이블과, 고정행(첫줄)과 고정열이 있다면
div의 크기는 고정이고 테이블의 크기는 그것보다 더 큽니다.
고로 스크롤이 발생하는데, 이때 스크롤되어 화면(div 시야 내)에서 사라지는 고정행과 고정열의 top과 left를 scrollTop과 scrollLeft 로 조절합니다.
처음에는 이렇게 했지만, 이 방식은 흔들림이 심하더군요.
(스크롤을 밑으로 하면 고정행이 위아래로 흔들리고, 옆으로 하면 고정열이 좌우로 흔들립니다.)


그리고 완전히 삽질한 방식이 있는데...
원본 테이블만으로 작업을 합니다.
고정행의 td(혹은 tr)과 고정열의 td에 전부 class를 주고
(어차피 테이블로 만드는건 php가...)
스크롤이 될 때마다 해당 클래스의 속성을 조절합니다.

document.styleSheets[0].cssRules[0].style.margin = xxx...

이런식으로 접근해서 일단 되기는 되는데 IE였나 FF였나 둘 중 하나는 조금 어긋났었고, 게다가 각 td별로 적용되다보니 스크롤 자체가 상당히 느려졌습니다.



지금 쓴 방식은

전체 div : #sortTable {position:relative}

이 안에

테이터 div : #dataDiv {position:relative ; width:700px ; height:500px ; overflow:scroll}
고정행/열 div : #keyDiv,#rowDiv,#colDiv {position:absolute ; top:0px ; overflow:hidden}

의 4개 div가 있는 상태.

dataDiv 안에는 원본 데이터 테이블이 있고, keyDiv/rowDiv/colDiv 에는 각각의 고정부분이 있습니다.

고정된 dataDiv 안에 그보다 더 큰 크기의 dataTable가 있기 때문에 스크롤이 발생하되, 이 스크롤은 dataDiv의 스크롤이므로 다른 고정부분 div/table에는 영향을 끼치지 않습니다.
그러므로 아무리 스크롤을 해도 그보다 위에 있는(코드상 뒤에 있으므로 z-index가 높은) 고정 부분 테이블은 움직이지 않습니다.

onscroll로 상하로 스크롤시 고정열(세로축)도 상하로 움직이면 되고, 좌우로 스크롤시 고정행(가로축)도 좌우로 움직이면 됩니다.

* 고정부분의 div들이 스크롤을 가리는 것을 막기 위해 각 div의 크기를 dataDiv의 clientWidth/Height로 적용합니다.
* 그리고 테이블의 경우 너비를 지정하지 않으면 모체의 크기로 전체가 잡혀버리므로 역시 원본 테이블의 너비를 가져와서 적용
* 제목 셀(thead)이 짧아도 밑의 내용 셀이 길기 때문에, 각 제목 셀의 너비를 원본 테이블 각 셀의 너비로 적용

* td에 nowrap를 줘서 모두 한줄로 적용되고 텍스트 뿐인 테이블이기 때문에 height는 손 대지 않아도 됩니다.




스크롤 자체는 위와 같은 방식입니다.

다만 고정행/열을 만드는 것도 문제인데...

db에서 뽑아오거나 해서 php에서 처리하는 경우

<div id="sortTable">

    <div id="dataDiv">
        <table id="dataTable">
            <?php 전체 자료 테이블 생성 ?>
        </table>
    </div>

    <div id="rowDiv">
        <table id="rowTable">
            <?php 생성 : 고정시킬 행 ?>
        </table>
    </div>

    <div id="colDiv">
        <table id="colTable">
            <?php 생성 : 고정시킬 열 ?>
        </table>
    </div>

    <div id="keyDiv">
        <table id="keyTable">
            <?php 생성 : 완전 고정시킬 왼쪽 상단 부분 ?>
        </table>
    </div>

</div>

이런식으로 생성하고 나서 각각의 너비/높이를 맞춰주면 됩니다.




참고//

링크 2번은...

php가 아닌 js로 정렬하게 만들어봤습니다.
데이터를 php로 가공해서 js의 이중배열로 만들고, 이걸 정렬 시킵니다.
그리고 그 결과를 바탕으로 html 코드를 만들고 innerHTML 로 집어넣기.

아래는 정렬 함수입니다.
test[0] = ["이완용","xx","123","Z",0];
test[1] = ["김구","백범","-23","Kim",1];
test[2] = ["최익현","면암","23","Chol",2];
test[3] = ["여운형","몽양","-93","Yeo",3];

sortKey = 2;
sortMode = 1;
// 1은 정렬, -1은 역순정렬
column = test[0].length;

test.sort(sortFunc);

function sortFunc(a,b) {
    var aS = a[sortKey].toString(10).toUpperCase();
    var bS = b[sortKey].toString(10).toUpperCase();
    if(aS == bS) return a[column-1]-b[column-1];

    while(aS || bS) {
        var aS = aS.replace(/^((\-?\d*)[^\d]*)/,"");
        var aT = RegExp.$1;
        var aN = RegExp.$2;

        var bS = bS.replace(/^((\-?\d*)[^\d]*)/,"");
        var bT = RegExp.$1;
        var bN = RegExp.$2;
    
        if(aN && bN && aN != bN) {
            return (Number(aN)-Number(bN))*sortMode;
        }
        else if(aT != bT) {
            var sort2 = new Array(aT,bT);
            sort2.sort();
            return ((sort2[0] == aT)?-1:1)*sortMode;
        }
    }
}

정렬하는 배열의 각 2차배열의 sortKey 인덱스 기준 정렬...

숫자와 문자를 구분하여 정렬하되, 숫자가 가장 앞에 나올 경우 음수까지 비교.
php 에서 이 함수를 적용하려 했는데 찾아보니 배열함수 natsort와 문자열 비교 함수 strnatcmp가 있더군요.
(그런데 이건 음수 구분을 안하네요.)

그리고 각 내부 배열의 마지막 값은 데이터가 아니라 정렬 순서를 저장하게 됩니다.
그래서 다른 인덱스로 정렬을 할 때 같은 값이 되면 이전 정렬 순서를 기준으로 정렬합니다.


출처 : iamSeeker

신고
Trackback 1 Comment 0
2007.04.13 07:48

IE/FF(Gecko,W3C) 이벤트 설명

링크
IE와 FF에서의 이벤트 처리에 대한 설명을 정리해봤습니다. 틀린게 있을 수도 있습니다. 모질라 DOM레퍼런스에도 없는게 있어서, 그런 설명이 없을 수도 있습니다. 제가 쓸 일이 없다고 생각한건, 대충 설명되어잇을 수 있습니다.
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

IE/FF(Gecko,W3C) 이벤트 설명

IE와 FF에서 이밴트를 불러 사용하는 방법(예제)
브라우저 IE FF IE&FF
input 개체 <input onclick="fn()"> <input onclick="fn(event)"> <input onclick="fn(event)">
함수

function fn(){
alert(event.type);
}

function fn(e){
alert(e.type);
}
function fn(e){
var evt = window.event || e;
alert(evt.type);
}

설명
(예제 값은 <input> 에서 onclick 이벤트로 발생시킴)

설명 순서는 내 마음대로, 관계있는 것 끼리 엮음.
해석하기 어렵거나 이해하기 어려운건 원문과 같이 나타냈습니다.
IE value FF value 특징 설명
기능키
altKey FALSE altKey FALSE 읽기전용 키보드 ALT키가 눌러져있는가?
altLeft FALSE     읽기전용 왼쪽 ALT키가 눌러져있는가?
ctrlKey FALSE ctrlKey FALSE 읽기전용 키보드 Ctrl 키가 눌러져있는기?
ctrlLeft FALSE     읽기전용 키보드 왼쪽 Ctrl키가 눌러져있는가?
shiftKey FALSE shiftKey FALSE 읽기전용 Shift 키가 눌러져있는가?
shiftLeft FALSE     읽기전용 왼쪽 Shift 키가 눌러져있는가?
키보드/마우스
keyCode 0     읽기전용 현재 발생된 키코드(키보드에서 눌려진 키의 10진수 값)
    which 1 읽기전용 현재 발생된 키코드(키보드에서 눌려진 키의 10진수 값) & 마우스 동작
1:왼쪽마우스,2:가운데마우스,3:왼쪽마우스, 나머지값:키의 ASCII 값
    detail 1 읽기전용 click, dblclick, mousedown, or mouseup 이벤트에서만 발생, 마우스가 클릭 수를 표시, dblclick는 항상 2
  isChar FALSE 읽기전용 Returns a boolean indicating whether the event produced a key character or not.
입력된 값이 글자인지 체크
button 0 button 0 읽기전용 현재 눌려진 마우스 버튼(IE)
onmousedown, onmouseup, onmousemove 이벤트에서만 발생
(onClick에서는 0)
  IE
0 Default. No button is pressed.
1 Left button is pressed.
2 Right button is pressed.
3 Left and right buttons are both pressed.
4 Middle button is pressed.
5 Left and middle buttons both are pressed.
6 Right and middle buttons are both pressed.
7 All three buttons are pressed.

  FF  
0 for standard 'click', usually left button  
1 for middle button, usually wheel-click
 
2 for right button, usually right-click  
wheelDelta 0     읽기전용 마우스 휠의 이동량
type click type click 읽기전용 현재 발생된 이벤트 타입
    timeStamp 4108593 읽기전용 이밴트가 생성된 시간(유닉스타임)
    view [object Window] 읽기전용 The view attribute identifies the AbstractView from which the event was generated.
    metaKey FALSE   Used to indicate whether the 'meta' key was depressed during the firing of the event. On some platforms this key may map to an alternative key name.
repeat FALSE       Retrieves whether the onkeydown event is being repeated.
onkeydown이벤트에서 키입력의 반복을 허용하는가?
X/Y좌표
clientX 552 clientX 25 읽기전용 이벤트가 발생한 X위치(현재 페이지 기준)
clientY 188 clientY 392 읽기전용 이벤트가 발생한 Y위치(현재 페이지 기준)
offsetX 537     읽기전용 이벤트가 발생된 대상에서의 이벤트 발생 위치 X값
offsetY -107     읽기전용 이벤트가 발생된 대상에서의 이벤트 발생 위치 Y값
screenX 754     읽기전용 window.screen 에서 상대적 위치 X값
screenY 285     읽기전용 window.screen 에서 상대적 위치 Y값
x 552     읽기전용 현재 보이는 페이지에서의 상대적 위치 X값(스크롤 값을 계산되지 않는다)
y 188     읽기전용 현재 보이는 페이지에서의 상대적 위치 Y값(스크롤 값을 계산되지 않는다)
    layerX 26 읽기전용 Returns the horizontal coordinate of the event relative to the current layer.
레이어에서의 상대적 위치 X값
    layerY 393 읽기전용 Returns the vertical coordinate of the event relative to the current layer.
레이어에서의 상대적 위치 Y값
    pageX 25 읽기전용 Returns the horizontal coordinate of the event relative to the page.
    pageY 392 읽기전용 Returns the vertical coorindate of the event relative to the page.
이밴트 대상
fromElement null     읽기전용 이벤트가 발생된 개체(이밴트가 진행중일 때)
srcElement [object] currentTarget [object HTMLInputElement] 읽기전용 현재 이벤트가 발생된 개체
  eventPhase 2 읽기전용 Indicates which phase of the event flow is currently being evaluated.
  explicitOriginalTarget [object HTMLInputElement] 읽기전용 The explicit original target of the event. (Mozilla-specific)
toElement null     읽기전용 Sets or retrieves a reference to the object toward which the user is moving the mouse pointer.
사용자에 의한 마우스 이동으로 지못된 개체를 참조
    originalTarget [object HTMLInputElement] 읽기전용 The original target of the event, before any retargetings (Mozilla-specific).
    relatedTarget null 읽기전용 Identifies a secondary target for the event.
이벤트에 영향을 받은 2번째 대상
    target [object HTMLInputElement] 읽기전용 Returns a reference to the target to which the event was originally dispatched.
이밴트가 발생된 대상을 참조
propertyName         이벤트의 발생으로 변경되는 프로퍼티의 이름
(ex> textbox에 키가 입력되면 value 값을 가지게된다)
이밴트버블
cancelBubble FALSE cancelBubble FALSE   이벤트가 다음 이벤트처리자에 연결되는지 처리
(false:허용됨(기본값)/true:허용안됨(현재에서 이벤트는 정지))
    bubbles TRUE 읽기전용 이벤트가 버블링 되는지 표시
    cancelable TRUE 읽기전용 이벤트를 멈출 수 있는가를 표시
returnValue undefined       Sets or retrieves the return value from the event.
이벤트가 반환되는가?
true(기본) : 이 이벤트는 다른 곳에 반환된다.(이벤트가 계속)
false : 이 이벤트는 이곳에서 끝난다(이벤트가 취소)
DB관련
bookmarks null       Returns a collection of Microsoft ActiveX Data Objects (ADO) bookmarks tied to the rows affected by the current event.
(개체에 연결된 DB내역(rows)참조)
boundElements [object]       Returns a collection of all elements on the page bound to a data set.
(개체에 연결된 DB 데이터(Data Set) 참조)
dataFld       읽기전용 Sets or retrieves the data column affected by the oncellchange event.
oncellchange 이벤트로 영형을 받은 데이터 Column
dataTransfer null     Object Provides access to predefined clipboard formats for use in drag-and-drop operations.
드래그앤드롭의 동작은 제어
qualifier       Sets or retrieves the name of the data member provided by a data source object(DSO).
reason 0       Sets or retrieves the result of the data transfer for a data source object(DSO).
recordset null       Sets or retrieves from a data source object a reference to the default record set.
         
기타
  isTrusted TRUE    
    rangeOffset 0    
    rangeParent [object Text]    
nextPage     IE5.5+ nextPage 속성값은 인쇄나 인쇄 템플릿에서 다음 페이지의 위치를 나타내는 문자열이다.
contentOverflow FALSE     읽기전용 Retrieves a value that indicates whether the document contains additional content after processing the current LayoutRect object.
srcFilter null     읽기전용

onfilterchange 이벤트를 발생시킨 Filter

srcUrn       읽기전용 Retrieves the Uniform Resource Name (URN) of the behavior that fired the event.
이벤트를 발생시킨 behavior 의 주소(URN)
behaviorCookie 0       일반 HTML에 사용되지 않는다.
behaviorPart 0       일반 HTML에 사용되지 않는다.
           
FF이벤트의 메소드
    stopPropagation function stopPropagation() {[native code]}   Stops the propagation of events further along in the DOM.
이밴트의 번짐을 취소시킨다.
    getPreventDefault function getPreventDefault() {[native code]}    
    initEvent

function initEvent(){[native code]}

  Initializes the value of an Event created through the DocumentEvent interface.
이밴트가 만들어질 때 초기화 하는 메소드
    initMouseEvent function initMouseEvent() {[native code]}   Initializes a mouse event once it's been created
마우스 이밴트가 만들어 질 때 초기화 하는 메소드
    initUIEvent function initUIEvent() {[native code]}  

Initializes a UI event once it's been created
UI이벤트가 생성될 초기화 하는 메소드

    preventBubble function preventBubble() {[native code]}   Prevents the event from bubbling. This method is deprecated in favor of standard stopPropagation and is removed in Gecko
    preventCapture function preventCapture() {[native code]}   This method is deprecated in favor of standard stopPropagation and is removed in Gecko 1.9.
    preventDefault function preventDefault() {[native code]}   Cancels the event (if it is cancelable).
이밴트를 취소한다.

참고 사이트
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/objects/obj_event.asp
http://developer.mozilla.org/en/docs/DOM:event
http://koxo.com/
 
-만든이: 공대여자, mins01
http://mins01.zerock.net
mins01(at)lycos.co.kr


신고
Trackback 0 Comment 0
2007.04.12 13:26

new Object() 와 {} 의 차이에 대한 댓글정리문서

재미있는 내용이라 phpschool에서 가져왔습니다.


먼저 전 선생님이 아닙니다.
누굴 가르쳐본적도 없고, 가르치면서 일을 진행한적도 없습니다.


하지만, 고니님이 주장하는것과 제가 생각하는것이 달라,
단지, 처음부터 끝까지 거짓이 진실이 되는걸 볼수 없기 때문에 150개가 넘는 댓글을 달게 된것입니다.


어쨋든 고니님의 뜻도
-----------------------------
아뇨. 정말로 틀렸다는 것을 증명해주시기를 바라고 있습니다.
원하신다면 문서로 만들어서 대중의 심판을 받을 각오도 되어있습니다.
-----------------------------
와 같아 최대한 주관을 배제하려고 글을 올립니다.



주관이 섞인 부분은 지적해 주시면, 지우도록 하겠습니다.

만약 주관이 섞여 있다면, 위의 글들을 보시고, 해당하는 주관을 배제하시기 발바니다.


원본의 댓글들은 다음과 같습니다.

http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=52892&page=1

아래의 논쟁으로 부터 시작된거이며, 명제는 다음과 같습니다.










1. Core Object 인 Object 의 정의는 다음과 같다. (http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Object)

Object is the primitive JavaScript object type. All JavaScript objects are descended from Object. That is, all JavaScript objects have the methods defined for Object.

(주관배제하기 위해 해석하지 않습니다.)


2. new Object() 와 {} 는 Object 의 instance 를 만든다.

3. predefined Core Objects

Array Object
Boolean Object
Date Object
Function Object
Math Object
Number Object
RegExp Object
String Object

4. __proto__ 와 prototype 은 다르다.
prototype is for types, while __proto__ is the same for instances
(http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Inheritance)
(http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Property_Inheritance_Revisited:Determining_Instance_Relationships)

5. constructor 의 정의는
Specifies the function that creates an object's prototype.

6. prototype 의 정의는
prototype: Allows the addition of properties to all objects.






논쟁거리는

1. new Object() === {} 가 같다?
2. Object 가 {} 으로 만들어진다?
3. constructor 의 비교로 객체가 똑같다고 말할수 있다?
4. Object 는 Function 의 instance 이다?

입니다.






여기부터는 대화의 내용을 정리한것이라, 최대한 주관을 배제하려고 노력했습니다.


1. 고니님은 new Object() === {} 같다.
    다르다는 것을 증명을 해보라

-> {} 는 setter 와 getter 를  prefix 할때 사용한다.
    허나 new Object() 는 added later to any object at any time using 이다.

-> {} 문법이 말 그대로 Object initializer 라서지, 그게 new Object 와 {}가 다르다는 근거는 되지 못한다는 것

-> ie에서
   
    delete Object;
    alert({});                // instance return
    alert(new Object()); // error

    FF 에서는 core Object가 삭제되지 않아 위의 코드가 정상적으로 진행된다.

-> 행복한 고니님의 주장.. Jscript 이기 때문에, IE 에서만 동작하기 때문에 인정할수 없다.
-> 아래의 4번의 내용은 Firefox에서만 동작한다. 따라서 특정브라우저에서만 동작된다고, 본질은 무시하지 못한다.

-> 고니님 rhino 소스를 보여준다. 이래도 같지가 않은지를...
->
---------------------------------------------------------------------------

public static Scriptable newObjectLiteral(Object[] propertyIds,
                                          Object[] propertyValues,
                                          Context cx, Scriptable scope)
{
    Scriptable object = cx.newObject(scope);
    for (int i = 0, end = propertyIds.length; i != end; ++i) {
        Object id = propertyIds[i];
        Object value = propertyValues[i];
        if (id instanceof String) {
            ScriptableObject.putProperty(object, (String)id, value);
        } else {
            int index = ((Integer)id).intValue();
            ScriptableObject.putProperty(object, index, value);
        }
    }
    return object;
}


public final Scriptable newObject(Scriptable scope, String constructorName,
                                  Object[] args)
{
    scope = ScriptableObject.getTopLevelScope(scope);
    Function ctor = ScriptRuntime.getExistingCtor(this, scope,
                                                  constructorName);
    if (args == null) { args = ScriptRuntime.emptyArgs; }
    Object a = ctor.construct(this , scope, args);
    return ctor.construct(this, scope, args);
}

---------------------------------------------------------------------------

소스와


4단계 .
object = new Object();
function a() {
    var object = new Object();

    var tmp;
    for(var i = 0; i < arguments[i] ; ++i){
        tmp = arguments[i].split(':');
        object[tmp[0]] = tmp[1];
    }

    return object;
};

var xx  = a();
alert(xx.__proto__.__proto__);        // null
alert(object.__proto__.__proto__);  // null
alert(object.__proto__ === xx.__proto__);    // Object 는 같다.
alert(object === xx);    // false


소스를 보여주며, 4단계에 걸쳐 퀴즈로 증명.




2. Object 가 {} 으로 만들어진다?

-> ECMA 문서에 있다고 고니님 주장.
-> Object 와 instance 간의 차이를 모르는것 같아 Object 가 {} 으로 만들어진다는 내용을 찾을수 없다. 자세한 페이자와 줄번호를 알려달라함.
-> Object 는 new Object() 를 의미하는것이다. 말꼬리 잡는것으로 고니님 주장.
    (Object 클래스 자체로 이해하고 있었군요. Object 가 생성된다는 의미를 저는 Object 객체가 생성된다라고
    사용해왔고 코드를 통해 설명할 때는 분명 new Object 를 사용했었으며, 처음부터 지금까지 계속 같은 말만 하고 있습니다.비록 표현에 오해가 있을 수 있다해도 말이죠.)

-> Java 로 쓴글을 문맥만 보고 Javascript 로 이해해야 되는지에 대한 반문


3. constructor 로 객체를 비교할수 있다?

-> 행복한 고니님의 주장은
var obj1 = new Object;
var obj2 = {};
alert(obj1.constructor === obj2.constructor);

의 결과는 true입니다. 두 객체의 생성자는 완전히 똑같은 객체이며

alert(obj1.constructor === Object);

에서 보다시피 그것은 Object 이다.

-> alert(Array.constructor);
alert(Object.constructor);
alert(Function.constructor);
alert(Number.constructor);

alert(Array.constructor === Object.constructor);
alert(Array.constructor === Object.constructor);
alert(Array.constructor === Function.constructor);
alert(Array.constructor === Number.constructor);

alert(Function.prototype.constructor.constructor);
alert(Array.prototype.constructor.constructor === Function.prototype.constructor.constructor);
alert(Array.prototype.constructor.constructor === Number.prototype.constructor.constructor);
alert(Array.prototype.constructor.constructor === Object.prototype.constructor.constructor);
alert(Object.prototype.constructor.constructor === Object.prototype.constructor.constructor);
alert(Array.prototype.constructor.constructor === Array.prototype.constructor.constructor);


Array === Object === Function === Number 

모두가 같다.? 말이 되지 않는다.

-> Array === Object는 아니죠. identity도 다르고 값도 다르니까요. 하지만 "자료구조"임에는 확실
    그게 Array와 Object의 "본질" 이라 표기
    (new Object).constructor 를 하게되면 new Object 자체의 성질을 묻는 것이고,
    (new Object).constructor.constructor 를 하게되면 (new Object 타입객체라는 인스턴스)의 성질을 묻는 겁니다.
    성질은 -> 본질을 의미한다 주장.

-> 그럼 instance 간의 비교
    new Object().constructor.constructor == new Array().constructor.constructor 가 성립되는 이유가 말이 안된다.
    따라서 constructor 로 Object 를 비교하는것은 어불성설이다.

    이유는 Object가 최상위이기 때문이다.
    Object
    |
    Array - Number - String - Function ...
    으로 되어 있고 각각의 Function 이라는 chain 으로 감싸서 서로 연결되도록 구성되어 있는것입니다.

    그래서 constructor 로 객체를 비교하는것은 무리가 있다라는 것입니다.
    constructor 를 2번 비교하는것이랑 1번비교하는것이랑의 차이는 없다.


    alert(delete Function.prototype.constructor); // prototype chain 해제
    alert(new Function().constructor.constructor);  // object return
    alert(new Object().constructor.constructor);  // object return
    alert(new Array().constructor.constructor);  // object return
    alert(new Number().constructor.constructor);  // object return
    alert(new String().constructor.constructor);  // object return

    alert(String.constructor);  // object return
    alert(Function.constructor);  // object return
    alert(Object.constructor);  // object return
    alert(Array.constructor);  // object return
    alert(Number.constructor);  // object return

4. 고니님 Object 는 Function 의 instance 이다. 주장
   
   
    alert(Object.__proto__ === Function.prototype);
    alert(Object.__proto__ === Object.prototype);
    alert(Array.__proto__ === Function.prototype);
    alert(Array.__proto__ === Object.prototype);

-> __proto__ 와 prototype 이 같다고 생각하시는지 질문.

  alert(new Object().__proto__ === new Object().prototype);

  왜 위의 코드는 왜 다른지.


-> instanceof 로 고니님 반증
    delete Function.prototype.constructor;
    alert(Object instanceof Function);
    alert(Object.__proto__ === Function.prototype);
    alert(Object.__proto__ === Object.prototype);
    alert(Array.__proto__ === Function.prototype);
    alert(Array.__proto__ === Object.prototype);


-> 명제에서 __proto__ 와 prototype 은 다르다는걸 모르고 계속적으로 비교

    alert(Object.prototype.__proto__); // null -> function 의 상속이 아니다. 라는 증명

    alert(Function.prototype.__proto__.__proto__); //null
    alert(Array.prototype.__proto__.__proto__); // null
    alert(String.prototype.__proto__.__proto__); // null
    alert(Object.prototype); // object
    alert(Function.prototype.__proto__); // object
    alert(Array.prototype.__proto__); // object
    alert(String.prototype.__proto__); // object

    따라서, Object 가 최상위객체이며, function(){} 으로 prototype chain 만 구성한다.

    즉, Object 는 Function 의 instance 가 아니다.
    고로, 고니님이 주장하는 내용은 주관,고집 이다. 라고 주장





여기까지이며, 원문의 댓글과 정리된 내용이 뜻이 다름이 있으면 관련된 내용에 대해 배제하시기 바랍니다.

감사합니다.
  License
본 게시물은 LGPL을 따릅니다. [ LGPL 안내 ]

   행복한고니   07-03-29 02:48  
아.... 길다~ 수고하셨습니다.
쪽지 확인하시고 제 글도 한번 읽어주세요. ^^

______________________________________________________________

아... 그리고 __proto__ 와 생성자의prototype을 비교하는 것은 님께서 링크했던 바로 그 MDC 문서에 있는 내용입니다. MDC 문서작성자가 누군지 몰라도 잘 몰랐나보네요. ㅎㅎ

http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Property_Inheritance_Revisited:Determining_Instance_Relationships

chris와 Engineer의 관계가 인스턴스와 생성자가 아니라고 하시다면 할말 없죠 뭐... 그 고집을 누가 당하겠습니까. ^^

제 글을 다시한번 읽어보세요. 한번이라도 생성자라는 표현없이 __proto__ 와 prototype의 관계를 설명했는지... __proto__에 대해 말씀하시기 이미 오래전에 코드도 보여줬는데 뜬금없는 아래의 코드는 뭐람... -_-;;

남이 한말을 이해도 못하고
alert(new Object().__proto__ === new Object().prototype);
가 올바른 거냐고 물으시면 곤란하죠.

______________________________________________________________

나머지는 적었다가 그냥 지웁니다.

글 자체에는 관여안하려 했는데, 자신이 제 의도를 잘라먹고 이해한 것을 마치 제가 이해를 잘못 한 것처럼 적어놓아서 그 부분만 짚었습니다.

진실은 보시는 분들이 판단하시리라 믿습니다. :)
     
   숨어지내리   07-03-29 12:16  
댓글 있으리라 짐작 했습니다. ^^

-----------------------------------------------------------------------
진실은 보시는 분들이 판단하시리라 믿습니다. :)
-----------------------------------------------------------------------

제가 필히 말하고 싶습니다. 중간에 왜곡이란게 들어가지만 않다면요.. 정.말.로.!!
   피곤해   07-03-29 09:32  
좋은 정보 감사합니다.. ^^;

근데, json에 대한 설명해둔 국내 자료 같은 것은 없나요??
json 봐 두어야 하는데.. 마땅한 것이 눈에 띄지 않네요..
   oneorzero   07-03-29 11:29  
음....예전에 이런건 아니지만 다른 논쟁거리때문에 다툰(싸움?의견충돌?ㅎㅎ)기억이 있습니다.
결론은...어쨋거나 어떤결과가 나오든 기분이 나쁘지만 그만큼 많이 생각하고 알고있는걸 다시생각하는
계기가 되더군요.
   navyism   07-03-29 11:51  
뭐 잘은 모르지만 두분의 글을 참 재미있게(?) 읽고 있습니다.

제 이해가 맞다면...
이야기의 시작은 행복한고니님이 {}는 new Object를 이용하여 object를 생성한다라는 의견을 말씀하셨던 것이고, 숨어지내리님은 {}과 new Object는 다르다라는 반론을 제기하신 것 같습니다.

var obj1 = new Object;
var obj2 = {};
alert(obj1.constructor === obj2.constructor);

이에 대해 행복한고니님은 위의 예제로 생성자를 비교함으로써 서로 같다라는 것을 증명하려하셨고, ECMA-262문서를 근거로 제시하셨죠.
호기심이 생겨 ECMA-262문서를 찾아보니 아래와 같은 내용이 있었습니다.

* Semantics
The production ObjectLiteral : { } is evaluated as follows:
1. Create a new object as if by the expression new Object().
2. Return Result(1).

짧은 영어로는 {}가 new Object에 의해 객체를 생성한다라는 뜻이 맞긴 맞는 것 같습니다.
이것은 굳이 이 문서를 찾아보지 않더라도 {}의 생성자를 확인해보면 쉽게 알 수 있는 내용입니다.

function Object() {
    [native code]
}

이에 대해 숨어지내리님은 아래와 같은 예제를 알려주셨습니다.

delete Object;
alert({}); 
alert(new Object());

Object를 삭제하고도 {}는 객체를 만들어 냅니다. 결국 {}는 new Object에 의한 것이 아니다라는 것이죠.
약간 응용해보면 아래와 같이 생각해볼 수도 있습니다.

delete Array;
alert([]); 
alert(new Array());

물론 결과는 같습니다.
Array는 삭제되었지만 []는 배열을 만들어냈습니다.
생성자를 확인해보면 역시나 Array로 되어있고요.

여기서 약간 논지가 흐려지고 있는 것 같은데요...
1. {}로 만들어 진 것과 new Object로 만들어 진 것은 서로 같다/다르다.
2. {}는 new Object를 이용하여 객체를 만든다/만들지 않는다.

서로 어떤 것을 주장하고 계신걸까요?
재미있게 읽기만 하다가 잠시 헷갈려서 글을 남겨봅니다...
     
   숨어지내리   07-03-29 11:57  
ㅎㅎㅎ ^^; 고니님으로 충분합니다.

이미 제의견은 답글로 달려 있고, rhino 소스에 대한 저의 생각과 증명을
문서정리에도 포함했으니, 댓글과 정리문서를
확인해 보세요..^^

ps. 저 nalog 잘 사용하고 있는데..ㅋㅋ ^^;; 한번 뜯어봐야겠다. (농담입니다. ^^)
          
   navyism   07-03-29 13:08  
뭐 누구 편들자는 것은 아닌 것 아시죠?^^;;
               
   숨어지내리   07-03-29 13:34  
네.. ^^ 그래서 조크 날린겁니다.
          
   행복한고니   07-03-29 14:01  
증명이 안될텐데요? ^^
님이 처음에 하셨던 바로 그 실수를 또 하십니까?

아래 코드로 증명하셨다고 하셨습니다.
____________________________________
object = new Object();
function a() {
    var object = new Object();

    var tmp;
    for(var i = 0; i < arguments[i] ; ++i){
        tmp = arguments[i].split(':');
        object[tmp[0]] = tmp[1];
    }

    return object;
};

var xx  = a();
alert(xx.__proto__.__proto__);        // null
alert(object.__proto__.__proto__);  // null
alert(object.__proto__ === xx.__proto__);    // Object 는 같다.
alert(object === xx);    // false
____________________________________
identity하고 equality를 혼동하지는 않으셨으면 좋겠습니다.

object2 = new Object();
var xxx = a();

alert(object === object2);
alert(xxx === xx);

또한, 테스트 할 때는 다른 것도 해보시라고 누누히 말씀드렸었습니다. 같은 방식으로 만들어도 identity는 다릅니다. 당연한 것이 서로 다른 객체니까요. 사실 __proto__를 저런 식으로 중첩(2개 이상)해서 사용하는 것 자체에도 의미가 없기는 하지만 그 부분을 제쳐두고라도 논리가 틀렸습니다.

지금 숨어지내리님은 본인 스스로 적절하지 않은 소스라고 말씀하신 것을 다시 반복하고 계십니다.
               
   comefeel   07-03-29 14:11  
답글 그만 다세요 ..
   공대여자   07-03-29 11:59  
tip/tech 에 좋은 글 올라오는건 좋은데...
이런 글이 '포럼'에 올라가야합니다!

움.. 그런데 자바스크립트는 대부분이 객체로 알고있는데..
어쨌든 누가 결론좀.
     
   숨어지내리   07-03-29 12:14  
이것도 하나의 tip이라고 할수 있습니다.

Basic(기본)을 모르고 안다고 할수 있겠습니까? ^^

많은분들의 tip & tech 중 tip 이라고 생각하면 좋을거 같은데요..
   불친절한코더씨   07-03-29 12:31  
포럼에 올렸야하는거 같은데요.
   딸기키우자   07-03-29 13:39  
다시 시작 하시는 건가요 아래 글 1/3 정도 읽다가 포기 했슴^^;
너무나 자기주장이 강한 분들이라고 생각이 드는군요!
이런 분류의 사람들 사이에서는 결론이 잘 나질 않죠!



"이세상에 완전한것은 없다" 가 생각나는 1人

고운하루들 보내세요
   comefeel   07-03-29 14:12  
답글 그만 다세요.
   버럭오행   07-03-29 14:37  
결국 전 2시간동안 다 읽었습니다. 아 재밌네요.
나의 부족함을 느끼게해주는 글과 댓글이네요.
   BL   07-03-30 00:57  
전.. 아는게 없어서 읽어도 이해도 잘 안되지만..
아무튼 논쟁은 좋은데,
글 중간 중간에 인신공격이 들어가 있는거 같아서 보기 안타까웠습니다.
   ε♡з   07-03-30 06:37  
xx하니 xx가 맞다. 이건 하나의 이론이죠.
진실을 따지는건 '숨어지내리'님의 주장이 최상위에 있다고 자부하는겁니다.
신만이 할 수 있는걸 어찌..
언제든 자신도 틀릴수 있다는 자세가 필요할것 같네효.
잘은 모르지만 JS가 자체적으로 발전함에 따라 이론이 뒤틀려질수도 있겠죠?

‘반증가능성(Falsiability)’이 있을 때에만 진정 과학적이라고 할 수 있다. 즉, 한 주장이 틀릴 수 있음을 객관적으로 증명할 수 있을 때에만 ‘과학적’이라고 할 수 있다는 것이다. - 칼포퍼

반증가능성을 일체 무시하고 진실을 따지는건 비과학적이고 종교적입니다. ㄳㄳ
물론 fact를 따질순 있는데.. 고수분들끼리도 분분한 내용이기에.. (전 x도 몰라서 ^^ 히히)
   maggot   07-03-30 11:34  
저도 원글에 답글좀 달아볼려고 rhino 소스 보다가 comfeel 님의 중재로 포기했습니다만
ECMA 는 스펙이고, 구현은 각 벤더에 따라 달라지는거 아닐까 싶습니다
같은 스펙을 놓고도, rhino, jscript, spidermonkey 각각 미세한 차이(상용으로 확장구현된 엔진은 더 심함)가 존재할 터인데...
문제는 core object, Object, function, Function 등 각 용어에 대해 말하는 분과 듣는 분의 이해가 서로 다른 것 같다~ 라는데 있는것 같기도 합니다
여하튼 이런 논쟁이 소모적인 양상이 되기보다는 두 분의 적절한 배려로 인해 발전적인 방향이 되면 좋겠네요
     
   낭망백수   07-03-31 13:13  
지금 comfeel 님이 중재중이신 모양인가요? ^^;;;
          
   maggot   07-04-01 02:14  
달리 마땅한 단어가 없어서리...
답글달지 마세요를 두분의 논쟁이니 두분께 맡겨라는 뜻으로
저는 받아들였더랬습니다
아... 그리고 오늘이 4월 1일이니 미리 연습 좀 해 두어야 겠네요
퍼덕~ 퍼덕~
   에리카v   07-04-04 23:41  
뒤늦게 읽긴했는데.. 앞에글부터.. 사실 자바스크립트는 깊게 공부해본적이 없어서.. 참아쉽네요.
이해가 되는 내용이었다면 좋았을텐데
   치즈버거   07-04-05 15:00  
저도 글을 다 보진 않았지만..
이런 질문을 하고 싶네요
두분 각자의 주장을 기반으로 코딩을 했을때, 문제점/장점 이 있는건가요?
아니면 그저 논리적으로 '주장을 위한 주장' 인가요?
신고
Trackback 4 Comment 0


티스토리 툴바