Javascript에서 정적 변수를 작성하는 방법
답변
클래스 기반의 정적으로 유형이 지정된 객체 지향 언어 (예 : Java, C ++ 또는 C #) 에서 온 경우 인스턴스가 아닌 “유형”과 관련된 변수 또는 메소드를 작성하려고한다고 가정합니다.
생성자 함수와 함께 “클래식”접근 방식을 사용하는 예는 기본 OO JavaScript의 개념을 이해하는 데 도움이 될 수 있습니다.
function MyClass () { // constructor function
var privateVariable = "foo"; // Private variable
this.publicVariable = "bar"; // Public variable
this.privilegedMethod = function () { // Public Method
alert(privateVariable);
};
}
// Instance method will be available to all instances but only load once in memory
MyClass.prototype.publicMethod = function () {
alert(this.publicVariable);
};
// Static variable shared by all instances
MyClass.staticProperty = "baz";
var myInstance = new MyClass();
staticProperty
는 MyClass 객체 (함수)에 정의되어 있으며 생성 된 인스턴스와 관련이 없으며 JavaScript는 함수를 일급 객체 로 취급 하므로 객체 이므로 속성을 함수에 할당 할 수 있습니다.
업데이트 : ES6 은 키워드를 통해 클래스 를 선언 하는 기능을 도입했습니다 class
. 기존 프로토 타입 기반 상속에 대한 구문 설탕입니다.
static
키워드는 쉽게 클래스에 정적 속성 또는 메서드를 정의 할 수 있습니다.
ES6 클래스로 구현 된 위의 예제를 보자.
class MyClass {
// class constructor, equivalent to
// the function body of a constructor
constructor() {
const privateVariable = 'private value'; // Private variable at the constructor scope
this.publicVariable = 'public value'; // Public property
this.privilegedMethod = function() {
// Public Method with access to the constructor scope variables
console.log(privateVariable);
};
}
// Prototype methods:
publicMethod() {
console.log(this.publicVariable);
}
// Static properties shared by all instances
static staticProperty = 'static value';
static staticMethod() {
console.log(this.staticProperty);
}
}
// We can add properties to the class prototype
MyClass.prototype.additionalMethod = function() {
console.log(this.publicVariable);
};
var myInstance = new MyClass();
myInstance.publicMethod(); // "public value"
myInstance.additionalMethod(); // "public value"
myInstance.privilegedMethod(); // "private value"
MyClass.staticMethod(); // "static value"
답변
JS 함수도 객체라는 사실을 활용할 수 있습니다. 즉, 속성을 가질 수 있습니다.
예를 들어 Javascript 의 (현재 사라진) 기사 정적 변수에 제공된 예제를 인용하십시오 .
function countMyself() {
// Check to see if the counter has been initialized
if ( typeof countMyself.counter == 'undefined' ) {
// It has not... perform the initialization
countMyself.counter = 0;
}
// Do something stupid to indicate the value
alert(++countMyself.counter);
}
해당 함수를 여러 번 호출하면 카운터가 증가하는 것을 볼 수 있습니다.
그리고 이것은 전역 변수로 전역 네임 스페이스를 오염시키는 것보다 훨씬 나은 솔루션 일 것입니다.
그리고 클로저를 기반으로 한 또 다른 가능한 솔루션 이 있습니다 : javascript에서 정적 변수를 사용하는 Trick :
var uniqueID = (function() {
var id = 0; // This is the private persistent value
// The outer function returns a nested function that has access
// to the persistent value. It is this nested function we're storing
// in the variable uniqueID above.
return function() { return id++; }; // Return and increment
})(); // Invoke the outer function after defining it.
어떤 종류의 결과를 얻습니까? 이번을 제외하고는 증가 된 값이 표시되는 대신 반환됩니다.
답변
IIFE (즉시 호출 된 함수 표현식)를 통해 수행합니다.
var incr = (function () {
var i = 1;
return function () {
return i++;
}
})();
incr(); // returns 1
incr(); // returns 2
답변
arguments.callee를 사용하여 “정적”변수를 저장할 수 있습니다 (익명 함수에서도 유용함).
function () {
arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1;
arguments.callee.myStaticVar++;
alert(arguments.callee.myStaticVar);
}
답변
비슷한 답변을 두 번 보았지만 이 게시물이 가장 잘 설명되어 있다고 말씀 드리고 싶습니다.
여기에서 가져온 코드가 있습니다. 클래스의 디자인 템플릿으로 사용할 수 있기 때문에 커뮤니티에 도움이되는 완전한 예제를 얻도록 수정했습니다.
또한 귀하의 질문에 답변합니다 :
function Podcast() {
// private variables
var _somePrivateVariable = 123;
// object properties (read/write)
this.title = 'Astronomy Cast';
this.description = 'A fact-based journey through the galaxy.';
this.link = 'http://www.astronomycast.com';
// for read access to _somePrivateVariable via immutableProp
this.immutableProp = function() {
return _somePrivateVariable;
}
// object function
this.toString = function() {
return 'Title: ' + this.title;
}
};
// static property
Podcast.FILE_EXTENSION = 'mp3';
// static function
Podcast.download = function(podcast) {
console.log('Downloading ' + podcast + ' ...');
};
해당 예제가 제공되면 다음과 같이 정적 속성 / 기능에 액세스 할 수 있습니다 .
// access static properties/functions
console.log(Podcast.FILE_EXTENSION); // 'mp3'
Podcast.download('Astronomy cast'); // 'Downloading Astronomy cast ...'
그리고 객체 속성 / 기능 은 다음과 같이 간단합니다.
// access object properties/functions
var podcast = new Podcast();
podcast.title = 'The Simpsons';
console.log(podcast.toString()); // Title: The Simpsons
console.log(podcast.immutableProp()); // 123
참고 podcast.immutableProp ()에있는 것을, 우리는이 폐쇄 : _somePrivateVariable에 대한 참조가 함수 내에서 유지됩니다.
getter와 setter를 정의 할 수도 있습니다 . 이 코드 스 니펫을 살펴보십시오 ( d
속성을 선언하려는 객체의 프로토 타입 y
은 생성자 외부에서 볼 수없는 개인 변수입니다).
// getters and setters
var d = Date.prototype;
Object.defineProperty(d, "year", {
get: function() {return this.getFullYear() },
set: function(y) { this.setFullYear(y) }
});
d.year
를 통해 속성 get
과 set
함수 를 정의합니다. 를 지정하지 않으면 set
속성은 읽기 전용이며 수정할 수 없습니다 (설정하려고하면 오류가 발생하지 않지만 아무런 영향을 미치지 않습니다). 각 속성에는 속성 (선언 후 변경 가능) 및 속성 으로 열거 자로 사용할 수 있는 속성 writable
이 있습니다 configurable
( enumerable
기본값) false
. defineProperty
예를 들어 3 번째 파라미터 를 통해 설정할 수 있습니다 enumerable: true
.
유효한 것은 다음 구문입니다.
// getters and setters - alternative syntax
var obj = { a: 7,
get b() {return this.a + 1;},
set c(x) {this.a = x / 2}
};
읽기 / 쓰기 가능 속성 a
, 읽기 전용 속성 b
및 쓰기 전용 속성 을 정의하여 속성 c
에 a
액세스 할 수 있습니다.
용법:
console.log(obj.a); console.log(obj.b); // output: 7, 8
obj.c=40;
console.log(obj.a); console.log(obj.b); // output: 20, 21
노트:
new
키워드를 잊어 버렸을 때 예기치 않은 동작을 피하려면 함수에 다음을 추가하는 것이 좋습니다 Podcast
.
// instantiation helper
function Podcast() {
if(false === (this instanceof Podcast)) {
return new Podcast();
}
// [... same as above ...]
};
이제 다음 인스턴스화가 모두 예상대로 작동합니다.
var podcast = new Podcast(); // normal usage, still allowed
var podcast = Podcast(); // you can omit the new keyword because of the helper
‘new’문은 새로운 객체를 생성하고 모든 속성과 메소드를 복사합니다.
var a=new Podcast();
var b=new Podcast();
a.title="a"; b.title="An "+b.title;
console.log(a.title); // "a"
console.log(b.title); // "An Astronomy Cast"
또한 상황 return
에 따라 생성자 함수 의 명령문 을 사용 Podcast
하여 클래스가 내부적으로 의존하지만 노출되어야하는 함수를 보호하는 사용자 정의 객체를 반환하는 것이 유용 할 수 있습니다 . 이에 대해서는 기사 시리즈의 2 장 (객체)에서 자세히 설명합니다.
당신은 말할 수 a
및 b
상속 Podcast
. 지금, 당신은 이후에 모두 적용 팟 캐스트에 대한 방법을 추가하는 것을 원하는 경우 a
와 b
통해 인스턴스 한을? 이 경우 .prototype
다음을 사용하십시오 .
Podcast.prototype.titleAndLink = function() {
return this.title + " [" + this.link + "]";
};
이제 전화를 a
하고 b
다시 :
console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]"
console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]"
프로토 타입에 대한 자세한 내용은 여기를 참조 하십시오 . 더 많은 상속을 원한다면 이것을 살펴 보는 것이 좋습니다 .
기사 시리즈 내가 위에서 언급 한 적이있다 추천 읽고, 그들은 또한 다음과 같은 항목을 포함한다 :
- 기능
- 사물
- 프로토 타입
- 생성자 함수에 새로운 기능 적용
- 게양
- 자동 세미콜론 삽입
- 정적 속성 및 방법
참고 것을 자동 세미콜론 삽입 (6.에서 언급 한) 자바 스크립트의 “기능”매우 자주 코드에서 이상한 문제의 원인에 대한 책임이있다. 따라서 기능보다는 버그로 간주합니다.
자세한 내용을 보려면 여기 에 이러한 주제에 대한 흥미로운 MSDN 기사 가 있으며 그중 일부는 더 자세한 내용을 제공합니다.
무엇이다 읽는 재미 (또한 주제는 위에서 언급 한 커버)로부터 그 기사입니다뿐만 아니라 MDN 자바 스크립트 가이드 :
JavaScript 에서 c # out
매개 변수 를 에뮬레이트 하는 방법을 알고 싶다면 여기에서 샘플 코드를DateTime.TryParse(str, out result)
찾을 수 있습니다.
당신의 그들을 IE 작업 (사용 개발자 도구를 엽니 다하지 않는 자바 스크립트에 대한 콘솔이없는 F12다음을 찾을 수 콘솔 탭을 엽니 다)는 유용 니펫을. console.log(msg);
위의 예에서 사용 된 대로 사용할 수 있습니다 . Podcast
기능 전에 삽입하십시오 .
편의를 위해 하나의 완전한 단일 코드 스 니펫에 위의 코드가 있습니다.
노트:
-
JavaScript 프로그래밍에 대한 몇 가지 유용한 팁, 힌트 및 권장 사항은 일반적으로 여기 (JavaScript 모범 사례) 와 여기 ( ‘var’대 ‘let’)에서 찾을 수 있습니다. 또한 암시 적 타입 캐스트 (강제)에 대한 이 기사도 권장됩니다 .
-
클래스를 사용하고 JavaScript로 컴파일하는 편리한 방법은 TypeScript입니다. 작동 방식을 보여주는 예제를 찾을 수 있는 놀이터 가 있습니다. 현재 TypeScript를 사용하지 않더라도 TypeScript를 JavaScript 결과와 나란히 볼 수 있기 때문에 살펴볼 수 있습니다. 대부분의 예제는 간단하지만 즉시 시도 할 수있는 Raytracer 예제도 있습니다. 특히 “클래스 사용”, “상속 사용”및 “제네릭 사용”예제를 콤보 상자에서 선택하여 살펴 보는 것이 좋습니다. JavaScript에서 즉시 사용할 수있는 멋진 템플릿입니다. Typescript는 Angular 와 함께 사용됩니다 .
-
JavaScript에서 로컬 변수, 함수 등을 캡슐화 하려면 다음과 같은 패턴을 사용하는 것이 좋습니다 (JQuery는 동일한 기술을 사용함).
<html>
<head></head>
<body><script>
'use strict';
// module pattern (self invoked function)
const myModule = (function(context) {
// to allow replacement of the function, use 'var' otherwise keep 'const'
// put variables and function with local module scope here:
var print = function(str) {
if (str !== undefined) context.document.write(str);
context.document.write("<br/><br/>");
return;
}
// ... more variables ...
// main method
var _main = function(title) {
if (title !== undefined) print(title);
print("<b>last modified: </b>" + context.document.lastModified + "<br/>");
// ... more code ...
}
// public methods
return {
Main: _main
// ... more public methods, properties ...
};
})(this);
// use module
myModule.Main("<b>Module demo</b>");
</script></body>
</html>
물론, 스크립트 코드를 별도의 *.js
파일 에 넣을 수 있습니다 . 이것은 예제를 짧게 유지하기 위해 인라인으로 작성되었습니다.
자체 호출 기능 (IIFE = 즉시 호출 된 함수 표현이라고도 함)은 여기에보다 자세히 설명되어 있습니다 .
답변
function Person(){
if(Person.count == undefined){
Person.count = 1;
}
else{
Person.count ++;
}
console.log(Person.count);
}
var p1 = new Person();
var p2 = new Person();
var p3 = new Person();
답변
업데이트 된 답변 :
에서 ECMAScript를 6 , 당신은 사용하여 정적 함수 만들 수 있습니다 static
키워드 :
class Foo {
static bar() {return 'I am static.'}
}
//`bar` is a property of the class
Foo.bar() // returns 'I am static.'
//`bar` is not a property of instances of the class
var foo = new Foo()
foo.bar() //-> throws TypeError
ES6 클래스는 정적에 대한 새로운 의미를 도입하지 않습니다. ES5에서 다음과 같이 동일한 작업을 수행 할 수 있습니다.
//constructor
var Foo = function() {}
Foo.bar = function() {
return 'I am static.'
}
Foo.bar() // returns 'I am static.'
var foo = new Foo()
foo.bar() // throws TypeError
Foo
JavaScript 함수는 객체이므로 속성에 할당 할 수 있습니다 .