>  기사  >  웹 프론트엔드  >  JavaScript가 객체를 생성하는 다양한 방법과 그 장단점에 대한 심층적인 이해

JavaScript가 객체를 생성하는 다양한 방법과 그 장단점에 대한 심층적인 이해

黄舟
黄舟원래의
2017-06-04 10:38:371276검색

이 글에서는 JavaScript객체 생성의 다양한 방법과 장점, 단점을 주로 소개합니다. 관심 있는 분들은 5가지 방법을 위주로 소개합니다.

앞에 적어주세요

객체를 생성하는 다양한 방법에 대해 장단점을 설명합니다.

하지만 참고:

이 기사는 "JavaScript 고급 프로그래밍"이 너무 잘 작성되었기 때문에 참고에 가깝습니다!

1. Factory Pattern

function createPerson(name) {
  var o = new Object();
  o.name = name;
  o.getName = function () {
    console.log(this.name);
  };

  return o;
}

var person1 = createPerson('kevin');

단점: 모든 인스턴스가 프로토타입을 가리키므로 개체를 식별할 수 없습니다.

2. ConstructorPattern

function Person(name) {
  this.name = name;
  this.getName = function () {
    console.log(this.name);
  };
}

var person1 = new Person('kevin');

장점: 인스턴스를 특정 유형으로 식별할 수 있습니다.

단점: 인스턴스가 생성될 때마다 각 메소드를 한 번 생성해야 합니다.

2.1 생성자 패턴 최적화

function Person(name) {
  this.name = name;
  this.getName = getName;
}

function getName() {
  console.log(this.name);
}

var person1 = new Person('kevin');

장점: 각 메소드를 다시 생성해야 하는 문제를 해결

단점: 이것이 캡슐화라는 것입니다.. .

3. 프로토타입 모드

function Person(name) {

}

Person.prototype.name = 'keivn';
Person.prototype.getName = function () {
  console.log(this.name);
};

var person1 = new Person();

장점: 메서드가 다시 생성되지 않습니다.

단점: 1. 모든 속성 및 메서드가 공유됩니다. 2. 매개변수를 초기화할 수 없습니다

3.1 프로토타입 패턴 최적화

아아아아

장점: 더 나은 캡슐화

단점: 프로토타입을 다시 작성하고 생성자 속성을 잃었습니다.

3.2 프로토타입 모드 최적화

function Person(name) {

}

Person.prototype = {
  name: 'kevin',
  getName: function () {
    console.log(this.name);
  }
};

var person1 = new Person();

장점: 인스턴스는 생성자 속성을 통해 생성자를 찾을 수 있습니다.

단점: 여전히 몇 가지 단점이 있습니다. 프로토타입 패턴

4. 구성 패턴

생성자 패턴과 프로토타입 패턴은 두 개의 검이 결합된 것입니다.

function Person(name) {

}

Person.prototype = {
  constructor: Person,
  name: 'kevin',
  getName: function () {
    console.log(this.name);
  }
};

var person1 = new Person();

장점: 공유 공유, 비공개 비공개, 가장 널리 사용되는 방법

단점: 어떤 사람들은 모든 것을 함께 작성하고 싶어합니다. 즉, 더 나은 캡슐화입니다.

4.1 동적 프로토타입 모드

function Person(name) {
  this.name = name;
}

Person.prototype = {
  constructor: Person,
  getName: function () {
    console.log(this.name);
  }
};

var person1 = new Person();

참고: 동적 프로토타입 모드에서는 프로토타입을 객체 리터럴로 재정의할 수 없습니다.

이유를 설명하세요:

function Person(name) {
  this.name = name;
  if (typeof this.getName != "function") {
    Person.prototype.getName = function () {
      console.log(this.name);
    }
  }
}

var person1 = new Person();

이 문제를 설명하려면 var person1 = new Person('kevin')이 시작되었다고 가정하세요.

new 및 Apply의 기본 실행 프로세스가 잘 익숙하지 않은 경우 하단의 관련 링크에서 기사를 읽을 수 있습니다.

new의 구현 단계를 검토해 보겠습니다.

  1. 먼저 새 개체를 만듭니다

  2. 그런 다음 개체의 프로토타입을 Person.prototype

  3. 으로 가리킨 다음 Person.apply(obj)

  4. 이 이 개체를 반환합니다.

