JavaScript의 숨겨진 기능? [닫은]


312

모든 프로그래머가 알아야 할 JavaScript의 "숨겨진 기능"은 무엇입니까?

다음 질문에 대한 답변의 우수한 품질을 본 후 JavaScript를 요청할 때가되었다고 생각했습니다.

자바 스크립트가 현재 가장 중요한 클라이언트 측 언어 임에도 불구하고 (Google에 물어보기 만해도) 대부분의 웹 개발자가 얼마나 강력한 지 알고있는 것은 놀라운 일입니다.


1
"이 다른 질문에 대한 담당자의 의견과 견해를 보았을 때, 나는 내 자신을 높이기 위해 거의 똑같은 질문을 할 것이라고 생각했다"고 말하지 않았습니까? ;-)
Bobby Jack

1
물론 비관론자. :) 나는 이것을 커뮤니티 질문으로 만드는 것을 고려했다. 또한 특정 수의 포인트를 얻은 후에는 모두 수익이 감소합니다.
Allain Lalonde

1
충분히 공평합니다-그것은 당신이 담당자를 '필요'하는 것처럼 보이지 않습니다! 나는 C # one에 큰 문제가 있다고 생각합니다.이 사이트가 의도 한 질문 유형과 정확히 같지는 않습니다.
Bobby Jack

3
예, 아닐 수도 있지만 답변의 지식이 훌륭하다는 것을 알았습니다. SO가 아닌 경우 평균 C # 프로그래머를 한곳에서 모든 곳에 노출시키기가 어려울 것이라고 생각합니다. 같은 하드 원리스트를 만들려면 몇 년이 걸렸습니다.
Allain Lalonde

7
저는 10 년 동안 전문적으로 JavaScript를 작성해 왔으며이 스레드에서 한두 가지를 배웠습니다. 고마워, 앨런!
앤드류 헤지스

답변:


373

함수에 매개 변수를 정의 할 필요는 없습니다. 함수의 arguments배열과 같은 객체를 사용할 수 있습니다 .

function sum() {
    var retval = 0;
    for (var i = 0, len = arguments.length; i < len; ++i) {
        retval += arguments[i];
    }
    return retval;
}

sum(1, 2, 3) // returns 6

117
비록 인수가 배열처럼 작동하지만 실제 자바 스크립트 배열이 아니라 객체 일뿐입니다. 따라서 join (), pop (), push (), slice () 등을 수행 할 수 없습니다. (원하는 경우 "var argArray = Array.prototype.slice.call (arguments);")
Jacob Mattison

51
Arguments 객체에 액세스하는 것이 상대적으로 비싸다는 점에 주목할 가치가 있습니다. 가장 좋은 예는 Safari, Firefox 및 Chrome 야간에 있으며 arguments객체를 참조하는 것만 으로 함수 호출이 훨씬 느려집니다. if (false) 인수; 성능을 손상시킬 수 있습니다.
olliej

48
같은 맥락에서 인수는 현재 함수 자체 인 "callee"속성을 갖습니다. 익명의 기능으로 재귀를 할 수 있습니다.
Vincent Robert

4
@Nathan "f (x, y, z)"는 "f ([x, y, z])"보다 낫습니다.
Mark Cidade

16
@Vincent Robert : arguments.callee더 이상 사용되지 않습니다.
ken

204

Douglas Crockford의 훌륭한 책 JavaScript : The Good Parts 의 대부분을 인용 할 수 있습니다 . 있습니다.

하지만, 당신을 위해 하나 할게요 항상 사용 ===하고 !==대신 ==하고!=

alert('' == '0'); //false
alert(0 == ''); // true
alert(0 =='0'); // true

==전이되지 않습니다. 사용 ===하면 예상대로 이러한 모든 진술에 대해 거짓을 줄 것입니다.


29
많은 사람들이 Crockford가 모든 것을 알고 있다고 생각하는 것은 부끄러운 일입니다. 부여, ... 사람은 바로 그의 비판의 대부분과 마크에 있지만 나는 짧은 많은 DEVS처럼 자신의 물건 담요 승인을주는 중지 할
제이슨 멧새

21
제이슨의 경고가 두 번째입니다. 그 자체로이 책은 아주 재미있다, 그것은 좋은 조언을 많이 준다, 그러나 DC가되어 지금까지 너무 일을 자신의 방법이 유일한 올바른 방법이라고 확신, 다른 모든 "결함"입니다. 몇 가지 예를 원한다면 JSLint Yahoo Group에 대한 그의 답변을보십시오.
Zilk

30
동적 타이핑으로 혼동되고 "실제로"동일하게하려면 == 대신 ===를 사용하는 것이 좋습니다. 동적 타이핑을 이해하는 사람들은 0 == ''또는 0 == '0'과 같이 캐스팅하려는 상황에서 계속 ==를 사용할 수 있습니다.
thomasrutter

20
글쎄 ==와 ===는 동적 타이핑에 관한 것이 아닙니다. == 다른 유형의 짐승 인 유형 강제 변환을 수행합니다. 알고 있다면 문자열 / 숫자 / 등으로 캐스트하려는 경우 명시 적으로 수행해야합니다.
Rene Saarsoo 2016 년

15
나는 가장 무서운 부분은 생각 ==입니다 '\n\t\r ' == 0=> trueD : ...
Shrikant Sharat

189

함수는 JavaScript에서 일류 시민입니다.

var passFunAndApply = function (fn,x,y,z) { return fn(x,y,z); };

var sum = function(x,y,z) {
  return x+y+z;
};

alert( passFunAndApply(sum,3,4,5) ); // 12

함수형 프로그래밍 기술을 사용하여 우아한 자바 스크립트 작성 .

특히 함수는 매개 변수로 전달 될 수 있습니다. 예를 들어 Array.filter () 는 콜백을 허용합니다.

[1, 2, -1].filter(function(element, index, array) { return element > 0 });
// -> [1,2]

특정 함수의 범위 내에서만 존재하는 "비공개"함수를 선언 할 수도 있습니다.

function PrintName() {
    var privateFunction = function() { return "Steve"; };
    return privateFunction();
}

3
자바 스크립트에서 함수를 만드는 방법에는 세 가지가 있습니다. function sum (x, y, z) {return (x + y + z); } 및 var sum = new Function ( "x", "y", "z", "return (x + y + z);"); 다른 방법입니다.
Marius

6
함수형 데이터의 개념은 필자의 책에서 분명히 큰 포인트를 얻습니다.
Jason Bunting

