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.floor나 Number? 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){ ... });

이 코드 listNodes는Array

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.