>웹 프론트엔드 >JS 튜토리얼 >JavaScript의 객체 지향 프로그래밍에 대한 자세한 소개

JavaScript의 객체 지향 프로그래밍에 대한 자세한 소개

黄舟
黄舟원래의
2017-03-04 15:54:001019검색

소개

JavaScript는 강력한 객체 지향 프로그래밍 언어이지만 기존 프로그래밍 언어와는 달리 프로토타입 기반 OOP 모델을 사용하므로 대부분의 사람들이 구문을 이해하기 어렵습니다. 개발자. 또한 JavaScript는 함수를 기본 개체로 처리하므로 언어에 익숙하지 않은 개발자에게 더 큰 혼란을 초래할 수 있습니다. 그래서 우리는 이 책을 간략한 소개로 앞부분에 두기로 결정했으며, JavaScript의 객체지향 프로그래밍에 대한 참고 자료로도 사용할 수 있습니다.

이 문서는 객체 지향 프로그래밍 규칙에 대한 미리보기를 제공하지 않지만 해당 인터페이스에 대한 개요를 제공합니다.

네임스페이스

타사 라이브러리, 프레임워크 및 웹 종속성이 점점 더 많이 등장함에 따라 JavaScript 개발에서는 네임스페이스가 필수적입니다. 전역 네임스페이스 개체와 네임스페이스 간의 충돌을 피하려고 노력해야 합니다. 변수.

안타깝게도 JavaScript는 네임스페이스 컴파일을 지원하지 않지만 객체를 사용하여 동일한 결과를 얻을 수 있습니다. JavaScript에는 네임스페이스 인터페이스를 구현하기 위한 많은 패턴이 있지만 이 분야에서 가장 일반적으로 사용되는 패턴인 중첩된 네임스페이스도 다룹니다.

중첩 네임스페이스

중첩 네임스페이스 패턴은 객체 리터럴을 사용하여 특정 애플리케이션에 대한 특정 이름으로 기능을 번들링합니다.

처음에는 전역 개체를 생성하고 이를 MyApp이라는 변수에 할당합니다.

// global namespace
var MyApp = MyApp || {};

위 구문은 MyApp이 정의되었는지 확인합니다. 이미 정의된 경우 이를 우리 자신에게 할당하기만 하면 됩니다. 대신 함수와 변수를 담을 빈 컨테이너를 만듭니다.

동일한 기술을 사용하여 하위 네임스페이스를 만들 수도 있습니다. 예:

// sub namespaces
MyApp.users = MyApp.user || {};

컨테이너를 시작하면 (컨테이너) 내부에서 함수와 변수를 정의하고 기존 정의와 충돌할 위험 없이 전역 네임스페이스에서 호출할 수 있습니다.

// declarations

MyApp.users = {

	existingUsers: '', // variable in namespace

	renderUsersHTML: function() { // function in namespace

		// render html list of users

	}

};

// syntax for using functions within our namespace from the global scope

MyApp.users.renderUsersHTML();

JavaScript 이름 지정 패턴에 대한 내부 개요는 Goggle의 Addy Osmani가 필수 JavaScript 네임스페이스 패턴 문서에서 소개했습니다. 다양한 모드를 탐색하고 싶다면 여기가 시작하기에 좋은 장소가 될 것입니다.

객체

JavaScript 코드를 작성해 본 적이 있다면 이미 객체를 사용해 본 것입니다. JavaScript에는 세 가지 유형의 개체가 있습니다.

네이티브 개체

네이티브 개체는 언어 사양의 일부이며 실행되는 실행 환경에 관계없이 사용할 수 있습니다. 기본 객체에는 Array, Date, Math,parseInt 등이 포함됩니다. 모든 기본 개체에 대해 알아보려면 JavaScript 내장 개체 참조

var cars = Array(); // Array is a native object

호스트 개체