방금 샘플을 업데이트하여 특정 함수 범위 내에서만 존재하는 "비공개"함수를 사용하는 방법을 보여주었습니다.
Chris Pietschmann

new Function()만큼 악하다 eval. 사용하지 마세요.
Nicolás

11
이것이 숨겨진 기능인지는 확실하지 않습니다. 핵심 기능과 비슷합니다.
Claudiu

162

in 연산자를 사용하여 객체에 키가 있는지 확인할 수 있습니다 .

var x = 1;
var y = 3;
var list = {0:0, 1:0, 2:0};
x in list; //true
y in list; //false
1 in list; //true
y in {3:0, 4:0, 5:0}; //true

객체 리터럴이 너무 추한 경우이를 매개 변수가없는 함수 팁과 결합 할 수 있습니다.

function list()
 { var x = {};
   for(var i=0; i < arguments.length; ++i) x[arguments[i]] = 0;
   return x
 }

 5 in list(1,2,3,4,5) //true

22
그렇게 영리하지는 않지만 키가 있는지 확인하고 값이 있는지 확인합니다. 목록에있는 x; 값 1이 없기 때문에 x [1]! = null이기 때문에 작동합니다.
Armin Ronacher

1
나는이 기술을 사용하지 않았으므로 실제로 객체 리터럴을 사용했음을 잊었습니다. 수정 해 주셔서 감사합니다.
Mark Cidade

34
또한주의하십시오 : in 연산자는 프로토 타입 체인도 테스트합니다! 누군가가 Object.prototype에 '5'라는 속성을 넣은 경우 두 번째 예제는 list (1, 2, 3, 4) '에서'5를 호출하더라도 true를 반환합니다 ... hasOwnProperty를 사용하는 것이 좋습니다 메소드 : list (1, 2, 3, 4) .hasOwnProperty (5)는 Object.prototype에 '5'속성이 있더라도 false를 반환합니다.
Martijn 2016 년

3
가장 일반적인 솔루션의 경우, 이름이 "hasOwnProperty"인 경우에도 Object에 고유 한 속성이 있는지 테스트 할 수있는 방법은 다음과 같습니다. Object.prototype.hasOwnProperty.call (object, name) ;
Kris Kowal

1
@Kris, 누군가 Object.prototype.hasOwnProperty를 덮어 쓰지 않는 한)
Nick

153

변수에 기본값 지정

||대입 식에서 논리 또는 연산자 를 사용하여 기본값을 제공 할 수 있습니다 .

var a = b || c;

a변수의 값을 얻을 것이다 c경우 만 b입니다 falsy (경우 null, false, undefined, 0, empty string, 또는 NaN), 그렇지 않은 경우 a의 값을 얻을 것이다b .

이것은 제공되지 않는 경우 인수에 기본값을 지정하려는 경우 함수에서 유용합니다.

function example(arg1) {
  arg1 || (arg1 = 'default value');
}

이벤트 핸들러의 IE 대체 예 :

function onClick(e) {
    e || (e = window.event);
}

다음과 같은 언어 기능이 오랫동안 우리와 함께 있었으며 모든 JavaScript 구현이이를 지원하지만 ECMAScript 5th Edition 까지는 사양의 일부가 아닙니다 .

debugger

설명 : § 12.15 디버거 문

이 문장을 사용하면 다음 과 같이 코드에 프로그래밍 방식 으로 중단 점 을 넣을 수 있습니다 .

// ...
debugger;
// ...

디버거가 있거나 활성 상태이면 해당 줄에서 바로 중단됩니다.

그렇지 않으면 디버거가 없거나 활성화되어 있으면이 명령문은 관찰 가능한 효과가 없습니다.

여러 줄 문자열 리터럴

설명 : § 7.8.4 문자열 리터럴

var str = "This is a \
really, really \
long line!";

당신은 조심해야 캐릭터 때문에 옆에 \ 있어야 당신은 뒤에 공백이있는 경우, 라인 종결 될 \예를 들어, 코드는 것 보면 정확히 같은,하지만이 인상됩니다 SyntaxError.


28
null 인 경우, false로 간주되는 경우는 아닙니다. a = 0 || 42; 이것은 당신에게 42를 줄 것입니다. 이것은 파이썬이나 C #이 아닌 것과 비슷합니다 ?? 운영자. C # 동작을 원하면 a = (b === null)? c : b;
Armin Ronacher 2018 년

ASP.NET에서 개발하는 경우 Visual Studio에서도 작동합니다. :)
chakrit

2
나는 적절한 || 정의되지 않은 경우에만. 오버로드 된 메소드의 에뮬레이션을 만들고 싶었 기 때문에 오늘이 0에 물 렸습니다. 마지막 인수가 선택적이고 기본값이 대신 사용됩니다.
egaga

이 트릭은 +1 기본 Google 웹 로그 분석 스 니펫에서 활용합니다. `var _gaq = _gaq || [];`; 지나치게 열성적인 사용자가 자신의 작업을 덮어 쓰는 것을 방지합니다.
Yahel

2
여러 줄 문자열 리터럴 기술에 대해 몰랐습니다. 정말 환상적입니다. 감사합니다.
Charlie Flowers

145

JavaScript에는 블록 범위가 없습니다 (하지만 클로저가 있으므로 호출해도됩니까?).

var x = 1;
{
   var x = 2;
}
alert(x); // outputs 2

3
좋은 것입니다. 대부분의 C와 같은 언어와는 정말 중요한 차이점입니다.
Martin Clarke

9
항상 "var tmp = function () {/ * block scope * /} ();"을 수행 할 수 있습니다. 구문은 추악하지만 작동합니다.
Joeri Sebrechts

3
또는 Firefox 전용 인 경우 "let"을 사용할 수 있습니다. stackoverflow.com/questions/61088/…
Eugene Yokota

10
또는 그냥 : (function () {var x = 2;}) (); 경보 (x의 유형); // undefined
Pim Jager

@Pim : JSLint의 말 : "함수를 포함하는 Parens로 호출을 이동하십시오.". " 'function'과 '('.) 사이에 정확히 하나의 공백이
있어야합니다

144

[]대신에 객체 속성에 액세스 할 수 있습니다.

이를 통해 변수와 일치하는 속성을 찾을 수 있습니다.

obj = {a:"test"};
var propname = "a";
var b = obj[propname];  // "test"

이 이름을 사용하여 이름이 유효한 식별자가 아닌 객체 속성을 가져 오거나 설정할 수 있습니다.

