수색…


표준 함수 프로토 타입

먼저 생성자로 사용할 Foo 함수를 정의합니다.

function Foo (){}

Foo.prototype 을 편집하여 Foo 모든 인스턴스에서 공유 할 속성과 메서드를 정의 할 수 있습니다.

Foo.prototype.bar = function() {
  return 'I am bar';
};

그런 다음 new 키워드를 사용하여 인스턴스를 만들고 메서드를 호출 할 수 있습니다.

var foo = new Foo();

console.log(foo.bar()); // logs `I am bar`

Object.key와 Object.prototype.key의 차이점

파이썬과 같은 언어에서와 달리 생성자 함수의 정적 속성은 인스턴스에 상속 되지 않습니다 . 인스턴스는 부모 유형의 프로토 타입을 상속 한 프로토 타입에서만 상속합니다. 정적 속성은 상속되지 않습니다.

function Foo() {};
Foo.style = 'bold';

var foo = new Foo();

console.log(Foo.style); // 'bold'
console.log(foo.style); // undefined

Foo.prototype.style = 'italic';

console.log(Foo.style); // 'bold'
console.log(foo.style); // 'italic'

프로토 타입의 새 개체

JavaScript에서는 모든 객체가 다른 객체의 프로토 타입이 될 수 있습니다. 객체가 다른 객체의 프로토 타입으로 만들어지면 객체는 부모의 모든 속성을 상속받습니다.

var proto = { foo: "foo", bar: () => this.foo };

var obj = Object.create(proto);

console.log(obj.foo);
console.log(obj.bar());

콘솔 출력 :

> "foo"
> "foo"

참고 Object.create 는 ECMAScript 5에서 사용할 수 있지만 ECMAScript 3에 대한 지원이 필요한 경우 여기에 polyfill이 있습니다.

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

출처 : http://javascript.crockford.com/prototypal.html


Object.create ()

Object.create () 메서드는 지정된 프로토 타입 객체 및 속성을 사용하여 새 객체를 만듭니다.

구문 : Object.create(proto[, propertiesObject])