이때 Apply 구현 단계를 검토하면 obj.Person 메서드가 실행되고, 이때 생성자의 프로토타입 속성이 실행됩니다. 인스턴스의 프로토타입에서는 리터럴 메서드를 사용하여 Person.prototype을 직접 덮어쓰지만 person1은 여전히 ​​Person.prototype이 아닌 이전 프로토타입을 가리킵니다. 이전 프로토타입에는 getName 메소드가 없어서 오류가 보고되었습니다!

문자 그대로 코드를 작성하고 싶다면 다음을 시도해 보세요:


function Person(name) {
  this.name = name;
  if (typeof this.getName != "function") {
    Person.prototype = {
      constructor: Person,
      getName: function () {
        console.log(this.name);
      }
    }
  }
}
 
var person1 = new Person('kevin');
var person2 = new Person('daisy');
 
// 报错 并没有该方法
person1.getName();
 
// 注释掉上面的代码,这句是可以执行的。
person2.getName();

5.1 기생 생성자 패턴


function Person(name) {
  this.name = name;
  if (typeof this.getName != "function") {
    Person.prototype = {
      constructor: Person,
      getName: function () {
        console.log(this.name);
      }
    }
 
    return new Person(name);
  }
}
 
var person1 = new Person('kevin');
var person2 = new Person('daisy');
 
person1.getName(); // kevin
person2.getName(); // daisy

기생 생성자 패턴은 개인적으로 다음과 같이 읽어야 한다고 생각합니다.

Parasite-constructor-pattern, 즉 생성자에 기생하는 메서드입니다.

즉, 생성자를 가장하여 다른 사람의 머리 위로 양 같은 것을 팔려고 한다는 것입니다. 인스턴스를 사용하여 생성된 인스턴스는 생성자를 가리킬 수 없습니다.

이 방법은 특별한 상황에서 사용할 수 있습니다. 예를 들어, 추가 메서드를 사용하여 특별한 array를 만들고 싶지만 Array 생성자를 직접 수정하고 싶지 않은 경우 다음과 같이 작성할 수 있습니다.


function Person(name) {
 
  var o = new Object();
  o.name = name;
  o.getName = function () {
    console.log(this.name);
  };
 
  return o;
 
}
 
var person1 = new Person('kevin');
console.log(person1 instanceof Person) // false
console.log(person1 instanceof Object) // true

다음과 같이 작성할 수 있습니다. 기생 생성자 패턴이라고 불리는 것이 실제로 팩토리보다 낫습니다. 패턴은 객체를 생성할 때 하나의 새로운 패턴을 더 사용합니다. 실제로 두 가지의 결과는 동일합니다.

그러나 작성자는 SpecialArray를 일반 배열처럼 사용하기를 원할 수도 있지만 SpecialArray를 함수로 사용할 수는 있지만 이는 작성자의 의도가 아니며 우아하지 않게 됩니다.

다른 모드를 사용할 수 있는 경우에는 이 모드를 사용하지 마세요.

그러나 위 예의 loop


function SpecialArray() {
  var values = new Array();
 
  for (var i = 0, len = arguments.length; i len; i++) {
    values.push(arguments[i]);
  }
 
  values.toPipedString = function () {
    return this.join("|");
  };
  return values;
}
 
var colors = new SpecialArray('red', 'blue', 'green');
var colors2 = SpecialArray('red2', 'blue2', 'green2');
 
 
console.log(colors);
console.log(colors.toPipedString()); // red|blue|green
 
console.log(colors2);
console.log(colors2.toPipedString()); // red2|blue2|green2

로 대체될 수 있습니다.


for (var i = 0, len = arguments.length; i len; i++) {
  values.push(arguments[i]);
}

5.2 소위 안정적인 생성자 패턴


values.push.apply(values, arguments);

객체, 공용 속성이 없는 객체를 나타내며 해당 메서드는 이를 참조하지 않습니다.

기생 생성자 패턴에는 두 가지 차이점이 있습니다.

  1. 새로 생성된 인스턴스 메서드는 이것을 참조하지 않습니다

  2. 생성자를 호출하기 위해 새로운 연산자를 사용하지 않습니다

안전한 객체는 다음에 가장 적합합니다. 일부 안전 환경.

안전한 생성자 패턴도 팩토리 패턴과 동일하며 객체의 유형을 식별할 수 없습니다.

위 내용은 JavaScript가 객체를 생성하는 다양한 방법과 그 장단점에 대한 심층적인 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.