obj["class"] = "test";  // class is a reserved word; obj.class would be illegal.
obj["two words"] = "test2"; // using dot operator not possible with the space.

어떤 사람들은 이것을 알고 사용하게하지 평가 () A는이 같은, 정말 나쁜 생각을 :

var propname = "a";
var a = eval("obj." + propname);

이것은 읽기가 어렵고 (jslint를 사용할 수 없음) 오류를 찾기가 어렵고 실행 속도가 느리고 XSS 악용으로 이어질 수 있습니다.


평가하지만, 거의 필요 악
더그 Domeny

나는 eval을 사용하지 않으며 이것을 발견했을 때를 기억합니다. 그것은 나를 매우 행복하게 만들었습니다.

요약하면, 점과 첨자 표기법을 통해 객체 속성에 액세스 할 수 있습니다.
Russ Cam

9
점 참조는 실제로 bracketref의 구문 설탕이라는 점에 주목하는 것이 흥미 롭습니다. foo.bar어쨌든 사양에 따르면 다음과 같이 동작 foo["bar"]합니다. 또한 모든 것이 문자열 속성이라는 점에 유의하십시오. 배열 액세스를 수행하더라도 array[4], 4는 문자열로 변환됩니다 (적어도 ECMAScript v3 사양에 따름)
Claudiu

모든 JS 프로그래머가 이것을 알아야한다고 생각합니다.
Cem Kalyoncu 2016 년

144

특정 주제에 대해 알맞은 JavaScript 참조를 검색하려면 검색어에 "mdc"키워드를 포함 시키십시오. 첫 번째 결과는 Mozilla 개발자 센터에서 얻은 것입니다. 오프라인 참조 나 책을 가지고 다니지 않습니다. 나는 항상 "mdc"키워드 트릭을 사용하여 내가 원하는 것을 직접 얻습니다. 예를 들면 다음과 같습니다.

Google : 자바 스크립트 배열 정렬 mdc
(대부분의 경우 '자바 스크립트'를 생략 할 수 있음)

업데이트 : Mozilla Developer Center의 이름이 Mozilla Developer Network 로 변경되었습니다 . "mdc"키워드 트릭은 여전히 ​​작동하지만 머지 않아 "mdn"사용시작 해야 할 수도 있습니다 .


50
와, 훌륭한 자원. 엉터리 w3schools보다 즉시 더 나은 ...
DisgruntledGoat

11
Firefox를 사용하는 경우 Google에 문의하지 않아도됩니다. 주소 표시 줄에 "array mdc"를 입력하고 Enter 키를 누르십시오.
Sasha Chedygov

2
가장 중요한 부분은이 스택 오버플로 질문이 결과의 첫 페이지에
어떻게 나타나는지입니다.)

5
propo this : promotejs.com , Google 검색 결과에서 MDC 결과를 더욱 높이기위한 풀뿌리 SEO 이니셔티브.
Yahel

3
이제 MDN 문서 센터이므로 'mdc'키워드는 여전히 유효합니다 :)
Aleadam

143

어쩌면 어떤 사람들에게는 조금 분명 할 것입니다 ...

Firebug를 설치 하고 console.log ( "hello")를 사용하십시오. 임의의 alert ();을 사용하는 것보다 훨씬 낫습니다. 몇 년 전 많은 일을 기억합니다.


12
Firebug가 설치되지 않은 다른 사람에게 코드를 공개하기 전에 콘솔 명령문을 제거하는 것을 잊지 마십시오.
Chris Noe

161
function log (msg) {if (console) console.log (msg) else alert (msg)}
Josh

4
더 나은 방법은 로그 문장 앞에 ';;;' 그리고 최소화는 당신을 위해 그것을 처리합니다. (적어도, 내가 사용하는 Perl 모듈은 그 기능을 가지고 있으며 그것이 일반적이라고 주장합니다.)
Kev

10
Josh : 콘솔이 정의되어 있지 않아 작동하지 않습니다. typeof console! == "undefined"또는 window.console을 확인할 수 있습니다.
Eli Gray

23
항상 포함 : if (typeof ( 'console') == 'undefined') {console = {log : function () {}}; } 그런 다음 console.log를 계속 사용할 수 있으며 아무 것도 수행하지 않습니다.
gregmac

120

개인 방법

객체는 전용 메소드를 가질 수 있습니다.

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;

    // A private method only visible from within this constructor
    function calcFullName() {
       return firstName + " " + lastName;    
    }

    // A public method available to everyone
    this.sayHello = function () {
        alert(calcFullName());
    }
}

//Usage:
var person1 = new Person("Bob", "Loblaw");
person1.sayHello();

// This fails since the method is not visible from this scope
alert(person1.calcFullName());

16
그것은 실제로 개인 함수가 아닙니다-로컬 범위에서 더 많은 함수 변수입니다.
Keith

6
사실이지만 모든 운영 정의에 따르면 그 방법이라고 생각할 수 있습니다. 인스턴스 상태에 액세스 할 수 있으며 해당 인스턴스에서만 볼 수있는 이름을 가진 코드 블록입니다. 개인 메소드에 대한 정의는 무엇입니까?
Allain Lalonde

14
@Zach, 정확히! 수년간 클래스 기반 OO 언어로 작업 한 후 OO 개념을 구현 한 것임을 잊기 쉽습니다. 물론, 준 클래스 기반의 OO를 JS에 넣는 다양한 라이브러리도 도움이되지 않습니다.
Shog9

5
궁금한 점은 person1에 법률 블로그가 있습니까? ;-)
트래비스

4
체포 된 개발 참조 +1
Domenic

99

또한 Crockford의 "자바 스크립트 : 좋은 부분"에 언급되어 있습니다.

parseInt()위험합니다. 적절한 밑줄을 알리지 않고 문자열을 전달하면 예기치 않은 숫자가 반환 될 수 있습니다. 예를 들어 parseInt('010')10이 아닌 8을 반환합니다. 기본을 parseInt에 전달하면 제대로 작동합니다.

parseInt('010') // returns 8! (in FF3)
parseInt('010', 10); // returns 10 because we've informed it which base to work with.

13
코드 검토를 수행 할 때는 항상이 코드를 찾으십시오. ", 10"을 생략하는 것은 대부분의 테스트에서 눈에 띄지 않는 일반적인 실수입니다.
Doug Domeny

나는 몇 년 전에 기수 문제에 화상을 입었고 그처럼 반 직관적 인 것을 잊어 버린 적이 없습니다. 잠시 동안 궁금해 할 것이므로 지적해야 할 것이 좋습니다.
JamesEggers

