source

(JSON) 객체의 프로토타입에 메서드를 추가하는 방법

factcode 2023. 2. 9. 22:49
반응형

(JSON) 객체의 프로토타입에 메서드를 추가하는 방법

서버로부터 JSON 오브젝트(개인 오브젝트의 데이터 등)를 수신했다고 합니다.

{firstName: "Bjarne", lastName: "Fisk"}

이 데이터 위에 full Name을 계산하는 방법 등 몇 가지를 추가해 보겠습니다.

fullName: function() { return this.firstName + " " + this.lastName; }

내가 할 수 있도록

var personData = {firstName: "Bjarne", lastName: "Fisk"};
var person = PROFIT(personData);
person.fullName(); // => "Bjarne Fisk"

여기서 기본적으로 하고 싶은 것은 오브젝트의 프로토타입에 메서드를 추가하는 것입니다.fullName()메서드는 일반적이므로 데이터 개체 자체에 추가해서는 안 됩니다.예를 들어...:

personData.fullName = function() { return this.firstName + " " + this.lastName; }

...는 대량의 용장성을 발생시키고, 데이터 오브젝트를 「확장」할 가능성이 높아집니다.

이러한 방법을 단순한 데이터 객체에 추가하는 현재의 베스트 프랙티스 방법은 무엇입니까?

편집:

조금 주제에서 벗어났지만, 위의 문제가 해결된다면, 좋은 의사-를 할 수 있을 것이다.pattern matching다음과 같습니다.

if ( p = Person(data) ) {
   console.log(p.fullName());
} else if ( d = Dog(data) ) {
   console.log("I'm a dog lol. Hear me bark: "+d.bark());
} else {
   throw new Exception("Shitty object");
}

Person그리고.Dog이 경우 메서드가 추가됩니다.data오브젝트에는 올바른 속성이 있습니다.일치하지 않으면 위조를 반환합니다(즉, 데이터가 일치하지 않거나 일치하지 않음).

보너스 질문: 이 기능을 사용하거나 사용할 수 있는 라이브러리를 알고 계십니까?이미 Javascript 패턴인가요?그렇다면 뭐라고 부르죠? 자세한 링크가 있나요?감사합니다:)

오브젝트가 오브젝트를 생성하기 위해 서버 출력을 해석하는 JSON 라이브러리에서 나온다고 가정하면 일반적으로 오브젝트의 프로토타입에는 특별한 것이 없습니다.또한 서버 응답에 대해 생성된2개의 오브젝트는 프로토타입 체인을 공유하지 않습니다(물론 Object.protype 이외).

JSON에서 "Person"이 생성되는 모든 장소를 제어하면 반대로 작업을 수행할 수 있습니다. 즉, "빈" Person 오브젝트(프로토타입의 fullName과 같은 메서드를 사용하여)를 만들고 JSON에서 생성된 오브젝트($.extend, _extend 등을 사용)로 확장할 수 있습니다.

var p = { first : "John", last : "Doe"};

function Person(data) {
   _.extend(this, data);
}

Person.prototype.fullName = function() {
   return this.first + " " + this.last;   
}

console.debug(new Person(p).fullName());

여기에는 다른 가능성이 있다.JSON.parse는 리프 노드에서 루트 노드까지 발견된 개체를 되살리기 위해 사용되는 두 번째 매개 변수를 받아들입니다.따라서 고유한 특성에 따라 유형을 인식할 수 있는 경우 리바이버 함수로 유형을 구성할 수 있습니다.다음으로 매우 간단한 예를 제시하겠습니다.

var MultiReviver = function(types) {
    // todo: error checking: types must be an array, and each element
    //       must have appropriate `test` and `deserialize` functions
    return function(key, value) {
        var type;
        for (var i = 0; i < types.length; i++) {
            type = types[i];
            if (type.test(value)) {
                return type.deserialize(value);
            }
        }
        return value;
    };
};

var Person = function(first, last) {
    this.firstName = first;
    this.lastName = last;
};
Person.prototype.fullName = function() {
    return this.firstName + " " + this.lastName;
};
Person.prototype.toString = function() {return "Person: " + this.fullName();};
Person.test = function(value) {
    return typeof value.firstName == "string" && 
           typeof value.lastName == "string";
};
Person.deserialize = function(obj) {
    return new Person(obj.firstName, obj.lastName);
};

var Dog = function(breed, name) {
    this.breed = breed;
    this.name = name;
}
Dog.prototype.species = "canine";
Dog.prototype.toString = function() {
    return this.breed + " named " + this.name;
};
Dog.test = function(value) {return value.species === "canine";};
Dog.deserialize = function(obj) {return new Dog(obj.breed, obj.name);};


var reviver = new MultiReviver([Person, Dog]);

var text = '[{"firstName": "John", "lastName": "Doe"},' +
            '{"firstName": "Jane", "lastName": "Doe"},' +
            '{"firstName": "Junior", "lastName": "Doe"},' +
            '{"species": "canine", "breed": "Poodle", "name": "Puzzle"},' +
            '{"species": "canine", "breed": "Wolfhound", "name": "BJ"}]';

