[javascript] 인형 용 게터 \ 세터

나는 getters와 setter 주위에 머리를 갖기 위해 노력하고 있었고 그것의 침몰하지 않았다. 나는 JavaScript Getters and SettersGetters and Setters 정의하고 그것을 얻지 못했다.

누군가가 명확하게 진술 할 수 있습니까?

  1. 게터와 세터가해야 할 일
  2. 아주 간단한 예를 들어보십시오.


답변

@ millimoose ‘s answer 외에도 setter를 사용하여 다른 값을 업데이트 할 수도 있습니다.

function Name(first, last) {
    this.first = first;
    this.last = last;
}

Name.prototype = {
    get fullName() {
        return this.first + " " + this.last;
    },

    set fullName(name) {
        var names = name.split(" ");
        this.first = names[0];
        this.last = names[1];
    }
};

지금, 당신은 설정할 수 있습니다 fullName, 그리고 firstlast반대의 업데이트 및 그됩니다.

n = new Name('Claude', 'Monet')
n.first # "Claude"
n.last # "Monet"
n.fullName # "Claude Monet"
n.fullName = "Gustav Klimt"
n.first # "Gustav"
n.last # "Klimt"


답변

JavaScript의 게터와 세터

개요

JavaScript의 Getter 및 Setter는 계산 된 속성 또는 접근 자를 정의하는 데 사용됩니다 . 계산 된 속성은 함수를 사용하여 개체 값을 가져 오거나 설정하는 속성입니다. 기본 이론은 다음과 같습니다.

var user = { /* ... object with getters and setters ... */ };
user.phone = '+1 (123) 456-7890'; // updates a database
console.log( user.areaCode ); // displays '123'
console.log( user.area ); // displays 'Anytown, USA'

이는 범위에 숫자를 유지하거나 문자열을 다시 포맷하거나 변경된 이벤트를 트리거하거나 관계형 데이터를 업데이트하고 개인 속성에 대한 액세스를 제공하는 등 속성에 액세스 할 때 배후에서 자동으로 작업을 수행하는 데 유용합니다.

아래 예제는 기본 구문을 보여 주지만 특별한 작업을 수행하지 않고 내부 객체 값을 가져오고 설정합니다. 실제 상황에서는 위에서 언급 한대로 필요에 맞게 입력 및 / 또는 출력 값을 수정합니다.

키워드 가져 오기 / 설정

ECMAScript 5는 계산 된 속성을 정의하기위한 키워드 getset키워드를 지원 합니다. IE 8 이하를 제외한 모든 최신 브라우저에서 작동합니다.

var foo = {
    bar : 123,
    get bar(){ return bar; },
    set bar( value ){ this.bar = value; }
};
foo.bar = 456;
var gaz = foo.bar;

커스텀 게터와 세터

get그리고 set그들은 사용자 정의, 크로스 브라우저가 계산 된 속성 기능을 만들 오버로드 할 수 있도록, 예약어되지 않습니다. 이것은 모든 브라우저에서 작동합니다.

var foo = {
    _bar : 123,
    get : function( name ){ return this[ '_' + name ]; },
    set : function( name, value ){ this[ '_' + name ] = value; }
};
foo.set( 'bar', 456 );
var gaz = foo.get( 'bar' );

또는보다 콤팩트 한 접근을 위해 단일 기능을 사용할 수 있습니다.

var foo = {
    _bar : 123,
    value : function( name /*, value */ ){
        if( arguments.length < 2 ){ return this[ '_' + name ]; }
        this[ '_' + name ] = value;
    }
};
foo.value( 'bar', 456 );
var gaz = foo.value( 'bar' );

이와 같은 작업을 피하면 코드가 부풀어 질 수 있습니다.

var foo = {
    _a : 123, _b : 456, _c : 789,
    getA : function(){ return this._a; },
    getB : ..., getC : ..., setA : ..., setB : ..., setC : ...
};

위의 예에서 내부 속성 이름은 밑줄로 요약되어 사용자가 단순히 foo.barvs 를 사용하지 foo.get( 'bar' )않고 “요리되지 않은”값을 얻지 못하게합니다. 조건부 코드를 사용하여 액세스중인 속성의 이름에 따라 ( name매개 변수 를 통해 ) 다른 작업을 수행 할 수 있습니다 .

Object.defineProperty ()

사용 Object.defineProperty()은 게터와 세터를 추가하는 또 다른 방법이며 정의 된 객체에 사용할 수 있습니다. 또한 구성 가능하고 열거 가능한 동작을 설정하는 데 사용될 수 있습니다. 이 구문은 IE 8에서도 작동하지만 불행히도 DOM 객체에서만 작동합니다.

var foo = { _bar : 123 };
Object.defineProperty( foo, 'bar', {
    get : function(){ return this._bar; },
    set : function( value ){ this._bar = value; }
} );
foo.bar = 456;
var gaz = foo.bar;

__defineGetter __ ()

마지막으로 __defineGetter__()또 다른 옵션입니다. 더 이상 사용되지 않지만 웹에서 여전히 널리 사용되므로 조만간 사라지지 않을 것입니다. IE 10 이하를 제외한 모든 브라우저에서 작동합니다. 다른 옵션은 비 IE에서도 잘 작동하지만 유용하지 않습니다.

var foo = { _bar : 123; }
foo.__defineGetter__( 'bar', function(){ return this._bar; } );
foo.__defineSetter__( 'bar', function( value ){ this._bar = value; } );