4
왜 사용하지 Math.floorNumber? 10 === Math.floor("010"); 10 === Number("010");수레 :42 === Math.floor("42.69"); 42.69 === Number("42.69");
단지 누군가

1
@Infinity 게시 된 답변이 아닌 경우해야합니다. 내장 함수 동작을 재정의하는 것만 큼 간단하지는 않았습니다. 물론 다른 사이트에서 빌린 코드 패키지를 좀 더 자세히 살펴 봐야합니다. 그 무해한 parseInt기능은 쉽게 무해 하지 않은 일을하도록 만들 수 있습니다.
bob-the-destroyer

6
@Infinity : fn을 재정 의하여 '코딩 오류'를 강조 표시하는 것은 어떻습니까? __parseInt = parseInt; parseInt = function (str, base) { if (!base) throw new Error(69, "All your base belong to us"); return __parseInt(str, base); }
JBR 윌킨슨

97

함수는 객체이므로 속성을 가질 수 있습니다.

fn = 함수 (x) {
   // ...
}

fn.foo = 1;

fn.next = 기능 (y) {
  //
}

13
이것은 매우 유용한 팁입니다. 예를 들어, 기본값을 함수의 속성으로 설정할 수 있습니다. 예를 들면 다음과 같습니다. myfunc.delay = 100; 그런 다음 사용자는 기본값을 변경할 수 있으며 모든 함수 호출은 새로운 기본값을 사용합니다. 예를 들면 다음과 같습니다. myfunc.delay = 200; myfunc ();
BarelyFitz 2016 년

유용하고 위험합니다!
palswim

조잡 해 보입니다. 왜 변수 대신 이것을 사용합니까?
instantsetsuna

1
@instantsetsuna : 왜 또 다른 별도의 변수가 있습니까? 평소와 같이 이것은 "적절하고 유용한 경우에 사용하기"로 귀결됩니다. ;-)
VolkerK

91

자체 실행 기능을 말해야합니다.

(function() { alert("hi there");})();

Javascript 에는 블록 범위가 없으므로 로컬 변수를 정의하려는 경우 자체 실행 기능을 사용할 수 있습니다.

(function() {
  var myvar = 2;
  alert(myvar);
})();

여기서는 myvar전역 범위를 방해하거나 오염시키지 않으며 함수가 종료되면 사라집니다.


2
이것이 유용한 무엇입니까? 함수 외부에 경고를두면 동일한 결과가 나타납니다.
감자 엔지니어

7
경고에 관한 것이 아니라 함수를 한 번에 정의하고 실행하는 것입니다. 자체 실행 함수가 값을 반환하고 함수를 매개 변수로 다른 함수에 전달하도록 할 수 있습니다.
ScottKoon

5
@Paul 캡슐화에 좋습니다.
Mike Robinson

22
블록 범위 지정에도 좋습니다.
Jim Hunziker

24
예, 모든 .js파일을 익명의 자체 실행 기능으로 묶고 전역 적으로 액세스 할 수있는 모든 것을 window객체에 첨부 합니다. 글로벌 네임 스페이스 오염을 방지합니다.
cdmckay 2009

83

함수가 예상하는 매개 변수 수를 알 수 있습니다

function add_nums(num1, num2, num3 ){
    return num1 + num2 + num3;
}
add_nums.length // 3 is the number of parameters expected.

함수가 얼마나 많은 매개 변수를 수신하는지 파악

function add_many_nums(){
    return arguments.length;
}    
add_many_nums(2,1,122,12,21,89); //returns 6

23
첫 번째 부분에 대해 전혀 몰랐습니다. 좋은!
mcjabberz

1
마찬가지로 함수가 몇 개의 인수를 기대하는지 알 수 있습니다 function.length.
Xavi

6
답변의 첫 번째 부분 인
@Xavi

79

다음은 흥미로운 것들입니다.

  • 비교 NaN(심지어 아무것도하는 NaN) 포함하는, 항상 false입니다 ==, <하고 >.
  • NaN 숫자가 아님을 나타내지 만 유형을 요청하면 실제로 숫자를 반환합니다.
  • Array.sort 비교기 함수를 사용할 수 있으며 퀵 정렬과 같은 드라이버에 의해 호출됩니다 (구현에 따라 다름).
  • 정규식 "상수"는 마지막으로 일치 한 것과 같이 상태를 유지할 수 있습니다.
  • 자바 스크립트의 일부 버전에서 액세스를 허용 $0, $1, $2정규식에 대한 회원.
  • null다른 것과는 다릅니다. 객체, 부울, 숫자, 문자열 또는도 아닙니다 undefined. "alternate"와 비슷합니다 undefined. (참고 : typeof null == "object")
  • 가장 바깥 맥락에서 this 이 지정되지 않은 [Global] 객체를 생성합니다.
  • 로 변수 선언 var 자동 선언에 의존하지 선언하면 런타임에서 해당 변수에 대한 액세스를 최적화 할 수 있습니다
  • 그만큼 with구조는 optimzations을 파괴 할 것이다
  • 변수 이름에는 유니 코드 문자가 포함될 수 있습니다.
  • JavaScript 정규식은 실제로 정규적이지 않습니다. 그것들은 Perl의 정규 표현식을 기반으로하며 평가하는 데 매우 오랜 시간이 걸리는 lookaheads를 사용하여 표현식을 구성 할 수 있습니다.
  • 블록을 라벨로 지정하고의 대상으로 사용할 수 있습니다 break. 루프의 레이블을 지정하고 대상으로 사용할 수 있습니다 continue.
  • 배열이 희박하지 않습니다. 비어있는 배열의 1000 번째 요소를 설정하면로 채워 져야합니다 undefined. (구현에 따라 다름)
  • if (new Boolean(false)) {...}{...}블록 을 실행합니다
  • Javascript의 정규 표현식 엔진은 구현에 따라 다릅니다. 예를 들어 "휴대 불가능"정규 표현식을 작성할 수 있습니다.

[좋은 의견에 대한 답변으로 조금 업데이트되었습니다. 의견을 참조하십시오]


5
null은 실제로 (특별한) 객체입니다. typeof null"객체"를 반환합니다.
Ates Goral

4
다음과 같은 곳에서 [Global] 객체를 얻을 수도 있습니다. var glb = function () {return this; } ();
Zilk

2
브라우저에서 자바 스크립트의 전역 객체는 윈도우 객체입니다. 전역 범위에있을 때 : window.a == a;
Pim Jager 2016 년