를 참조하세요. 기본 개체와 달리 호스트 개체는 JavaScript 코드가 실행되는 환경에 의해 생성됩니다. 환경에 따라 서로 다른 호스트 개체가 생성됩니다. 이러한 호스트 개체를 사용하면 대부분의 경우 상호 작용할 수 있습니다. 실행 환경 중 하나인 브라우저에서 실행되는 코드를 작성하면 창, 문서, 위치, 기록과 같은 호스트 개체가 있을 것입니다.

document.body.innerHTML = 'Hello World!'; // document is a host object

// the document object will not be available in a 
// stand-alone environments such as Node.js

사용자 개체

사용자 개체(또는 이식된 개체)는 코드에 정의되고 런타임 중에 생성되는 개체입니다. JavaScript로 자신만의 개체를 만드는 방법에는 두 가지가 있으며 아래에 자세히 설명되어 있습니다.

객체 리터럴

네임스페이스 생성에 대한 이전 데모에서 우리는 이미 객체 리터럴을 접했습니다. 이제 객체 리터럴의 정의를 명확히 해보겠습니다. 객체 리터럴은 중괄호 쌍으로 묶인 이름-값 쌍의 쉼표로 구분된 목록입니다. 객체 리터럴은 변수(속성)와 함수(메서드)를 가질 수 있습니다. JavaScript의 다른 객체와 마찬가지로 함수의 매개변수나 반환 값으로 사용될 수도 있습니다.

이제 객체 리터럴을 정의하고 변수에 할당합니다.

// declaring an object literal

var dog = {

	// object literal definition comes here...

};

이 객체 리터럴에 속성과 메서드를 추가한 다음 전역 범위에서 액세스합니다.

// declaring an object literal

var dog = {

	breed: 'Bulldog', // object literal property

	bark: function() { // object literal method

		console.log("Woof!");

	},

};

// using the object

console.log( dog.breed ); // output Bulldog

dog.bark(); // output Woof!

여기를 보세요. 이전 네임스페이스와 매우 유사해 보이지만 이는 우연이 아닙니다. 리터럴 개체의 가장 일반적인 용도는 전역 범위의 변수나 개체와의 충돌을 피하기 위해 캡슐화된 패키지에 코드를 캡슐화하는 것입니다. 또한 유사한 이유로 구성 매개변수를 플러그인이나 객체에 전달하는 데에도 자주 사용됩니다.

디자인 패턴에 익숙하다면 객체 리터럴은 어느 정도 싱글톤, 즉 인스턴스가 하나만 있는 패턴입니다. 객체 리터럴은 본질적으로 인스턴스화 및 상속 기능이 없습니다. 다음으로 JavaScript에서 사용자 정의 객체를 생성하는 다른 방법을 배워야 합니다.

생성자

생성자 정의

함수는 JavaScript의 일급 시민입니다. 즉, 다른 엔터티에서 지원하는 모든 작업 함수가 지원된다는 의미입니다. JavaScript의 세계에서 함수는 런타임에 동적으로 구성될 수 있고, 매개변수로 사용될 수 있으며, 다른 함수의 반환 값으로 사용될 수 있고, 변수에 할당될 수도 있습니다. 또한 함수에는 고유한 속성과 메서드가 있을 수도 있습니다. JavaScript 함수의 특성상 인스턴스화하고 상속할 수 있습니다.

생성자를 사용하여 사용자 정의 개체를 만드는 방법을 살펴보겠습니다.

// creating a function

function Person( name, email ) {

	// declaring properties and methods using the (this) keyword

	this.name 	= name;
	this.email 	= email;

	this.sayHey = function() {

		console.log( "Hey, I’m " + this.name );

	};

}

// instantiating an object using the (new) keyword

var steve = new Person( "Steve", "steve@hotmail.com" );

// accessing methods and properties

steve.sayHey();

创建构造函数类似于创建普通函数,只有一点例外:用 this 关键字定义自发性和方法。一旦函数被创建,就可以用 new 关键字来生成实例并赋予变量。每次使用 new 关键字,this 都指向一个新的实例。

