2012-06-15 3 views
7

이전에 'JavaScript 라이브러리 만들기'를 읽는 방법을 읽었으며이 코드를 통해 제 머리카락을 찢어 내고 싶습니다. 여기 이러한 코드 조각은 어떻게 정확하게 기능합니까?

은 노트에 내 머리를 가지고 코드입니다 :

if (window === this) { 
    return new _(id); 
} 

_ (ID)이이 코드가 포함 된 단지 함수 이름입니다. 코드의 나머지 부분은 직접 살펴 봐야합니다.

function _(id) { 

// About object is returned if there is no 'id' parameter 
var about = { 
    Version: 0.5, 
    Author: "Michael Jasper", 
    Created: "Fall 2010", 
    Updated: "23 November 2011" 
}; 

if (id) { 

    // Avoid clobbering the window scope: 
    // return a new _ object if we're in the wrong scope 
    if (window === this) { 
     return new _(id); 
    } 

    // We're in the correct object scope: 
    // Init our element object and return the object 
    this.e = document.getElementById(id); 
    return this; 
    } else { 
    // No 'id' parameter was given, return the 'about' object 
    return about; 
    } 
}; 

이전에 '새로운 기능 돌아 가기'는 본 적이 없지만 어떻게 작동하는지 이해하고 싶습니다.

코드의 다른 부분 :

_.prototype = { 
    hide: function() { 
      this.e.style.display = 'none'; 
      return this; 
    } 

    show: function() { 
      this.e.style.display = 'inherit'; 
      return this; 
    } 
}; 

이 코드가 _ 객체에 새로운 메소드를 추가하는 것을 알고 있지만 왜 그들은 '이 반환'합니까? 나는 그것을하지 않고 그것을 잘 작동했습니다.

마지막 한가지는, 기사의 링크는 http://www.mikedoesweb.com/2012/creating-your-own-javascript-library/

+0

? 어쩌면 그 뒤에 뭔가를 추가 할 수 있을까요? 그냥 추측 – Anonymous

+6

'return this'는'magic(). do(). stuff() '에서처럼 체인을 가능하게합니다. –

+0

예, 체인을 의미하는 것은 jquery와 비슷하지만 jquery는 좀 더 복잡하고 많은 객체를 반환합니다. – Anonymous

답변

16

코드의 첫 번째 비트가 본질적으로 "생성자"함수가 호출되었는지를 감지하려고 ...

자바 스크립트에서, 당신은 두 가지 방법으로 객체를 생성하는 함수를 사용할 수 있습니다

function _(id) { 
    this.someProperty = "stuff"; 
    //Do more stuff to "this" 
    return this; 
} 

//in this scenario, the "this" object will be the window object 
var myObject = _(id); 
console.log(window.someProperty); //outputs "stuff"; 
console.log(myObject.someProperty); //outputs "stuff"; 

//in this scenario, the "this" object is what get's actually returned... 
var myObject = new _(id); 
console.log(window.someProperty); //outputs "undefined" 
console.log(myObject.someProperty); //outputs "stuff" 

따라서

if (window === this) { 
    return new _(id); 
} 

에 대한 검사가 실수로 new 키워드없이 생성자를 호출하지 않도록하기 위해 단순히있다. 이것은 객체에 할당 할 속성이 즉시 window 네임 스페이스에 할당되므로 나쁘다. 두 번째 질문에 대한 같은


, 저자는이 편리하고 좋은 찾고 객체 조작을 가능하게하는 fluent interface design pattern

각 방법의 끝에 return this;을 사용하고 있습니다. 이것의 일반적인 예는 jQuery를, 어디 수있는 하나의 객체 위에 체인 방법 ...

$(".some-css-selector").click(function() { 
    ... do something to the selected objects during the "click" event 
}).keyup(function() { 
    ... do something to the same objects during the "keyup" event 
}); 

편집 : 더글라스에서

아래 W3Geek의 의견에 대 한 응답에서 좀 더 자세한 내용은 Crockford의 저서 "Javascript : The Good Parts"(JS로 들어가면 좋은 읽기 ... 70 페이지 만 있지만 모두 읽을 가치가있다).


자바 스크립트의 new 연산자는 피연산자의 프로토 타입 멤버에서 상속하는 새로운 객체를 생성 한 다음 this에 새 개체를 바인딩, 피연산자를 호출합니다.이렇게하면 피연산자 (생성자 함수 여야 함)가 요청자에게 반환되기 전에 새 객체를 사용자 정의 할 수 있습니다.

`new 연산자를 사용하는 것을 잊어 버리면 대신 일반 함수 호출을 얻게되며이 객체는 새 객체가 아닌 전역 객체에 바인딩됩니다. 즉, 새 멤버를 초기화하려고 할 때 함수가 전역 변수를 clawbering합니다. 그건 아주 나쁜 것입니다.

...

생성자는 new 접두사로 사용하도록 설계 기능입니다. new 접두어는 함수의 프로토 타입을 기반으로 새 객체를 만들고 해당 객체를 this 매개 변수와 함축 된 함수에 바인딩합니다. new 접두어를 사용하지 않으면 새 개체가 만들어지지 않고 this은 전역 개체에 바인딩됩니다. 이것은 심각한 실수입니다.


+0

그래서 기본적으로 'this'는 잘못 사용하면 전역 범위가 오염되고 'check'는 그 일이 일어나지 않도록 방지하기 위해 배치됩니다. 내 질문은 무엇입니까 창 네임 스페이스가 잘못 되었습니까? 나는이 나쁜 방법에 대해 많이 보지만 결코 그런 이유는 없습니다. – W3Geek

+0

이 맞습니다. "window"객체에 속성을 추가하는 것은 좋지 않습니다. 왜냐하면 거기에 접근 할 수있는 (그리고 USE IT) 많은 다른 프레임 워크가 있기 때문입니다 ... 예를 들어, 사람들은'window.location.href' 객체 (현재 URL 귀하의 브라우저의) 항상 새로운 페이지로 "이동"... 모든 갑자기 귀하의'_' 개체에 위치 속성을 추가하면, 그것은 완전히 window.location 속성을 clobber 것입니다 ... 일반적으로 자신의 네임 스페이스에서 제어하고있는 것들을 넣어 부작용이 없음을 확인하십시오. –

+2

참고 : [전역 네임 스페이스에 변수를 "누설하는] 여기에 약간의 응답이있는 것 같습니다 (http :// /stackoverflow.com/questions/5951228/what-is-meant-by-leaking-into-global-scope). 일반적으로 댓글에 적합하지 않은 많은 토론이 있습니다. –

6

return this 당신에게 체인 메서드 호출 할 수있는 기능을 제공합니다. 당신은 _.show().hide()과 같은 정말로 시원하고 유용한 것들을 할 수 있습니다. :)