주목할 가치가 후자의 예에서, 내부 이름은 피하기 재귀에 접근 이름 (즉, 달라야한다는 것입니다 foo.bar호출 foo.get(bar)전화 foo.bar통화를 foo.get(bar)…).

또한보십시오

MDN get , set ,
Object.defineProperty () , __defineGetter __ () , __defineSetter __ ()
MSDN
IE8 Getter 지원


답변

예를 들어 계산 된 속성을 구현하는 데 사용합니다.

예를 들면 다음과 같습니다.

function Circle(radius) {
    this.radius = radius;
}

Object.defineProperty(Circle.prototype, 'circumference', {
    get: function() { return 2*Math.PI*this.radius; }
});

Object.defineProperty(Circle.prototype, 'area', {
    get: function() { return Math.PI*this.radius*this.radius; }
});

c = new Circle(10);
console.log(c.area); // Should output 314.159
console.log(c.circumference); // Should output 62.832

(코드 펜)


답변

오래된 질문을 부활 시켜서 미안하지만, 몇 가지 매우 기본적인 예와 모형 설명에 기여할 수 있다고 생각했습니다. 지금까지 게시 된 다른 답변 중 어느 것도 MDN 가이드 의 첫 번째 예제 와 같은 구문을 보여주지 않습니다.

얻는 사람:

var settings = {
    firstname: 'John',
    lastname: 'Smith',
    get fullname() { return this.firstname + ' ' + this.lastname; }
};

console.log(settings.fullname);

John Smith물론 로그 합니다. 게터의 변수 개체 속성처럼 동작하지만 이벤트 즉시 그 반환 값을 계산하는 기능의 유연성을 제공합니다. 기본적으로 호출 할 때 ()가 필요없는 함수를 만드는 멋진 방법입니다.

세터:

var address = {
    set raw(what) {
        var loc = what.split(/\s*;\s*/),
        area = loc[1].split(/,?\s+(\w{2})\s+(?=\d{5})/);

        this.street = loc[0];
        this.city = area[0];
        this.state = area[1];
        this.zip = area[2];
    }
};

address.raw = '123 Lexington Ave; New York NY  10001';
console.log(address.city);

New York콘솔에 로그인 합니다. getter와 마찬가지로 setter 는 객체 속성 값을 설정하는 것과 동일한 구문으로 호출되지만 ()없이 함수를 호출하는 또 다른 멋진 방법입니다.

더 철저하고 아마도 더 실용적인 예는 이 jsfiddle 을 참조하십시오 . 객체의 setter에 값을 전달하면 다른 객체 항목의 생성 또는 채우기가 트리거됩니다. 특히, jsfiddle 예제에서 숫자 배열을 전달하면 setter가 평균, 중앙값, 모드 및 범위를 계산하도록 프롬프트합니다. 그런 다음 각 결과에 대한 객체 속성을 설정합니다.


답변

게터와 세터는 클래스의 전용 속성이있을 때만 의미가 있습니다. Javascript에는 일반적으로 객체 지향 언어에서 생각하는 것처럼 개인 클래스 속성이 없으므로 이해하기 어려울 수 있습니다. 다음은 개인 카운터 개체의 예입니다. 이 개체의 좋은 점은 개체 외부에서 내부 변수 “count”에 액세스 할 수 없다는 것입니다.

var counter = function() {
    var count = 0;

    this.inc = function() {
        count++;
    };

    this.getCount = function() {
        return count;
    };
};

var i = new Counter();
i.inc();
i.inc();
// writes "2" to the document
document.write( i.getCount());

여전히 혼란 스러우면 Crockford의 Javascript 개인 멤버에 대한 기사를 살펴보십시오 .


답변

나는 당신이 연결하는 첫 번째 기사가 그것을 명확하게 밝힌다 고 생각합니다.

이러한 방식으로 JavaScript를 작성할 때의 분명한 이점은 사용자가 직접 액세스하기를 원하지 않는 값을 모호하게 사용할 수 있다는 것입니다.

여기서 목표는 get()또는 set()방법을 통해 필드에 대한 액세스 만 허용하여 필드를 캡슐화하고 추상화하는 것 입니다. 이런 방식으로 필드 / 데이터를 원하는 방식으로 내부에 저장할 수 있지만 외부 구성 요소는 게시 된 인터페이스에서 멀리 떨어져 있습니다. 이를 통해 외부 인터페이스를 변경하지 않고 내부 변경을 수행하거나 set()메소드 내에서 일부 유효성 검증 또는 오류 점검을 수행 할 수 있습니다 .


답변

액세스 제어없이 공용 속성이있는 객체를 보는 데 자주 사용되지만 JavaScript를 사용하면 속성을 정확하게 설명 할 수 있습니다. 실제로 속성에 액세스 할 수있는 방법과 적용 할 수있는 논리를 제어하기 위해 설명자를 사용할 수 있습니다. 다음 예제를 고려하십시오.

var employee = {
    first: "Boris",
    last: "Sergeev",
    get fullName() {
        return this.first + " " + this.last;
    },
    set fullName(value) {
        var parts = value.toString().split(" ");
        this.first = parts[0] || "";
        this.last = parts[1] || "";
    },
    email: "boris.sergeev@example.com"
};

최종 결과 :

console.log(employee.fullName); //Boris Sergeev
employee.fullName = "Alex Makarenko";

console.log(employee.first);//Alex
console.log(employee.last);//Makarenko
console.log(employee.fullName);//Alex Makarenko