8
"배열은 드물지 않습니다"는 구현에 따라 다릅니다. a [1000]의 값을 설정하고 a [999]를 보면 그렇습니다 undefined. 그러나 존재하지 않는 인덱스를 찾을 때 얻는 기본값입니다. a [2000]을 체크 undefined했다하더라도 이것이 메모리이지만 아직 메모리를 할당 한 것은 아닙니다. IE8에서는 당시 JScript 엔진의 느낌에 따라 일부 배열이 밀도가 높고 일부 배열이 희박합니다. 자세한 내용은 여기 읽기 : blogs.msdn.com/jscript/archive/2008/04/08/...
크리스 닐슨

2
@Ates 및 @SF : typeof는 다양한 유형의 "개체"를 반환합니다. 그러나 작동 방식과 유형이 "객체"로 식별되는 것을 알고 나면 구현에서 적어도 안정적이며 일관성이 있습니다.
thomasrutter

77

나는 파티에 늦었다는 것을 알고 있지만, +"숫자를 숫자로 변환"을 넘어서서 운영자의 유용성이 언급되지 않았다는 것을 믿을 수 없다 . 어쩌면 그것은 기능이 얼마나 숨겨져 있습니까?

// Quick hex to dec conversion:
+"0xFF";              // -> 255

// Get a timestamp for now, the equivalent of `new Date().getTime()`:
+new Date();

// Safer parsing than parseFloat()/parseInt()
parseInt("1,000");    // -> 1, not 1000
+"1,000";             // -> NaN, much better for testing user input
parseInt("010");      // -> 8, because of the octal literal prefix
+"010";               // -> 10, `Number()` doesn't parse octal literals 

// A use case for this would be rare, but still useful in cases
// for shortening something like if (someVar === null) someVar = 0;
+null;                // -> 0;

// Boolean to integer
+true;                // -> 1;
+false;               // -> 0;

// Other useful tidbits:
+"1e10";              // -> 10000000000
+"1e-4";              // -> 0.0001
+"-12";               // -> -12

물론, 당신은 Number()대신 에이 모든 것을 할 수 있지만, +운영자는 훨씬 더 예쁘다!

프로토 타입의 valueOf()메서드를 재정 의하여 개체의 숫자 반환 값을 정의 할 수도 있습니다 . 해당 객체에서 수행 된 숫자 변환은을 발생시키지 NaN않지만 valueOf()메소드 의 반환 값은 다음과 같습니다.

var rnd = {
    "valueOf": function () { return Math.floor(Math.random()*1000); }
};
+rnd;               // -> 442;
+rnd;               // -> 727;
+rnd;               // -> 718;

당신은 간단하게 할 수 없다 0xFF, 등의 필요를 +"0xFF".
nyuszika7 시간

9
@ Nyuszika7H : 다른 프리미티브와 객체 숫자로 강제하는 요점을 놓치고 있습니다. 물론 대신 0xFF쓸 수있는 것과 거의 같은 방식으로 글을 쓸 수 있습니다 . 나는 당신이 사용할 수있는 제안1+true+("0x"+somevar)parseInt(somevar, 16)원하는 경우 의 대안으로 .
Andy E

75

" 자바 스크립트의 확장 방법 프로토 타입 속성을 통해".

Array.prototype.contains = function(value) {  
    for (var i = 0; i < this.length; i++) {  
        if (this[i] == value) return true;  
    }  
    return false;  
}

contains모든 Array객체에 메소드 가 추가 됩니다. 이 구문을 사용하여이 메소드를 호출 할 수 있습니다

var stringArray = ["foo", "bar", "foobar"];
stringArray.contains("foobar");

18
다른 코드 (귀하의 코드가 아닌)가 Array 객체에 대해 가정 할 수 있기 때문에 이것은 일반적으로 나쁜 생각으로 간주됩니다.
Chris Noe

