javascript_javascript 기술로 객체를 생성하는 다양한 모드에 대한 간략한 분석
현재 "JavaScript를 사용한 고급 프로그래밍"(2판)을 읽고 있습니다.
자바스크립트로 객체 생성
•공장 모드
•생성자 패턴
•프로토타입 모드
• 생성자와 프로토타입 패턴 결합
•프로토타입 동적 모드
대부분의 객체지향 언어에는 클래스라는 개념이 있는데, 이를 통해 동일한 메소드와 속성을 가진 여러 객체를 생성할 수 있습니다. 기술적으로 말하면 JavaScript는 객체 지향 언어이지만 JavaScript에는 클래스 개념이 없으며 모든 것이 객체입니다. 모든 객체는 기존 참조 유형을 통해 생성된 특정 참조 유형의 인스턴스입니다. 참조 유형은 기본 유형이거나 사용자 정의될 수 있습니다. 기본 참조 유형에는 개체, 배열, 데이터, RegExp 및 함수가 포함됩니다. ! 참조 유형은 종종 클래스라고 불리는 데이터와 기능을 구성하는 데이터 구조입니다. 클래스 개념이 부족한 자바스크립트에서는 객체를 어떻게 효율적으로 생성하느냐가 해결해야 할 문제이다.
1.1.0. 일반적인 객체 생성 방법
var person = {}; //对象字面量表示,等同于var person = new Objcect(); person.name = 'evansdiy'; person.age = '22'; person.friends = ['ajiao','tiantian','pangzi']; person.logName = function() { console.log(this.name); }
객체 참조 유형을 기반으로 4개의 속성(그 중 하나는 메서드)을 포함하는 객체가 생성됩니다. 사람과 유사한 객체의 인스턴스가 많이 필요한 경우 중복된 코드가 많이 있을 것입니다.
1.1.1.공장 모드 [맨 위로]
객체 세부정보를 담을 수 있는 함수를 통해 객체를 생성한 후 이 객체를 반환합니다.
function person(name,age,friends) { var o = { name: name, age: age, friends: friends, logName: function() { console.log(this.name); } }; return o; } var person1 = person('Evansdiy','22',['ajiao','tiantian','pangzi']);
person 함수가 호출될 때마다 함수 내부의 객체 o를 통해 새로운 객체가 생성된 후 반환됩니다. 이 외에 새로운 객체를 생성하기 위해 존재하는 내부 객체 o는 다른 용도는 없습니다. 또한, 팩토리 패턴으로 생성된 객체의 유형을 판별하는 것도 불가능합니다.
1.1.2 생성자 패턴 [위로]
function Person(name,age,job) { this.name = name; this.age = age; this.job = job; this.logName = function() { console.log(this.name); } } //通过new操作符创建Person的实例 var person1 = new Person('boy-a','22','worker'); var person2 = new Person('girl-b','23','teacher'); person1.logName(); //boy-a person2.logName(); //girl-a
팩토리 패턴을 비교해 보면 여기서는 중간 객체를 생성할 필요도 없고 반환값도 없다는 것을 알 수 있습니다. 또한, 생성자의 인스턴스를 특정 타입으로 식별할 수 있어 객체 식별 문제를 해결한다(인스턴스의 생성자 속성을 확인하거나, 인스턴스가 특정 생성자를 통해 생성되었는지 여부를 instanceof 연산자를 사용하여 확인). .
console.log(person1.constructor == Person);//constructor는 생성자 프로토타입에 위치하며 생성자를 가리키며 결과는 true입니다
console.log(person1instanceofPerson);//instanceof 연산자를 사용하여 person1이 Person 생성자의 인스턴스인지 확인합니다. 그러나 생성자 모드에도 자체 문제가 있습니다. 실제로 logName 메서드가 다시 시작됩니다. 인스턴스화로 생성된 메서드는 동일하지 않습니다. 다음 코드는 false가 됩니다.
console.log(person1.logName == person2.logName);//false메서드를 생성자 외부로 이동하여(전역 함수가 됨) 이 문제를 해결할 수 있습니다.
function logName() { console.log(this.name); } function logAge() { console.log(this.age); }
1.1.3. 프로토타입 모드 [상위]
JavaScript의 모든 함수에는 프로토타입 속성에 대한 포인터가 포함되어 있습니다(대부분의 브라우저는 내부 속성 __proto__를 통해 액세스할 수 있음). 프로토타입 속성은 특정 참조 유형에 의해 생성된 모든 인스턴스를 포함하는 객체입니다.
function Person() {} Person.name = 'evansdiy'; Person.prototype.friends = ['ajiao','jianjian','pangzi']; Person.prototype.logName = function() { console.log(this.name); } var person1 = new Person(); person1.logName();//'evansdiy'
위 코드는 다음 작업을 수행합니다.
1. 생성자 함수 Person이 정의되고 Person 함수는 기본적으로 Person을 가리키는 생성자 속성만 포함하는 프로토타입 속성을 가져옵니다.2. Person.prototype을 통해 세 가지 속성을 추가합니다. 그 중 하나는 메서드입니다.
3. Person 인스턴스를 생성한 다음 인스턴스에서 logName() 메서드를 호출합니다.여기서 주목해야 할 것은 logName() 메소드의 호출 프로세스입니다:
1. person1 인스턴스에서 logName() 메서드를 찾아 해당 메서드가 없음을 확인하고 이를 person1의 프로토타입으로 추적합니다.
2. person1의 프로토타입에서 logame() 메소드를 찾습니다. 이 메소드를 호출하는 것은 이러한 검색 프로세스를 기반으로 동일 이름 속성을 정의하여 인스턴스가 프로토타입에 액세스하는 것을 방지할 수 있습니다. 이름이 같은 속성을 삭제하면 프로토타입에서 이름이 같은 속성이 삭제되지 않고 인스턴스 액세스만 차단된다는 점에 유의해야 합니다.
var person2 = new Person();
person2.name = 'laocai'; 인스턴스에 더 이상 속성이 필요하지 않으면 삭제 연산자를 통해 삭제할 수 있습니다.
person2.name 삭제; for-in 루프를 사용하여 인스턴스가 액세스할 수 있는 모든 속성(속성이 인스턴스 또는 프로토타입에 있는지 여부)을 열거합니다.
同时,也可以利用hasOwnProperty()方法判断某个属性到底存在于实例上,还是存在于原型中,只有当属性存在于实例中,才会返回true:
console.log(person1.hasOwnProperty('name'));//true!hasOwnProperty来自Object的原型,是javascript中唯一一个在处理属性时不查找原型链的方法。[via javascript秘密花园] 另外,也可以通过同时使用in操作符和hasOwnProperty()方法来判断某个属性存在于实例中还是存在于原型中:
console.log(('friends' in person1) && !person1.hasOwnProperty('friends'));先判断person1是否可以访问到friends属性,如果可以,再判断这个属性是否存在于实例当中(注意前面的!),如果不存在于实例中,就说明这个属性存在于原型中。 前面提到,原型也是对象,所以我们可以用对象字面量表示法书写原型,之前为原型添加代码的写法可以修改为:
Person.prototype = { name: 'evansdiy', friends: ['ajiao','jianjian','pangzi'], logName: function() { console.log(this.name); } }
由于对象字面量语法重写了整个prototype原型,原先创建构造函数时默认取得的constructor属性会指向Object构造函数:
//对象字面量重写原型之后
console.log(person1.constructor);//Object不过,instanceof操作符仍会返回希望的结果:
//对象字面量重写原型之后
console.log(person1 instanceof Person);//true当然,可以在原型中手动设置constructor的值来解决这个问题。
Person.prototype = { constructor: Person, ...... }
如果在创建对象实例之后修改原型对象,那么对原型的修改会立即在所有对象实例中反映出来:
function Person() {}; var person1 = new Person(); Person.prototype.name = 'evansdiy'; console.log(person1.name);//'evansdiy'
实例和原型之间的连接仅仅是一个指针,而不是一个原型的拷贝,在原型实际上是一次搜索过程,对原型对象的所做的任何修改都会在所有对象实例中反映出来,就算在创建实例之后修改原型,也是如此。 如果在创建对象实例之后重写原型对象,情况又会如何?
function Person() {}; var person1 = new Person1();//创建的实例引用的是最初的原型 //重写了原型 Person.prototype = { friends: ['ajiao','jianjian','pangzi'] } var person2 = new Person();//这个实例引用新的原型 console.log(person2.friends); console.log(person1.friends);
以上代码在执行到最后一行时会出现未定义错误,如果我们用for-in循环枚举person1中的可访问属性时,会发现,里头空无一物,但是person2却可以访问到原型上的friends属性。 !重写原型切断了现有原型与之前创建的所有对象实例的联系,之前创建的对象实例的原型还在,只不过是旧的。
//创建person1时,原型对象还未被重写,因此,原型对象中的constructor还是默认的Person()
console.log(person1.constructor);//Person()
//但是person2的constructor指向Object()
console.log(person2.constructor);//Object()需要注意的是,原型模式忽略了为构造函数传递参数的过程,所有的实例都取得相同的属性值。同时,原型模式还存在着一个很大的问题,就是原型对象中的引用类型值会被所有实例共享,对引用类型值的修改,也会反映到所有对象实例当中。
function Person() {}; Person.prototype = { friends: ['ajiao','tiantian','pangzi'] } var person1 = new Person(); var person2 = new Person(); person1.friends.push('laocai'); console.log(person2.friends);//['ajiao','tiantian','pangzi','laocai']
修改person1的引用类型值friends,意味着person2中的friends也会发生变化,实际上,原型中保存的friends实际上只是一个指向堆中friends值的指针(这个指针的长度是固定的,保存在栈中),实例通过原型访问引用类型值时,也是按指针访问,而不是访问各自实例上的副本(这样的副本并不存在)。
1.1.4.结合构造函数和原型模式创建对象 [top]
结合构造函数和原型模式的优点,弥补各自的不足,利用构造函数传递初始化参数,在其中定义实例属性,利用原型定义公用方法和公共属性,该模式应用最为广泛。
function Person(name,age) { this.name = name; this.age = age; this.friends = ['ajiao','jianjian','pangzi']; } Person.prototype = { constructor: Person, logName: function() { console.log(this.name); } } var person1 = new Person('evansdiy','22'); var person2 = new Person('amy','21'); person1.logName();//'evansdiy' person1.friends.push('haixao'); console.log(person2.friends.length);//3
1.1.5.原型动态模式 [top]
原型动态模式将需要的所有信息都封装到构造函数中,通过if语句判断原型中的某个属性是否存在,若不存在(在第一次调用这个构造函数的时候),执行if语句内部的原型初始化代码。
function Person(name,age) { this.name = name; this.age = age; if(typeof this.logName != 'function') { Person.prototype.logName = function() { console.log(this.name); }; Person.prototype.logAge = function() { console.log(this.age); }; }; } var person1 = new Person('evansdiy','22');//初次调用构造函数,此时修改了原型 var person2 = new Person('amy','21');//此时logName()方法已经存在,不会再修改原型
需要注意的是,该模式不能使用对象字面量语法书写原型对象(这样会重写原型对象)。若重写原型,那么通过构造函数创建的第一实例可以访问的原型对象不会包含if语句中的原型对象属性。
function Person(name,age) { this.name = name; this.age = age; if(typeof this.logName != 'function') { Person.prototype = { logName: function() { console.log(this.name); }, logAge: function() { console.log(this.Age); } } }; } var person1 = new Person('evansdiy','22'); var person2 = new Person('amy','21'); person2.logName();//'amy' person1.logName();//logName()方法不存在
需要说明的是,各模式都有自己的应用场景,无所谓优劣。
以上这篇浅析在javascript中创建对象的各种模式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











