C#과 Java에 익숙한 분들이라면 객체지향의 3대 개념(캡슐화, 상속, 다형성)에 대해 잘 알고 계실 텐데요. 오늘은 Javascript에서 캡슐화 기능을 활용하는 방법에 대해 이야기해 볼까 합니다. , 시작하자!
현실의 어떤 것들을 클래스로 추상화하고, 그 사물의 속성(명사)을 클래스의 속성으로, 사물의 행위(동사)를 클래스의 메소드로 활용하겠습니다. 객체지향 언어(C# 등)에는 클래스나 속성을 수정하는 몇 가지 키워드(Private, public, protected)가 있습니다. 이러한 키워드는 액세스 권한을 설명하므로 자세히 설명하지 않습니다.
Javascript의 변경 가능한 특성을 살펴보겠습니다(지난 시간의 예를 계속 사용합니다).
var Man = function(이름, 나이) { this.Name = name ; This.Age = age; } var Person = new Interface("Person", ["GetName", "GetAge"]); Man.prototype = { GetName: function () }, GetAge: function () { return this.Age; } } } var Alan = new Man("Alan", 25); Alert(Alan.GetAge()); function () { return "이름: "+this. GetName( ) + "; Age: " + this.GetAge() } Alert(Alan.DisplayAll());
먼저 2개의 public( public)이 있는 클래스(Javascript 익명 메서드)를 만들었습니다. 필드(이 블로그에서 자세히 설명하고 계속 읽으세요)와 2개의 공개 메서드를 사용하여 인스턴스--Alan을 만들었지만 이 인스턴스에 DisplayAll 메서드를 동적으로 추가할 수 있습니다. 어떤 객체 지향 언어도 이 작업을 수행할 수 없다고 생각합니다. Javascript의 유연한 구현 중 하나입니다.
이제 시나리오를 가정해 보겠습니다. 많은 프로그래머가 이 코드를 사용하려는 경우 Javascript의 가변성으로 인해 프로그래머는 인스턴스화 후 Name 값을 변경할 수 있으므로 이제 초기화 작업은 의미가 없습니다.
var Alan = new Man("Alan", 25); ());
따라서 Java나 C#에서는 외부 사람들이 이 필드를 임의로 수정하도록 할 수 없습니다. 이 필드를 비공개로 변경해야 하며 모든 것이 정상이지만 Javascript는 그렇지 않습니다. 이 키워드를 수행해야 합니다. 이것이 이 블로그의 의미입니다
var Person = new Interface("Person", ["SetName", "SetAge", "GetName" , " GetAge"]); var Man = function (이름, 나이) { this.SetAge(age); this.SetName(이름); } Man.prototype = { SetName: function (이름) { this.Name = 이름; }, SetAge: 함수(나이) { this.Age = 나이; }, GetName: 함수() { return this.Name; }, GetAge: 함수() { return this.Age; GetName: 함수 () Alan", 25); Alan.Name = "Alice"; //비극적입니다. Alan.SetAge(10)에 경고했을 때 저는 앨리스로 변했습니다.//비극적입니다. 누군가 저에게 너무 어리다고 경고했습니다(Alan .GetName()); DisplayAll = function () { return "Name: "+this.GetName() + "; Age: " + this.GetAge() } Alert(Alan.DisplayAll());
찾았습니다. C#의 Setter 및 Getter처럼 보이지만 여전히 외부에서 수정할 수 있습니다. 하지만 제약조건 측면에서는 위의 코드보다 메소드를 통해 초기값을 설정하는 것이 더 나은 것 같습니다. 하지만 여전히 문제는 해결되지 않습니다. 다음 방법을 살펴보겠습니다. Closure
클로저에 대해 이야기하기 전에 클로저의 본질을 이해해야 합니다. Javascript에서는 메서드에만 범위가 있습니다. 메서드에 선언된 변수를 외부에서 접근할 수 없으면 Private 개념이 나옵니다.
var Person = new Interface("Person", ["SetName", "SetAge", "GetName", "GetAge"]) var Man = function (newname, newage) { var name , age; this.SetName = 함수(newname) { name = newname; } this.SetAge = function(newage) { age = newage } this.GetName = function() { return name } this.GetAge = 함수() { return age; } this.SetAge(newage); var Alan = new Man("Alan", 25); //이제 이름은 비공개입니다. 수정됨 Alan.SetAge(10); //참사, 다른 사람이 너무 어리다고 경고했습니다.(Alan.GetAge());
이제 비공개 기능이 구현되었으므로 This를 방금 교체했습니다. Var와 함께. //공용 메서드를 호출하고 Private에 액세스할 수 있는 this.SetName, this.SetAge와 같은 권한 있는 메서드를 호출합니다.
공용 메서드가 Private 필드에 액세스하지 않는 경우 이를 Prototype에 넣을 수 있습니다. . //인스턴스가 여러 개인 경우 메모리에 복사본이 하나만 있다는 장점이 있습니다.
Man.prototype.DisplayAll = function() { return "Name: " + this.GetName() + "; Age : " + this.GetAge() }
하하~ 좀 더 어려운 것을 살펴보겠습니다: 정적 변수와 메서드
우리 모두는 static이 모든 것이 클래스( Class)에 속하므로 위 코드를 수정해 보겠습니다.
var Person = new Interface("Person", ["SetName", "SetAge", "GetName", "GetAge", "GetCount" ]); var Man = (function () { var count = 0; return function (newname, newage) { var name, age; this.SetName = function (newname) { name = newname; } this.SetAge = function (newage ) { age = newage; } this.GetName = function () { return name; } this.GetAge = function () { return age; } this.GetCount = function () { return count; newage); this.SetName(새 이름); count++; A lan1 = new Man("Alan", 25); var Alan2 = new Man("Alan", 25) Alert(""+Alan2.GetCount()가 있습니다. +" 인간의 사례" );