var family = JSON.parse(text, reviver)
family.join("\n");

// Person: John Doe
// Person: Jane Doe
// Person: Junior Doe
// Poodle named Puzzle
// Wolfhound named BJ

이것은, 자신의 타입을 명확하게 인식할 수 있는가에 달려 있습니다.예를 들어, 다른 유형의 사람(이름 및 성 속성도 있는 사람)이 있는 경우, 이러한 유형은 작동하지 않습니다.하지만 몇 가지 필요를 충족시킬 수 있을 겁니다.

JSON 각 JSON이다.Object.prototype시제품으로 만들기 위해서Person.prototype 먼저 PersonJavascript OOP(Javascript OOP:

function Person() {
    this.firstName = null;
    this.lastName = null;
}
Person.prototype.fullName = function() { return this.firstName + " " + this.lastName; }

을 ' 사물로 수 있는 예를 들어 다음과 같은 함수가 있는 경우mixin오브젝트 간에 모든 속성을 복사하기만 하면 다음과 같은 작업을 수행할 수 있습니다.

//example JSON object
var jsonPerson = {firstName: "Bjarne", lastName: "Fisk"};

var person = new Person();
mixin(person, jsonPerson);

이것은 문제를 해결하는 하나의 방법일 뿐이지만, 당신에게 몇 가지 아이디어를 줄 수 있기를 바랍니다.


"" " " " " " "Object.assign()최신 브라우저에서 사용할 수 있습니다.혼합 기능을 쓰는 대신 사용할 수 있습니다.Object.assign()https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill 를 참조해 주세요.

당신은 아마도 이것을 하지 않는 것이 좋을 것이다.

JSON을 사용하면 유형이 아닌 상태를 직렬화할 수 있습니다.따라서 사용 예에서는 다음과 같은 작업을 수행해야 합니다.

var Person = function ( data ) {
    if ( data ) {
        this.firstName = data.firstName;
        this.lastName = data.lastName;
    }
};

Person.prototype.fullName = function ( ) {
    return this.firstName + ' ' + this.lastName;
};

//

var input = '{"firstName":"john", "lastName":"Doe"}';
var myData = JSON.parse( input );
var person = new Person( myData );

즉, 기존 객체의 프로토타입(일명 클래스)을 변경하려고 합니다.기술적으로는 다음과 같이 할 수 있습니다.

var Person = {
  function fullName() { return this.firstName + " " + this.lastName; }
};

// that is your PROFIT function body: 
personData.__proto__ = Person ;

그 후에 당신이 얻을 수 있다면truepersonData instanceof Person

new-ish 객체를 사용합니다.setProtypeOf() (IE11 및 기타 모든 브라우저에서 지원됩니다.)

원하는 메서드(예: fullName()를 포함하는 클래스/프로토타입 생성 후

Object.setPrototypeOf( personData, Person.prototype );

경고(위 링크 MDN 페이지)에서 알 수 있듯이 이 기능은 가볍게 사용할 수 없습니다.기존 오브젝트의 프로토타입을 변경할 때는 이 기능이 타당하며, 그것을 목표로 하고 있는 것 같습니다.

데이터 전송 방법은 흔하지 않다고 생각합니다만, 좋은 아이디어인 것 같습니다.

이 프로젝트에서는 데이터와 함께 함수를 인코딩할 수 있지만 표준으로 간주되지 않으므로 동일한 라이브러리로 디코딩해야 합니다.

https://github.com/josipk/json-plus

익명의 물체에는 시제품이 없습니다.왜 그냥 이것만 가지고 있지 않지?

function fullName(obj) {
    return obj.firstName + ' ' + obj.lastName;
}

fullName(person);

함수 호출 대신 반드시 메서드 호출을 사용해야 하는 경우 항상 유사한 작업을 수행할 수 있지만 오브젝트를 사용할 수 있습니다.

var Person = function (person) { this.person = person; }
Person.prototype.fullName = function () {
    return this.person.firstName + ' ' + this.person.lastName;
}
var person = new Person(personData);
person.fullName();

베어본 개체에서 사용자 지정 메서드를 바인딩하기 위해 프로토타입을 사용할 필요가 없습니다.

여기에서는 중복 코드를 회피하는 코드를 오염시키지 않는 우아한 예가 있습니다.

var myobj = {
  title: 'example',
  assets: 
  {
    resources: ['zero', 'one', 'two']
  }
}

var myfunc = function(index)
{
    console.log(this.resources[index]); 
}

myobj.assets.giveme = myfunc

myobj.assets.giveme(1);

예시는 https://jsfiddle.net/bmde6L0r/에서 구할 수 있습니다.

언급URL : https://stackoverflow.com/questions/15054678/how-to-add-methods-to-a-json-objects-prototype

반응형