매개 변수 :

  • proto (새롭게 생성 된 객체의 원형이되는 객체)
  • propertiesObject (선택 사항이며 정의되지 않은 경우 열거 가능 자체 속성 (즉, 자체 프로토 타입 체인에 따라 열거 가능한 속성이 아니라 속성 자체에 정의 된 속성)은 새로 작성된 객체에 추가 할 속성 설명자를 지정하고 해당하는 이 속성은 Object.defineProperties ()의 두 번째 인수에 해당합니다.

반환 값

지정된 프로토 타입 개체 및 속성을 가진 새 개체입니다.

예외

proto 파라미터가 null 또는 객체가 아닌 경우는 TypeError 예외입니다.

프로토 타이프 상속

prototype 이라는 일반 객체가 있다고 가정 해 보겠습니다.

var prototype = { foo: 'foo', bar: function () { return this.foo; } };

이제 prototype 을 상속 한 obj 라는 다른 객체가 필요합니다. prototype이 obj 의 프로토 prototype 이라고 말하는 것과 같습니다.

var obj = Object.create(prototype);

이제 prototype 모든 속성과 메서드를 obj 사용할 수 있습니다.

console.log(obj.foo);
console.log(obj.bar());

콘솔 출력

"foo"
"foo"

Prototypal 상속은 내부적으로 객체 참조를 통해 이루어지며 객체는 완전히 변경 가능합니다. 즉, 프로토 타입에 대한 모든 변경 사항은 프로토 타입이 프로토 타입 인 다른 모든 개체에 즉시 영향을줍니다.

prototype.foo = "bar";
console.log(obj.foo);

콘솔 출력

"bar"

Object.prototype 은 모든 객체의 프로토 타입이므로 특히 제 3 자 라이브러리를 사용하는 경우에는 사용하지 않는 것이 좋습니다.하지만 조금만 더 할 수 있습니다.

Object.prototype.breakingLibraries = 'foo';
console.log(obj.breakingLibraries);
console.log(prototype.breakingLibraries);

콘솔 출력

"foo"
"foo"

재미있는 사실 나는이 예제를 만들기 위해 브라우저 콘솔을 사용했고 breakingLibraries 속성을 추가하여이 페이지를 breakingLibraries .


의사 고전적 상속

Prototype이 얼마나 강력한지를 보여주는 프로토 타입 상속 을 사용하여 고전적인 상속을 에뮬레이션합니다. 그것은 다른 언어에서 오는 프로그래머에게 더 매력적인 언어로 만들어졌습니다.

6

중요 사항 : ES6 이후로 언어가 일반 클래스를 시뮬레이트하기 때문에 의사 - 상속적인 상속을 사용하는 것이 타당하지 않습니다. ES6를 사용하고 있지 않다면, 해야합니다 . 여전히 고전적인 상속 패턴을 사용하고 ECMAScript 5 이하 환경에 있으면 의사 클래식이 최선의 방법입니다.

"클래스"는 new 피연산자와 함께 호출되도록 만들어진 함수이며 생성자로 사용됩니다.

function Foo(id, name) {
    this.id = id;
    this.name = name;
}

var foo = new Foo(1, 'foo');
console.log(foo.id);

콘솔 출력

1

foo는 Foo의 인스턴스입니다. JavaScript 코딩 규칙에 따르면 함수가 대문자로 시작하면 생성자 ( new 피연산자가있는)로 호출 할 수 있습니다.


"클래스"에 속성이나 메서드를 추가하려면 프로토 타입에 추가해야합니다.이 프로토 타입은 생성자의 prototype 속성에서 찾을 수 있습니다.

Foo.prototype.bar = 'bar';
console.log(foo.bar);

콘솔 출력

실제로 Foo가 "생성자"로서 수행하는 것은 프로토 타입으로 Foo.prototype 을 사용하여 객체를 만드는 것입니다.


모든 객체에서 해당 생성자에 대한 참조를 찾을 수 있습니다.

console.log(foo.constructor);

함수 Foo (id, name) {...

console.log({ }.constructor);

function Object () {[native code]}

또한 객체가 instanceof 연산자를 사용하여 지정된 클래스의 인스턴스인지 확인합니다.

console.log(foo instanceof Foo);

참된

console.log(foo instaceof Object);

참된

객체의 프로토 타입 설정하기

5

ES5 +를 사용하면 Object.create 함수를 사용하여 다른 객체가있는 객체를 프로토 타입으로 만들 수 있습니다.

const anyObj = {
    hello() {
        console.log(`this.foo is ${this.foo}`);
    },
};

let objWithProto = Object.create(anyObj);
objWithProto.foo = 'bar';

objWithProto.hello(); // "this.foo is bar"

프로토 타입이없는 Object를 명시 적으로 만들려면 프로토 타입으로 null 을 사용합니다. 즉, Object는 Object.prototype 에서 상속받지 않으며 존재 확인 사전에 사용되는 Object에 유용합니다.

let objInheritingObject = {};
let objInheritingNull = Object.create(null);

'toString' in objInheritingObject; // true
'toString' in objInheritingNull ; // false
6

ES6에서 Object.setPrototypeOf 사용하여 기존 Object의 프로토 타입을 변경할 수 있습니다 (예 :

let obj = Object.create({foo: 'foo'});
obj = Object.setPrototypeOf(obj, {bar: 'bar'});

obj.foo; // undefined
obj.bar; // "bar"

이것은에 포함, 거의 모든 곳에서 할 수있는 this 객체 또는 생성자에.

참고 : 이 프로세스는 현재 브라우저에서 매우 느리고 사용하지 말고 원하는 프로토 타입으로 Object를 작성하십시오.

5

ES5 이전에는 수동으로 정의 된 프로토 타입으로 Object를 만드는 유일한 방법은 예를 들어 new 로 구성하는 것이 었습니다

var proto = {fizz: 'buzz'};

function ConstructMyObj() {}
ConstructMyObj.prototype = proto;

var objWithProto = new ConstructMyObj();
objWithProto.fizz; // "buzz"

이 동작은 Poly.cill을 작성할 수있는 Object.create 충분히 가깝습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow