Javascript에서 정적 변수를 작성하는 방법
someFunc = () => { MyClass.myStaticVariable = 1; }
. 그런 다음 정적 메소드를 작성하여 정적 멤버를 리턴하십시오 (예 :) static getStatic() { return MyClass.myStaticVariable; }
. 그런 다음 MyClass.getStatic()
클래스 외부에서 호출 하여 정적 데이터를 유지할 수 있습니다!
Javascript에서 정적 변수를 작성하는 방법
someFunc = () => { MyClass.myStaticVariable = 1; }
. 그런 다음 정적 메소드를 작성하여 정적 멤버를 리턴하십시오 (예 :) static getStatic() { return MyClass.myStaticVariable; }
. 그런 다음 MyClass.getStatic()
클래스 외부에서 호출 하여 정적 데이터를 유지할 수 있습니다!
답변:
클래스 기반의 정적으로 유형이 지정된 객체 지향 언어 (예 : 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"
privilegedMethod
MyClass 인스턴스에서 호출 될 수있는 것처럼 보이기 때문에 OO의 개인 메소드와 같지 않을까요? 액세스 할 수 있기 때문에 권한이 있음을 의미 privateVariable
합니까?
this.constructor
"인스턴스 메소드"에서 정적 변수에 액세스하는 데 사용할 수 없습니까 ? 그렇다면 대답에 추가 할 가치가 있습니다.
MyClass.prototype.staticProperty = "baz";
정적 속성은 실제로 익명 함수로 정의되어 MyClass.prototype.staticProperty = function () {return staticVar;}
모든 변수가 단일 변수에 액세스하여 세터로 변경할 수 있도록 OO 원칙을 읽 거나 훨씬 더 정확해야합니다 .
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.
어떤 종류의 결과를 얻습니까? 이번을 제외하고는 증가 된 값이 표시되는 대신 반환됩니다.
countMyself.counter = countMyself.counter || initial_value;
정적 변수가 거짓이 아닌 경우 (false, 0, null 또는 빈 문자열)
===
을위한 typeof
검사는 다른 몇 가지 이상한 강압에가는거야.
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);
}
arguments.callee
더 이상 사용되지 않습니다.
callee
가지고있는 것이 좋았습니다. 해킹이 왜 이것을 사용하지 않기로 결정했는지 궁금합니다 ... : |
비슷한 답변을 두 번 보았지만 이 게시물이 가장 잘 설명되어 있다고 말씀 드리고 싶습니다.
여기에서 가져온 코드가 있습니다. 클래스의 디자인 템플릿으로 사용할 수 있기 때문에 커뮤니티에 도움이되는 완전한 예제를 얻도록 수정했습니다.
또한 귀하의 질문에 답변합니다 :
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 함수는 객체이므로 속성에 할당 할 수 있습니다 .
bar
의 속성을 Foo
하기 위해 3
이 같은Foo.bar = 3;
다음 예제와 설명은 Nicholas Zakas의 책 전문 웹 개발자를위한 전문 JavaScript 2 판입니다. 이것은 내가 찾고있는 대답이므로 여기에 추가하는 것이 도움이 될 것이라고 생각했습니다.
(function () {
var name = '';
Person = function (value) {
name = value;
};
Person.prototype.getName = function () {
return name;
};
Person.prototype.setName = function (value) {
name = value;
};
}());
var person1 = new Person('Nate');
console.log(person1.getName()); // Nate
person1.setName('James');
console.log(person1.getName()); // James
person1.name = 'Mark';
console.log(person1.name); // Mark
console.log(person1.getName()); // James
var person2 = new Person('Danielle');
console.log(person1.getName()); // Danielle
console.log(person2.getName()); // Danielle
Person
이 예제 의 생성자는 getName()
및 setName()
메소드 와 마찬가지로 개인 변수 이름에 액세스 할 수 있습니다. 이 패턴을 사용하면 이름 변수가 정적이되어 모든 인스턴스에서 사용됩니다. 즉 setName()
, 한 인스턴스를 호출 하면 다른 모든 인스턴스에 영향을줍니다. setName()
새 Person
인스턴스를 호출 하거나 만들면 이름 변수가 새 값으로 설정됩니다. 이로 인해 모든 인스턴스가 동일한 값을 반환합니다.
새 클래스 구문 을 사용하는 경우 이제 다음을 수행 할 수 있습니다.
class MyClass {
static get myStaticVariable() {
return "some static variable";
}
}
console.log(MyClass.myStaticVariable);
aMyClass = new MyClass();
console.log(aMyClass.myStaticVariable, "is undefined");
이는 JavaScript에서 정적 변수를 효과적으로 만듭니다.
MyClass
클래스 구문 외부 에서 정의 된 클로저가 필요합니다 .
class
ECMAScript 2015에 의해 도입 된 정보 . 다른 답변은 완전히 명확하지 않습니다.
여기에 정적 var에 만드는 방법을 보여주는 예입니다 staticVar
와 함께 ClassName
. var
신택스 :
class MyClass {
constructor(val) {
this.instanceVar = val;
MyClass.staticVar = 10;
}
}
var class1 = new MyClass(1);
console.log(class1.instanceVar); // 1
console.log(class1.constructor.staticVar); // 10
// New instance of MyClass with another value
var class2 = new MyClass(3);
console.log(class1.instanceVar); // 1
console.log(class2.instanceVar); // 3
정적 변수에 액세스하기 .constructor
위해 클래스를 만든 객체 생성자 함수에 대한 참조를 반환하는 속성을 사용합니다 . 생성 된 두 인스턴스에서 호출 할 수 있습니다.
MyClass.staticVar = 11;
console.log(class1.constructor.staticVar); // 11
console.log(class2.constructor.staticVar); // 11 <-- yes it's static! :)
MyClass.staticVar = 12;
console.log(class1.constructor.staticVar); // 12
console.log(class2.constructor.staticVar); // 12
나머지 외에도 현재 ECMA 제안서 에 초안 ( 2 단계 제안서 )이 있어 수업에 공개 필드 를 소개 합니다. ( 비공개 분야 고려 )static
제안서의 예제를 사용하여 제안 된 static
구문은 다음과 같습니다.
class CustomDate {
// ...
static epoch = new CustomDate(0);
}
다른 사람들이 강조한 다음과 같습니다.
class CustomDate {
// ...
}
CustomDate.epoch = new CustomDate(0);
그런 다음을 통해 액세스 할 수 있습니다 CustomDate.epoch
.
에서 새로운 제안을 추적 할 수 있습니다 proposal-static-class-features
.
현재 babel은 사용할 수 있는 변환 클래스 특성 플러그인 으로이 기능을 지원 합니다. 또한 여전히 진행 중이지만 V8
구현하고 있습니다.
아래와 같이 JavaScript에서 정적 변수를 만들 수 있습니다. count
정적 변수는 다음과 같습니다 .
var Person = function(name) {
this.name = name;
// first time Person.count is undefined, so it is initialized with 1
// next time the function is called, the value of count is incremented by 1
Person.count = Person.count ? Person.count + 1 : 1;
}
var p1 = new Person('User p1');
console.log(p1.constructor.count); // prints 1
var p2 = new Person('User p2');
console.log(p2.constructor.count); // prints 2
Person
함수 또는 인스턴스를 사용하여 정적 변수에 값을 지정할 수 있습니다 .
// set static variable using instance of Person
p1.constructor.count = 10; // this change is seen in all the instances of Person
console.log(p2.constructor.count); // prints 10
// set static variable using Person
Person.count = 20;
console.log(p1.constructor.count); // prints 20
JavaScript에서 정적 변수에 가장 가까운 것은 전역 변수입니다. 이것은 단순히 함수 또는 객체 리터럴의 범위 밖에서 선언 된 변수입니다.
var thisIsGlobal = 1;
function foo() {
var thisIsNot = 2;
}
다른 방법으로는 전역 변수를 다음과 같이 객체 리터럴 안에 저장하는 것입니다.
var foo = { bar : 1 }
그런 다음 variabels에 다음과 같이 액세스하십시오 foo.bar
.
여기에서 모든 클래스 개념을 요약하려면 다음을 테스트하십시오.
var Test = function() {
// "super private" variable, accessible only here in constructor. There are no real private variables
//if as 'private' we intend variables accessible only by the class that defines the member and NOT by child classes
var test_var = "super private";
//the only way to access the "super private" test_var is from here
this.privileged = function(){
console.log(test_var);
}();
Test.test_var = 'protected';//protected variable: accessible only form inherited methods (prototype) AND child/inherited classes
this.init();
};//end constructor
Test.test_var = "static";//static variable: accessible everywhere (I mean, even out of prototype, see domready below)
Test.prototype = {
init:function(){
console.log('in',Test.test_var);
}
};//end prototype/class
//for example:
$(document).ready(function() {
console.log('out',Test.test_var);
var Jake = function(){}
Jake.prototype = new Test();
Jake.prototype.test = function(){
console.log('jake', Test.test_var);
}
var jake = new Jake();
jake.test();//output: "protected"
});//end domready
글쎄, 이러한 것들에서 모범 사례를 살펴볼 수있는 또 다른 방법은 커피 스크립트가 이러한 개념을 어떻게 번역하는지 보는 것입니다.
#this is coffeescript
class Test
#static
@prop = "static"
#instance
constructor:(prop) ->
@prop = prop
console.log(@prop)
t = new Test('inst_prop');
console.log(Test.prop);
//this is how the above is translated in plain js by the CS compiler
Test = (function() {
Test.prop = "static";
function Test(prop) {
this.prop = prop;
console.log(this.prop);
}
return Test;
})();
t = new Test('inst_prop');
console.log(Test.prop);
이 스레드를 탐색 한 후 요구 사항을 해결하는 또 다른 접근법이 있습니다. "정적 변수"를 사용하여 정확히 달성하려는 대상에 따라 다릅니다.
전역 속성 sessionStorage 또는 localStorage를 사용하면 세션 수명 동안 또는 명시 적으로 지울 때까지 무기한 더 오랜 기간 동안 데이터를 저장할 수 있습니다. 이를 통해 페이지 / 앱의 모든 창, 프레임, 탭 패널, 팝업 등에서 데이터를 공유 할 수 있으며 하나의 코드 세그먼트에서 간단한 "정적 / 전역 변수"보다 훨씬 강력합니다.
최상위 전역 변수, 즉 Window.myglobal의 범위, 수명, 의미, 역학 등 모든 번거 로움을 피합니다. 그것이 얼마나 효율적인지 모르지만, 적당한 속도로 액세스하는 적당한 양의 데이터에는 중요하지 않습니다.
"sessionStorage.mydata = anything"로 쉽게 액세스하고 유사하게 검색합니다. "JavaScript : 결정적인 안내서, 6 판", David Flanagan, ISBN : 978-0-596-80552-4, 20 장, 섹션 20.1을 참조하십시오. 이것은 간단한 검색 또는 O'Reilly Safaribooks 구독 (무게가 금으로 표시됨)을 통해 PDF로 쉽게 다운로드 할 수 있습니다.
함수 / 클래스는 객체 범위에 단일 생성자 만 허용합니다.
Function Hoisting, declarations & expressions
Function 생성자로 생성 된 함수는 해당 생성 컨텍스트에 대한 클로저를 생성하지 않습니다. 그들은 항상 글로벌 범위에서 만들어집니다.
var functionClass = function ( ) { var currentClass = Shape; _inherits(currentClass, superClass); function functionClass() { superClass.call(this); // Linking with SuperClass Constructor. // Instance Variables list. this.id = id; return this; } }(SuperClass)
클로저 -클로저의 복사본은 보존 된 데이터로 작동합니다.
- 각 클로저의 사본은 자체 자유 값 또는 참조가있는 함수에 작성됩니다. 다른 함수 내에서 함수를 사용할 때마다 클로저가 사용됩니다.
JavaScript에서의 클로저는 innerFunctions에 의해 부모 함수의 모든 로컬 변수 사본을 유지 관리하는 것과 같습니다.
function closureFun( args ) { // Local variable that ends up within closure var num = args; num++; return function() { console.log(num); } } var closure1 = closureFun( 5 ); var closure2 = closureFun( 777 ); closure1(); // 5 closure2(); // 777 closure2(); // 778 closure1(); // 6
ES5 함수 클래스 : Object.defineProperty (O, P, Attributes)를 사용합니다
Object.defineProperty () 메소드는 개체에 직접 새 속성을 정의하거나 수정 기존 속성을 개체에 대한, 그리고 개체를 반환합니다.
`` 를 사용하여 몇 가지 방법을 만들었습니다. 으므로 매번 함수 클래스를 쉽게 이해할 수 있습니다.
'use strict';
var Shape = function ( superClass ) {
var currentClass = Shape;
_inherits(currentClass, superClass); // Prototype Chain - Extends
function Shape(id) { superClass.call(this); // Linking with SuperClass Constructor.
// Instance Variables list.
this.id = id; return this;
}
var staticVariablesJOSN = { "parent_S_V" : 777 };
staticVariable( currentClass, staticVariablesJOSN );
// Setters, Getters, instanceMethods. [{}, {}];
var instanceFunctions = [
{
key: 'uniqueID',
get: function get() { return this.id; },
set: function set(changeVal) { this.id = changeVal; }
}
];
instanceMethods( currentClass, instanceFunctions );
return currentClass;
}(Object);
var Rectangle = function ( superClass ) {
var currentClass = Rectangle;
_inherits(currentClass, superClass); // Prototype Chain - Extends
function Rectangle(id, width, height) { superClass.call(this, id); // Linking with SuperClass Constructor.
this.width = width;
this.height = height; return this;
}
var staticVariablesJOSN = { "_staticVar" : 77777 };
staticVariable( currentClass, staticVariablesJOSN );
var staticFunctions = [
{
key: 'println',
value: function println() { console.log('Static Method'); }
}
];
staticMethods(currentClass, staticFunctions);
var instanceFunctions = [
{
key: 'setStaticVar',
value: function setStaticVar(staticVal) {
currentClass.parent_S_V = staticVal;
console.log('SET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
}
}, {
key: 'getStaticVar',
value: function getStaticVar() {
console.log('GET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
return currentClass.parent_S_V;
}
}, {
key: 'area',
get: function get() {
console.log('Area : ', this.width * this.height);
return this.width * this.height;
}
}, {
key: 'globalValue',
get: function get() {
console.log('GET ID : ', currentClass._staticVar);
return currentClass._staticVar;
},
set: function set(value) {
currentClass._staticVar = value;
console.log('SET ID : ', currentClass._staticVar);
}
}
];
instanceMethods( currentClass, instanceFunctions );
return currentClass;
}(Shape);
// ===== ES5 Class Conversion Supported Functions =====
function defineProperties(target, props) {
console.log(target, ' : ', props);
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function staticMethods( currentClass, staticProps ) {
defineProperties(currentClass, staticProps);
};
function instanceMethods( currentClass, protoProps ) {
defineProperties(currentClass.prototype, protoProps);
};
function staticVariable( currentClass, staticVariales ) {
// Get Key Set and get its corresponding value.
// currentClass.key = value;
for( var prop in staticVariales ) {
console.log('Keys : Values');
if( staticVariales.hasOwnProperty( prop ) ) {
console.log(prop, ' : ', staticVariales[ prop ] );
currentClass[ prop ] = staticVariales[ prop ];
}
}
};
function _inherits(subClass, superClass) {
console.log( subClass, ' : extends : ', superClass );
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype,
{ constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });
if (superClass)
Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
아래 코드 스 니펫은 각 인스턴스마다 인스턴스 멤버 및 공통 정적 멤버의 자체 사본이 있습니다.
var objTest = new Rectangle('Yash_777', 8, 7);
console.dir(objTest);
var obj1 = new Rectangle('R_1', 50, 20);
Rectangle.println(); // Static Method
console.log( obj1 ); // Rectangle {id: "R_1", width: 50, height: 20}
obj1.area; // Area : 1000
obj1.globalValue; // GET ID : 77777
obj1.globalValue = 88; // SET ID : 88
obj1.globalValue; // GET ID : 88
var obj2 = new Rectangle('R_2', 5, 70);
console.log( obj2 ); // Rectangle {id: "R_2", width: 5, height: 70}
obj2.area; // Area : 350
obj2.globalValue; // GET ID : 88
obj2.globalValue = 999; // SET ID : 999
obj2.globalValue; // GET ID : 999
console.log('Static Variable Actions.');
obj1.globalValue; // GET ID : 999
console.log('Parent Class Static variables');
obj1.getStaticVar(); // GET Instance Method Parent Class Static Value : 777
obj1.setStaticVar(7); // SET Instance Method Parent Class Static Value : 7
obj1.getStaticVar(); // GET Instance Method Parent Class Static Value : 7
정적 메서드 호출은 클래스에서 직접 이루어지며 클래스 인스턴스에서는 호출 할 수 없습니다. 그러나 인스턴스 내부에서 정적 멤버를 호출 할 수 있습니다.
구문 사용하기 :
this.constructor.staticfunctionName();
class MyClass {
constructor() {}
static staticMethod() {
console.log('Static Method');
}
}
MyClass.staticVar = 777;
var myInstance = new MyClass();
// calling from instance
myInstance.constructor.staticMethod();
console.log('From Inside Class : ',myInstance.constructor.staticVar);
// calling from class
MyClass.staticMethod();
console.log('Class : ', MyClass.staticVar);
ES6 클래스 : ES2015 클래스는 프로토 타입 기반 OO 패턴에 대한 간단한 설탕입니다. 편리한 단일 선언 형식을 사용하면 클래스 패턴을보다 쉽게 사용할 수 있으며 상호 운용성을 장려합니다. 클래스는 프로토 타입 기반 상속, 수퍼 호출, 인스턴스 및 정적 메소드 및 생성자를 지원합니다.
예 : 내 이전 게시물을 참조하십시오.
Javascript에서 함수 로컬 정적 변수를 에뮬레이트하는 방법에는 4 가지가 있습니다.
방법 1 : 함수 객체 속성 사용 (이전 브라우저에서 지원됨)
function someFunc1(){
if( !('staticVar' in someFunc1) )
someFunc1.staticVar = 0 ;
alert(++someFunc1.staticVar) ;
}
someFunc1() ; //prints 1
someFunc1() ; //prints 2
someFunc1() ; //prints 3
방법 2 : 클로저, 변형 1 사용 (이전 브라우저에서 지원됨)
var someFunc2 = (function(){
var staticVar = 0 ;
return function(){
alert(++staticVar) ;
}
})()
someFunc2() ; //prints 1
someFunc2() ; //prints 2
someFunc2() ; //prints 3
방법 3 : 클로저, 변형 2 사용 (이전 브라우저에서도 지원됨)
var someFunc3 ;
with({staticVar:0})
var someFunc3 = function(){
alert(++staticVar) ;
}
someFunc3() ; //prints 1
someFunc3() ; //prints 2
someFunc3() ; //prints 3
방법 4 : 클로저, 변형 3 사용 (EcmaScript 2015 지원 필요)
{
let staticVar = 0 ;
function someFunc4(){
alert(++staticVar) ;
}
}
someFunc4() ; //prints 1
someFunc4() ; //prints 2
someFunc4() ; //prints 3
키워드를 사용하여 JavaScript에서 정적 함수를 정의 할 수 있습니다 static
.
class MyClass {
static myStaticFunction() {
return 42;
}
}
MyClass.myStaticFunction(); // 42
이 글을 쓰는 시점에서 여전히 클래스 내에서 정적 속성 (함수 이외의)을 정의 할 수는 없습니다. 정적 속성은 여전히 3 단계 제안서 이므로 아직 JavaScript의 일부가 아닙니다. 그러나 다른 객체와 마찬가지로 클래스에 단순히 할당하는 것을 막을 수있는 것은 없습니다.
class MyClass {}
MyClass.myStaticProperty = 42;
MyClass.myStaticProperty; // 42
마지막 참고 사항 : 상속 된 정적 객체를 사용할 때주의하십시오. 상속 된 모든 클래스는 동일한 객체 사본을 공유합니다 .
JavaScript에는 용어 또는 키워드 정적이 없지만 이러한 데이터를 다른 객체와 마찬가지로 함수 객체에 직접 넣을 수 있습니다.
function f() {
f.count = ++f.count || 1 // f.count is undefined at first
alert("Call No " + f.count)
}
f(); // Call No 1
f(); // Call No 2
정적 함수 변수를 많이 사용하며 JS에는 내장 메커니즘이 없기 때문에 부끄러운 일입니다. 변수와 함수가 하나의 함수 내에서 사용되었지만 외부 범위에서 정의되는 코드를 너무 자주 볼 수 있습니다. 이것은 추악하고 오류가 발생하기 쉽고 문제를 묻는 것입니다 ...
나는 다음과 같은 방법을 생각해 냈습니다.
if (typeof Function.prototype.statics === 'undefined') {
Function.prototype.statics = function(init) {
if (!this._statics) this._statics = init ? init() : {};
return this._statics;
}
}
이것은 모든 함수에 'statics'메서드를 추가합니다 (예, 긴장을 풀십시오). 호출 될 때 함수 객체에 빈 객체 (_statics)를 추가하고 반환합니다. init 함수가 제공되면 _statics는 init () result로 설정됩니다.
그런 다음 다음을 수행 할 수 있습니다.
function f() {
const _s = f.statics(() => ({ v1=3, v2=somefunc() });
if (_s.v1==3) { ++_s.v1; _s.v2(_s.v1); }
}
이것을 다른 정답 인 IIFE와 비교할 때, 이것은 하나의 할당과 하나의 함수 호출마다 하나의 함수를 추가하고 함수에 '_statics'멤버를 추가하는 경우 단점이 있지만, 몇 가지 장점이 있습니다. 내부 함수 코드에서 '정적'을 사용하는 내부 함수가 아닌 상단은 '_s'로 명시 적입니다. 접두사를 사용하면 전체적으로보고 이해하는 것이 더 간단합니다.
에서 ES6
/ ES 2015 class
키워드는 함께 소개 된 static
키워드. 이것은 javavscript가 구현하는 프로토 타입 상속 모델에 대한 구문 설탕이라는 점을 명심하십시오. static
키워드는 방법에 대한 다음과 같은 방식으로 작동합니다 :
class Dog {
static bark () {console.log('woof');}
// classes are function objects under the hood
// bark method is located on the Dog function object
makeSound () { console.log('bark'); }
// makeSound is located on the Dog.prototype object
}
// to create static variables just create a property on the prototype of the class
Dog.prototype.breed = 'Pitbull';
// So to define a static property we don't need the `static` keyword.
const fluffy = new Dog();
const vicky = new Dog();
console.log(fluffy.breed, vicky.breed);
// changing the static variable changes it on all the objects
Dog.prototype.breed = 'Terrier';
console.log(fluffy.breed, vicky.breed);
Javascript에는 정적 변수와 같은 것이 없습니다. 이 언어는 프로토 타입 기반 객체를 지향하므로 클래스는 없지만 객체가 "복사"하는 프로토 타입은 없습니다.
전역 변수 또는 프로토 타입을 사용하여 프로토 타입에 속성을 추가하여 시뮬레이션 할 수 있습니다.
function circle(){
}
circle.prototype.pi=3.14159
Function.prototype
function circle() {}
| circle.prototype
| circle.prototype.pi = 3.14
| circle.prototype
| Function.prototype
| Function.__proto__
(그것이 당신이 의도 한 것이라면)
jQuery를 사용하는 MVC 웹 사이트를 사용하면서 특정 이벤트 핸들러 내의 AJAX 작업을 이전 요청이 완료된 후에 만 실행할 수 있는지 확인하고 싶습니다. 이것을 달성하기 위해 "정적"jqXHR 객체 변수를 사용합니다.
다음과 같은 버튼이 있습니다 :
<button type="button" onclick="ajaxAction(this, { url: '/SomeController/SomeAction' })">Action!</button>
일반적으로 클릭 핸들러에 다음과 같은 IIFE를 사용합니다.
var ajaxAction = (function (jqXHR) {
return function (sender, args) {
if (!jqXHR || jqXHR.readyState == 0 || jqXHR.readyState == 4) {
jqXHR = $.ajax({
url: args.url,
type: 'POST',
contentType: 'application/json',
data: JSON.stringify($(sender).closest('form').serialize()),
success: function (data) {
// Do something here with the data.
}
});
}
};
})(null);
프로토 타입을 사용하려면 방법이 있습니다
var p = function Person() {
this.x = 10;
this.y = 20;
}
p.prototype.counter = 0;
var person1 = new p();
person1.prototype = p.prototype;
console.log(person1.counter);
person1.prototype.counter++;
var person2 = new p();
person2.prototype = p.prototype;
console.log(person2.counter);
console.log(person1.counter);
이렇게하면 모든 인스턴스에서 카운터 변수에 액세스 할 수 있으며 속성의 변경 사항이 즉시 반영됩니다!