39
일반적으로 Array 객체에 대해 가정하는 것은 나쁜 생각으로 간주됩니다. :(
eyelidlessness

흠 .. 자바 스크립트 1.6 배열 엑스트라? indexOf? 종을 울리는가?
Breton

2
@Breton : Array 클래스에만 국한된 것이 아니라 단지 예일뿐입니다. 이것을 사용하여 새로운 Date (). toString ()을 확장합니다. 마스크 문자열을 사용할 수 있습니다. 모든 객체를 확장 할 수 있으며 모든 인스턴스가 새로운 메소드를 얻습니다.
Esteban Küber 2016 년

1
@Mathias : 이것은 DOM에 관한 것이 아닙니다.
고인돌

60

객체에서 속성을 올바르게 제거하려면 속성을 undefined로 설정하는 대신 속성을 삭제해야합니다 .

var obj = { prop1: 42, prop2: 43 };

obj.prop2 = undefined;

for (var key in obj) {
    ...

prop2 특성 은 여전히 ​​반복의 일부입니다. 완전히 없애고 싶다면prop2 하려면 대신 다음을 수행해야합니다.

delete obj.prop2;

속성을 반복 할 때 prop2 속성 이 더 이상 나타나지 않습니다.


3
delete 문에 브라우저 별 특징이없는 것은 아닙니다. 예를 들어 IE에서 시도하고 객체가 기본 JS 객체가 아닌 경우 (자신이 추가 한 속성을 삭제할 때도) 큰 오류가 발생하여 실패합니다. delete myvar에서와 같이 변수를 삭제하기위한 것도 아닙니다. 하지만 일부 브라우저에서는 작동한다고 생각합니다. 위 답변의 코드는 꽤 안전 해 보입니다.
thomasrutter

그건 그렇고, undefined도 변수가 될 수 있습니다! var undefined = "something"시도
Johann Philipp Strathausen 2012

57

with.

거의 사용되지 않고 솔직하게도 거의 사용되지 않습니다 ... 그러나 제한된 상황에서는 용도가 있습니다.

예를 들어, 객체 리터럴은 객체 에서 속성을 빠르게 설정하는 데 매우 편리 합니다. 그러나 기존 객체의 속성 중 절반 을 변경해야하는 경우 어떻게해야 합니까?

var user = 
{
   fname: 'Rocket', 
   mname: 'Aloysus',
   lname: 'Squirrel', 
   city: 'Fresno', 
   state: 'California'
};

// ...

with (user)
{
   mname = 'J';
   city = 'Frostbite Falls';
   state = 'Minnesota';
}

Alan Storm은 이것이 다소 위험 할 수 있다고 지적합니다. 컨텍스트로 사용 된 개체 에 할당 된 속성 중 하나 가없는 경우 외부 범위에서 해결되어 전역 변수를 만들거나 덮어 쓸 수 있습니다. 기본 또는 빈 값을 가진 속성이 정의되지 않은 객체에서 작업하기 위해 코드를 작성하는 데 사용하는 경우 특히 위험합니다.

var user = 
{
   fname: "John",
// mname definition skipped - no middle name
   lname: "Doe"
};

with (user)
{
   mname = "Q"; // creates / modifies global variable "mname"
}

따라서 with그러한 과제 에 대한 진술 의 사용을 피하는 것이 좋습니다 .

참조 : 자바 스크립트의 문 "을"에 대한 합법적 인 사용이 있습니까?


29
문장에 대한 일반적인 지혜는 피해야한다. 사용자 객체에 언급 한 속성 중 하나가 없으면 with 블록의 의사 범위 외부의 변수가 수정됩니다. 그런 식으로 버그가 있습니다. yuiblog.com/blog/2006/04/11/with-statement-considered-harmful
Alan Storm

1
이의 제기는 철자가 틀린 변수에 관한 것이 아니라 코드 블록을 살펴보고 해당 블록의 특정 행이 무엇인지 확실하게 말할 수 있다는 것입니다. Javascript 객체는 매우 동적이기 때문에 현재 어떤 속성 / 멤버인지 확실하게 말할 수 없습니다.
Alan Storm

2
아멘-내가 찾은 JS에서 "with"문장을 본다면, 그것을 제거하고 그것을 사용하는 것이 왜 그것이 "숨겨진 기능"이 아닌지를 알기 위해 그것을 쓴 개발자에게 질문 할 것이다. "이상한 기능"과 비슷합니다.
Jason Bunting

1
보다 복잡한 체인 abcd "with with (abc) {d.foo = bar;}는 강력하고 본질적으로 오류가 발생하지 않습니다. 핵심은 루트를 한 수준 높이고 변수 이름의 철자를 잘못 쓰는 것입니까? 당신이 할 경우 그 어디든지 상관없이 "을"의, 해.
annakata

4
Douglas Crockford는 최근 "with"는 .NET Rocks에서 JavaScript의 최악의 부분 중 하나라고 말했습니다! 팟 캐스트.
핵심

51

작업하도록 설계된 유형이 아닌 객체에서 메서드 (또는 함수)를 호출 할 수 있습니다. 이것은 사용자 정의 객체에서 기본 (빠른) 메소드를 호출하는 데 좋습니다.

var listNodes = document.getElementsByTagName('a');
listNodes.sort(function(a, b){ ... });

이 코드 listNodesArray

Array.prototype.sort.apply(listNodes, [function(a, b){ ... }]);

이 코드 listNodes는에서 사용할 배열과 같은 속성 (길이, [] 연산자)을 충분히 정의하기 때문에 작동 합니다 sort().


43

프로토 타이 상속 (Douglas Crockford에 의해 대중화 됨)은 Javascript의 많은 것들에 대해 생각하는 방식을 완전히 혁신시킵니다.

Object.beget = (function(Function){
    return function(Object){
        Function.prototype = Object;
        return new Function;
    }
})(function(){});

살인자 야! 거의 아무도 그것을 사용하지 않는 것이 유감입니다.

다른 객체에 대한 (실제) 프로토 타입 상속 링크를 유지하면서 객체의 새 인스턴스를 "얻고"확장 할 수 있습니다. 예:

var A = {
  foo : 'greetings'
};  
var B = Object.beget(A);

alert(B.foo);     // 'greetings'

// changes and additionns to A are reflected in B
A.foo = 'hello';
alert(B.foo);     // 'hello'

A.bar = 'world';
alert(B.bar);     // 'world'


// ...but not the other way around
B.foo = 'wazzap';
alert(A.foo);     // 'hello'

B.bar = 'universe';
alert(A.bar);     // 'world'

42

어떤 사람들은 이것을 맛의 문제라고 부르지 만,

aWizz = wizz || "default";
// same as: if (wizz) { aWizz = wizz; } else { aWizz = "default"; }

삼항 연산자는 구성표처럼 작동하도록 연결될 수 있습니다 (조건 ...).

(cond (predicate  (action  ...))
      (predicate2 (action2 ...))
      (#t         default ))

로 쓸 수 있습니다 ...

predicate  ? action( ... ) :
predicate2 ? action2( ... ) :
             default;

부작용없이 코드를 분기하므로 매우 "기능적"입니다. 따라서 대신 :

if (predicate) {
  foo = "one";
} else if (predicate2) {
  foo = "two";
} else {
  foo = "default";
}

당신은 쓸 수 있습니다:

foo = predicate  ? "one" :
      predicate2 ? "two" :
                   "default";

재귀와도 잘 작동합니다 :)


나는 당신이주는 술어 구문을 좋아합니다. 나는 그렇게 체인을 생각하지 않았습니다. 산뜻한.
Allain Lalonde

2
어 ... JavaScript에는 switch () 문이 있습니다. :-)
staticsan 2016 년

나는 스위치 문을 좋아하지 않습니다. 그것들은 함수형 프로그래밍이 아니라 C의 인공물입니다. 필자의 예제에서 switch 문은 여전히 ​​"foo ="로 시작하는 세 개의 별도 명령문이 필요합니다.
Andrey Fedorov

14
나는 삼항 연산자를 환영합니다.
thomasrutter

8
다시 읽을 때, 이것이 "코드를 다른 언어처럼 보이게"하는 것이 아니라 실제로 코드의 의미 적 의미를 단순화한다는 것을 지적하고 싶습니다. "foo를 세 가지 중 하나로 설정하십시오" things ","if "가 아니라"foo = ... "로 시작해야하는 문장입니다.
Andrey Fedorov

41

숫자도 객체입니다. 따라서 다음과 같은 멋진 작업을 수행 할 수 있습니다.

// convert to base 2
(5).toString(2) // returns "101"

// provide built in iteration
Number.prototype.times = function(funct){
  if(typeof funct === 'function') {
    for(var i = 0;i < Math.floor(this);i++) {
      funct(i);
    }
  }
  return this;
}


(5).times(function(i){
  string += i+" ";
});
// string now equals "0 1 2 3 4 "

var x = 1000;

x.times(function(i){
  document.body.innerHTML += '<p>paragraph #'+i+'</p>';
});
// adds 1000 parapraphs to the document

세상에! toString (radix)에 대해 몰랐습니다.
Ates Goral

1
그 구현은 times비효율적입니다. Math.floor매번 한 번이 아니라 매번 호출됩니다.
고인돌

33

JavaScript에서 클로저 (C # v2.0 +의 익명 메소드와 유사)는 어떻습니까 ? 함수 또는 "표현식"을 작성하는 함수를 작성할 수 있습니다.

폐쇄 예 :

//Takes a function that filters numbers and calls the function on 
//it to build up a list of numbers that satisfy the function.
function filter(filterFunction, numbers)
{
  var filteredNumbers = [];

  for (var index = 0; index < numbers.length; index++)
  {
    if (filterFunction(numbers[index]) == true)
    {
      filteredNumbers.push(numbers[index]);
    }
  }
  return filteredNumbers;
}

//Creates a function (closure) that will remember the value "lowerBound" 
//that gets passed in and keep a copy of it.
function buildGreaterThanFunction(lowerBound)
{
  return function (numberToCheck) {
    return (numberToCheck > lowerBound) ? true : false;
  };
}

var numbers = [1, 15, 20, 4, 11, 9, 77, 102, 6];

var greaterThan7 = buildGreaterThanFunction(7);
var greaterThan15 = buildGreaterThanFunction(15);

numbers = filter(greaterThan7, numbers);
alert('Greater Than 7: ' + numbers);

numbers = filter(greaterThan15, numbers);
alert('Greater Than 15: ' + numbers);

1
확실하지 않지만 (numberToCheck> lowerBound)를 반환 할 수 있습니까? 허위 사실; 단순히 반환됩니다 (numberToCheck> lowerBound); 내 이해를 높이려고 노력하는 중 ...
davidsleeps

4
C #의 익명 함수는 클로저와 동일하지만 다른 방법은 아닙니다 :)
vava

11
클로저와 익명 함수는 분리 된 별개의 개념입니다. 명명되지 않은 함수는 익명 함수를 갖습니다. '만들기'범위의 변수가 생성 된 함수와 연결되어 있다는 것은 폐쇄입니다. 간단히 말해 클로저는 숨겨진 전역 변수와 비슷합니다.
slebetman

1
사실입니다. 익명 메소드가 작성 범위에서 변수를 사용하는 경우에만 클로저와 유사합니다. 답변에 영어를 업데이트했습니다. 그것은 여전히 ​​바람직한 것을 남기고 있지만 올바른 영어를 구하기가 어렵습니다.
Tyler

2
나는 이것이 클로저가 무엇인지 이해하는 것이 가장 좋고 가장 쉬운 것이라고 생각하지 않습니다. 그냥 말하면 폐쇄의 요점은 많은 변수가 '범위를 벗어난'것처럼 보일지라도 원래 해당 범위 내에 정의 된 함수에서 계속 사용할 수 있다는 것입니다. 위의 예에서 외부 함수 buildGreaterThanFunction이 종료 된 경우에도 익명의 내부 함수로 lowerBound 변수에 액세스 할 수 있습니다.
thomasrutter

32

암시 된 프로토 타입 체인 spoon16을 사용하여 클래스를 확장 (상속)하고 속성 / 방법재정의 할 수도 있습니다 .

다음 예제에서는 Pet 클래스를 만들고 몇 가지 속성을 정의합니다. 또한 Object에서 상속 된 .toString () 메서드를 재정의합니다.

그런 다음 Pet확장하고 .toString () 메서드를 재정 의하여 동작 (다형성)을 다시 변경 하는 Dog 클래스를 만듭니다 . 또한 자식 클래스에 다른 속성을 추가합니다.

그런 다음 상속 체인을 검사하여 Dog가 여전히 Dog 유형, Pet 유형 및 Object 유형임을 보여줍니다.

// Defines a Pet class constructor 
function Pet(name) 
{
    this.getName = function() { return name; };
    this.setName = function(newName) { name = newName; };
}

// Adds the Pet.toString() function for all Pet objects
Pet.prototype.toString = function() 
{
    return 'This pets name is: ' + this.getName();
};
// end of class Pet

// Define Dog class constructor (Dog : Pet) 
function Dog(name, breed) 
{
    // think Dog : base(name) 
    Pet.call(this, name);
    this.getBreed = function() { return breed; };
}

// this makes Dog.prototype inherit from Pet.prototype
Dog.prototype = new Pet();

// Currently Pet.prototype.constructor
// points to Pet. We want our Dog instances'
// constructor to point to Dog.
Dog.prototype.constructor = Dog;

// Now we override Pet.prototype.toString
Dog.prototype.toString = function() 
{
    return 'This dogs name is: ' + this.getName() + 
        ', and its breed is: ' + this.getBreed();
};
// end of class Dog

var parrotty = new Pet('Parrotty the Parrot');
var dog = new Dog('Buddy', 'Great Dane');
// test the new toString()
alert(parrotty);
alert(dog);

// Testing instanceof (similar to the `is` operator)
alert('Is dog instance of Dog? ' + (dog instanceof Dog)); //true
alert('Is dog instance of Pet? ' + (dog instanceof Pet)); //true
alert('Is dog instance of Object? ' + (dog instanceof Object)); //true

이 질문에 대한 답 은 Ray Djajadinata훌륭한 MSDN 기사 에서 수정 한 코드 였습니다.


31

유형에 따라 예외가 발생할 수 있습니다. MDC 에서 인용 :

try {
   myroutine(); // may throw three exceptions
} catch (e if e instanceof TypeError) {
   // statements to handle TypeError exceptions
} catch (e if e instanceof RangeError) {
   // statements to handle RangeError exceptions
} catch (e if e instanceof EvalError) {
   // statements to handle EvalError exceptions
} catch (e) {
   // statements to handle any unspecified exceptions
   logMyErrors(e); // pass exception object to error handler
}

참고 : 조건부 catch 절은 ECMAScript 사양에 포함되지 않은 Netscape (및 Mozilla / Firefox) 확장이므로 특정 브라우저를 제외하고는 신뢰할 수 없습니다.


29
나는 그것을 도울 수 없었다 : 붙잡기 (당신이 할 수 있으면 나에게)
Ates Goral

6
인용 한 MDC 페이지에서 참고 사항을 읽으십시오. 조건부 캐치 절은 ECMAScript 사양의 일부가 아닌 Netscape (및 Mozilla / Firefox) 확장이므로 특정 브라우저를 제외하고는 신뢰할 수 없습니다.
Jason S

31

내 머리 꼭대기에서 ...

기능

arguments.callee는 "arguments"변수를 호스팅하는 함수를 나타내므로 익명 함수를 재귀하는 데 사용할 수 있습니다.

var recurse = function() {
  if (condition) arguments.callee(); //calls recurse() again
}

다음과 같이하려는 경우에 유용합니다.

//do something to all array items within an array recursively
myArray.forEach(function(item) {
  if (item instanceof Array) item.forEach(arguments.callee)
  else {/*...*/}
})

사물

객체 멤버에 대한 흥미로운 점 : 이름으로 문자열을 가질 수 있습니다.

//these are normal object members
var obj = {
  a : function() {},
  b : function() {}
}
//but we can do this too
var rules = {
  ".layout .widget" : function(element) {},
  "a[href]" : function(element) {}
}
/* 
this snippet searches the page for elements that
match the CSS selectors and applies the respective function to them:
*/
for (var item in rules) {
  var elements = document.querySelectorAll(rules[item]);
  for (var e, i = 0; e = elements[i++];) rules[item](e);
}

String.split 은 정규 표현식을 매개 변수로 사용할 수 있습니다.

"hello world   with  spaces".split(/\s+/g);
//returns an array: ["hello", "world", "with", "spaces"]

String.replace 는 정규 표현식을 검색 매개 변수로 사용하고 함수를 대체 매개 변수로 사용할 수 있습니다.

var i = 1;
"foo bar baz ".replace(/\s+/g, function() {return i++});
//returns "foo1bar2baz3"

당신이 언급 한 것들 ... 그들은 모든 브라우저에서 구현됩니까?
cllpse

4
아니요. 모자이크에는 대부분 부족합니다.
jsight

2
자바 스크립트 기능은 모든 주요 브라우저 (IE6 / 7, FF2 / 3, Opera 9+, Safari2 / 3 및 Chrome)에서 구현됩니다. document.querySelectorAll이 아직 모든 브라우저에서 지원되는 것은 아닙니다 (JQuery의 $ () W3C 버전 및 프로토 타입의 $$ () 임)
Leo

6
arguments.calleeECMAScript 5에서는 더 이상 사용되지 않으며 throw 및 예외가 발생합니다.
Hello71

사실이 아닙니다. 객체 키는 "hasOwnProperty"라는 문자열을 이름으로 사용할 수 없으며 내장 객체 메소드를 무시합니다.
Breton

29

대부분의 경우 스위치 대신 객체를 사용할 수 있습니다.

function getInnerText(o){
    return o === null? null : {
        string: o,
        array: o.map(getInnerText).join(""),
        object:getInnerText(o["childNodes"])
    }[typeis(o)];
}

업데이트 : 사전에 비효율적 인 평가 사례에 대해 우려하는 경우 (프로그램 설계 초기에 효율성에 대해 걱정하는 이유는 무엇입니까 ??) 다음과 같이 할 수 있습니다.

function getInnerText(o){
    return o === null? null : {
        string: function() { return o;},
        array: function() { return o.map(getInnerText).join(""); },
        object: function () { return getInnerText(o["childNodes"]; ) }
    }[typeis(o)]();
}

이것은 스위치 나 객체보다 타이핑 (또는 읽기)하기가 더 쉽지만 아래 주석 섹션에 자세히 설명 된 스위치 대신 객체를 사용하는 이점을 유지합니다. 이 스타일은 또한 일단 충분히 자라면 이것을 적절한 "클래스"로 돌리는 것이 더 간단합니다.

update2 : ES.next에 대해 제안 된 구문 확장을 사용하면 다음과 같습니다.

let getInnerText = o -> ({
    string: o -> o,
    array: o -> o.map(getInnerText).join(""),
    object: o -> getInnerText(o["childNodes"])
}[ typeis o ] || (->null) )(o);

3
이것이 파이썬이 switch 문을 사용하지 않는 방법입니다.
outis

2
문제는 항상 모든 경우를 평가한다는 것입니다.
Kornel

@porneL 이것은 사실이지만 몇 가지 이점을 제공합니다. 논리적으로 더 깨끗합니다. 사례는 해시 테이블에서 조회되는 문자열이며 각각이 true를 반환 할 때까지 각 항목이 동일한 지 평가해야합니다. 따라서 더 많은 "값"이 평가되는 동안 더 적은 "키"가 평가됩니다. 개체는 동적으로 생성 및 추후 확장 성을 위해 수정 될 수 있으며 UI 인쇄 또는 문서 생성에 반영되며 동적 "조회"기능으로 대체 될 수도 있습니다.이 기능은 사례를 복사 / 붙여 넣기하는 것보다 낫습니다. 나누기, 넘어짐 또는 기본값에 대한 혼동이 없습니다. JSON 직렬화 가능 ...
Breton

@porneL 아, 그리고 다시 한번 확장 성을 위해, 객체는 외부 구성이나 데이터 파일로 쉽게 분리 될 수 있습니다. 와.
Breton

이것이 늦은 항목이라는 것을 알고 있지만 사용자 정의 유형 검사 논리가 없다면 배열이 언제 예제와 함께 작동합니까? var arr = []; typeof arr; // object
keeganwatkins

25

객체의 속성을 반복 할 때 hasOwnProperty 메소드 를 사용해야합니다 .

for (p in anObject) {
    if (anObject.hasOwnProperty(p)) {
        //Do stuff with p here
    }
}

이는 anObject직접 속성 에만 액세스 하고 프로토 타입 체인에있는 속성은 사용하지 않도록하기위한 것입니다.


23

공용 인터페이스를 가진 전용 변수

자체 호출 기능 정의와 함께 깔끔한 작은 트릭을 사용합니다. 리턴 된 오브젝트 내부의 모든 것은 공용 인터페이스에서 사용 가능하고 다른 모든 것은 개인용입니다.

var test = function () {
    //private members
    var x = 1;
    var y = function () {
        return x * 2;
    };
    //public interface
    return {
        setx : function (newx) {
            x = newx;
        },
        gety : function () {
            return y();
        }
    }
}();

assert(undefined == test.x);
assert(undefined == test.y);
assert(2 == test.gety());
test.setx(5);
assert(10 == test.gety());

1
이것은 yuiblog.com/blog/2007/06/12/module-pattern 에서 Eric Miraglia에 의해 불린 것처럼 모듈 패턴이라고 불리며, 이름이 잘못되었다고 생각합니다. 또한 'this'객체를 사용하여 공개 메소드가 다른 공개 메소드를 호출 할 수 있다고 덧붙일 수도 있습니다. 코드에서 항상이 패턴을 사용하여 일을 체계적이고 깨끗하게 유지합니다.
mikeycgto
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.