构建函数实例化和传统面向对象编程语言中的通过类实例化并非完全不同,但是,这里存在一个可能不易被察觉的问题。

当使用 new 关键字创建新对象的时候,函数块会被反复执行,这使得每次运行都会产生新的匿名函数来定义方法。这就像创建新的对象一样,会导致程序消耗更多内存。这个问题在现代浏览器上运行的程序中并不显眼。但随着应用规则地扩大,在旧一点的浏览器、计算机或者低电耗设备中就会出现性能问题。不过不用担心,有更好的办法将方法附加给构造函数(是不会污染全局环境的哦)。

方法和原型

前面介绍中提到 JavaScript 是一种基于原型的编程语言。在 JavaScript 中,可以把原型当作对象模板一样来使用。原型能避免在实例化对象时创建多余的匿名函数和变量。

在 JavaScript 中,prototype 是一个非常特别的属性,可以让我们为对象添加新的属性和方法。现在用原型重写上面的示例看看:

// creating a function

function Person( name, email ) {

	// declaring properties and methods using the (this) keyword

	this.name 	= name;
	this.email 	= email;

}

// assign a new method to the object’s prototype

Person.prototype.sayHey = function() {

	console.log( "Hey, I’m " + this.name );

}

// instantiating a new object using the constructor function

var steve = new Person( "Steve", "steve@hotmail.com" );

// accessing methods and properties

steve.sayHey();

这个示例中,不再为每个 Person 实例定义 sayHey 方法,而是通过原型模板在各实例中共享这个方法。

继承性

通过原型链,原型可以用来实例继承。JavaScript 的每一个对象都有原型,而原型是另外一个对象,也有它自己的原型,周而复始…直到某个原型对象的原型是 null——原型链到此为止。

在访问一个方法或属性的时候,JavaScript 首先检查它们是否在对象中定义,如果不,则检查是否定义在原型中。如果在原型中也没找到,则会延着原型链一直找下去,直到找到,或者到达原型链的终端。

现在来看看代码是怎么实现的。可以从上一个示例中的 Person 对象开始,另外再创建一个叫 Employee 的对象。

// Our person object

function Person( name, email ) {

	this.name 	= name;
	this.email 	= email;

}

Person.prototype.sayHey = function() {

	console.log( "Hey, I’m " + this.name );

}

// A new employee object

function Employee( jobTitle ) {

	this.jobTitle = jobTitle;

}

现在 Employee 只有一个属性。不过既然员工也属于人,我们希望它能从 Person 继承其它属性。要达到这个目的,我们可以在 Employee 对象中调用 Person 的构造函数,并配置原型链。

// Our person object

function Person( name, email ) {

	this.name 	= name;
	this.email 	= email;

}

Person.prototype.sayHey = function() {

	console.log( "Hey, I’m " + this.name );

}

// A new employee object

function Employee( name, email, jobTitle ) {

	// The call function is calling the Constructor of Person
	// and decorates Employee with the same properties

	Person.call( this, name, email );

	this.jobTitle = jobTitle;

}

// To set up the prototype chain, we create a new object using 
// the Person prototype and assign it to the Employee prototype

Employee.prototype = Object.create( Person.prototype );

// Now we can access Person properties and methods through the
// Employee object

var matthew = new Employee( "Matthew", "matthew@hotmail.com", "Developer" );

matthew.sayHey();

要适应原型继承还需要一些时间,但是这一个必须熟悉的重要概念。虽然原型继承模型常常被认为是 JavaScript 的弱点,但实际上它比传统模型更强大。比如说,在掌握了原型模型之后创建传统模型简直就太容易了。

ECMAScript 6 引入了一组新的关键字用于实现 类。虽然新的设计看起来与传统基于类的开发语言非常接近,但它们并不相同。JavaScript 仍然基于原型。

以上就是JavaScript 中的面向对象编程的详细介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!

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