해결 방법: 1. 철자 및 경로를 확인합니다. 3. 레지스트리를 확인합니다. 5. Office를 업데이트하거나 복구합니다. 7. 다른 버전의 구성 요소를 사용합니다. 9. 다른 해결 방법을 찾아보세요. 자세한 소개: 1. 철자 및 경로 확인: 개체의 이름과 경로에 철자 오류가 없는지, 파일이 지정된 경로에 존재하는지 확인합니다. 2. 구성 요소 등에 대한 참조를 추가합니다.

WebSocket 및 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 소개: 지속적인 기술 개발로 음성 인식 기술은 인공 지능 분야의 중요한 부분이 되었습니다. WebSocket과 JavaScript를 기반으로 한 온라인 음성 인식 시스템은 낮은 대기 시간, 실시간, 크로스 플랫폼이라는 특징을 갖고 있으며 널리 사용되는 솔루션이 되었습니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법을 소개합니다.

WebSocket과 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 서론: 인터넷 기술의 급속한 발전과 함께 실시간 모니터링 시스템이 다양한 분야에서 널리 활용되고 있다. 실시간 모니터링을 구현하는 핵심 기술 중 하나는 WebSocket과 JavaScript의 조합입니다. 이 기사에서는 실시간 모니터링 시스템에서 WebSocket 및 JavaScript의 적용을 소개하고 코드 예제를 제공하며 구현 원칙을 자세히 설명합니다. 1. 웹소켓 기술

WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법 오늘날의 디지털 시대에는 점점 더 많은 기업과 서비스에서 온라인 예약 기능을 제공해야 합니다. 효율적인 실시간 온라인 예약 시스템을 구현하는 것이 중요합니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. WebSocket이란 무엇입니까? WebSocket은 단일 TCP 연결의 전이중 방식입니다.

JavaScript 및 WebSocket을 사용하여 실시간 온라인 주문 시스템을 구현하는 방법 소개: 인터넷의 대중화와 기술의 발전으로 점점 더 많은 레스토랑에서 온라인 주문 서비스를 제공하기 시작했습니다. 실시간 온라인 주문 시스템을 구현하기 위해 JavaScript 및 WebSocket 기술을 사용할 수 있습니다. WebSocket은 TCP 프로토콜을 기반으로 하는 전이중 통신 프로토콜로 클라이언트와 서버 간의 실시간 양방향 통신을 실현할 수 있습니다. 실시간 온라인 주문 시스템에서는 사용자가 요리를 선택하고 주문을 하면

JavaScript 및 WebSocket: 효율적인 실시간 일기 예보 시스템 구축 소개: 오늘날 일기 예보의 정확성은 일상 생활과 의사 결정에 매우 중요합니다. 기술이 발전함에 따라 우리는 날씨 데이터를 실시간으로 획득함으로써 보다 정확하고 신뢰할 수 있는 일기예보를 제공할 수 있습니다. 이 기사에서는 JavaScript 및 WebSocket 기술을 사용하여 효율적인 실시간 일기 예보 시스템을 구축하는 방법을 알아봅니다. 이 문서에서는 특정 코드 예제를 통해 구현 프로세스를 보여줍니다. 우리

JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법, 특정 코드 예제가 필요합니다. 서문: 웹 개발에서는 서버와의 데이터 상호 작용이 종종 포함됩니다. 서버와 통신할 때 반환된 HTTP 상태 코드를 가져와서 작업의 성공 여부를 확인하고 다양한 상태 코드에 따라 해당 처리를 수행해야 하는 경우가 많습니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법과 몇 가지 실용적인 코드 예제를 제공합니다. XMLHttpRequest 사용

사용법: JavaScript에서 insertBefore() 메서드는 DOM 트리에 새 노드를 삽입하는 데 사용됩니다. 이 방법에는 삽입할 새 노드와 참조 노드(즉, 새 노드가 삽입될 노드)라는 두 가지 매개 변수가 필요합니다.
