객체지향이란 무엇인가요? 객체지향은 생각이다! (무의미한 말).
객체지향은 프로그램의 핵심 모듈을 객체로 간주할 수 있으며, 모듈에는 속성과 메소드가 있습니다. 이런 식으로 일부 속성과 메서드를 캡슐화하면 향후 사용이 매우 편리할 것이며 지루하고 반복적인 작업을 피할 수도 있습니다. 다음으로 JS에서의 객체지향 구현에 대해 설명하겠습니다.
공장 모드
팩토리 패턴은 소프트웨어 엔지니어링 분야에서 잘 알려진 디자인 패턴입니다. ECMAScript에서는 클래스를 생성할 수 없기 때문에 특정 인터페이스를 가진 객체를 생성하려면 함수 캡슐화를 사용합니다. 구현 방법은 매우 간단합니다. 즉, 함수 내에서 개체를 만들고 개체에 속성과 메서드를 할당한 다음 개체를 반환합니다.
function createBlog(name, url) { var o = new Object(); o.name = name; o.url = url; o.sayUrl= function() { alert(this.url); } return o; } var blog1 = createBlog('wuyuchang', 'http://www.jb51.net/');
팩토리 패턴의 구현 방법은 매우 간단하여 유사한 객체를 여러 개 생성하는 문제를 해결한 것을 알 수 있습니다. 그러나 팩토리 패턴은 Date, Array, Array와 달리 모두 객체이기 때문에 객체의 유형을 식별할 수 없습니다. 등등, 그래서 생성자 패턴이 있습니다.
생성자 패턴
ECMAScript의 생성자는 Array 및 Date와 같은 기본 JS 객체와 유사한 특정 유형의 객체를 생성할 수 있습니다. 구현 방법은 다음과 같습니다.
function Blog(name, url) { this.name = name; this.url = url; this.alertUrl = function() { alert(this.url); } } var blog = new Blog('wuyuchang', 'http://www.jb51.net/'); console.log(blog instanceof Blog); // true, 判断blog是否是Blog的实例,即解决了工厂模式中不能
이 예제와 공장 모델의 함수 이름이 다르다는 점을 제외하면 주의 깊은 아이들은 많은 차이점을 발견할 수 있습니다.
함수 이름의 첫 글자는 대문자여야 합니다. (표준에서는 첫 글자를 대문자로 써야 한다고 엄격하게 요구하지는 않지만, 관례적으로 생성자의 첫 글자는 대문자로 써야 합니다.
생성된 개체가 표시되지 않습니다
이 개체에 속성과 메서드를 직접 할당
반품 명세서 없음
new를 사용하여 객체 생성
객체 인식 가능(여기서 생성자 패턴이 팩토리 패턴보다 우수함)
생성자는 사용하기 쉽지만 단점이 없는 것은 아닙니다. 생성자를 사용할 때 가장 큰 문제는 인스턴스가 생성될 때마다 메서드를 다시 생성해야 한다는 것입니다(이론적으로 객체의 속성은 다음과 같습니다). 객체가 생성될 때마다 다릅니다. 객체의 메소드는 동일하지만 정확히 동일한 메소드를 두 번 생성할 필요는 없으므로 객체 외부로 함수를 이동할 수 있습니다(어쩌면 일부 어린이는 이미 단점을 보았을 수도 있습니다. 우우!).
function Blog(name, url) { this.name = name; this.url = url; this.alertUrl = alertUrl; } function alertUrl() { alert(this.url); } var blog = new Blog('scjb51', 'http://sc.jb51.net/'), blog2 = new Blog('jb51', 'http://www.jb51.net/'); blog.alertUrl(); // http://sc.jb51.net/ blog2.alertUrl(); // http://www.jb51.net/
alertUrl을 전역 함수로 설정하여 blog와 blog2가 동일한 기능에 액세스하도록 했습니다. 그러나 문제는 실제로 Blog에서만 사용되는 함수를 전역 범위에서 정의합니다. 좀 더 수용하기 어려운 점은 특정 객체에서만 사용되는 많은 메서드가 전역 범위에 정의되어 있다는 점입니다. 공간 낭비는 말할 것도 없고 객체 지향 캡슐화도 손실되므로 이 문제는 프로토타입을 통해 해결할 수 있습니다. . 질문.
프로토타입 모드
우리가 만드는 모든 함수에는 객체에 대한 포인터인 프로토타입 속성이 있으며, 이 객체의 목적은 특정 유형의 모든 인스턴스에서 공유할 수 있는 속성과 메서드를 포함하는 것입니다. 프로토타입 객체를 사용하면 모든 객체 인스턴스가 포함된 속성과 메서드를 공유할 수 있다는 장점이 있습니다.
function Blog() { } Blog.prototype.name = 'wuyuchang'; Blog.prototype.url = 'http://tools.jb51.net/'; Blog.prototype.friend = ['fr1', 'fr2', 'fr3', 'fr4']; Blog.prototype.alertInfo = function() { alert(this.name + this.url + this.friend ); } // 以下为测试代码 var blog = new Blog(), blog2 = new Blog(); blog.alertInfo(); // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4 blog2.alertInfo(); // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4 blog.name = 'wyc1'; blog.url = 'http://***.com'; blog.friend.pop(); blog2.name = 'wyc2'; blog2.url = 'http://+++.com'; blog.alertInfo(); // wyc1http://***.comfr1,fr2,fr3 blog2.alertInfo(); // wyc2http://+++.comfr1,fr2,fr3
프로토타입 패턴에는 단점이 있습니다. 우선 초기화 매개변수를 전달하는 생성자를 생략하므로 기본적으로 모든 인스턴스가 동일한 속성 값을 얻습니다. 이는 매우 불편합니다. 아직 프로토타입이 아닙니다. 프로토타입 패턴의 가장 큰 문제는 공유의 특성 때문에 발생합니다. 한 인스턴스가 참조를 수정하면 다른 인스턴스도 참조를 변경합니다. 그래서 보통 프로토타입만 단독으로 사용하지 않고 프로토타입 패턴과 생성자 패턴을 결합하여 사용하는 경우가 많습니다.
혼합 모드(프로토타입 모드, 생성자 모드)
function Blog(name, url, friend) { this.name = name; this.url = url; this.friend = friend; } Blog.prototype.alertInfo = function() { alert(this.name + this.url + this.friend); } var blog = new Blog('wuyuchang', 'http://tools.jb51.net/', ['fr1', 'fr2', 'fr3']), blog2 = new Blog('wyc', 'http://**.com', ['a', 'b']); blog.friend.pop(); blog.alertInfo(); // wuyuchanghttp://tools.jb51.net/fr1,fr2 blog2.alertInfo(); // wychttp://**.coma,b
혼합 모드에서는 생성자 모드를 사용하여 인스턴스 속성을 정의하고, 프로토타입 모드를 사용하여 메서드 및 공유 속성을 정의합니다. 각 인스턴스에는 고유한 인스턴스 속성이 있지만 동시에 메서드를 공유하여 메모리를 최대한 절약합니다. 또한 이 모드는 초기 매개변수 전달도 지원합니다. 장점은 많습니다. 이 모드는 ECMAScript에서 사용자 정의 객체를 생성하는 가장 널리 사용되고 인식되는 방법입니다.
동적 프로토타입 모드
동적 프로토타입 모드는 생성자에 모든 정보를 캡슐화하고 생성자에서 프로토타입을 초기화함으로써(첫 번째 객체가 인스턴스화될 때 프로토타입만 초기화됨) 메소드가 맞는지 여부를 판단하여 프로토타입 초기화 여부를 선택할 수 있습니다. 유효한. .
function Blog(name, url) { this.name = name; this.url = url; if (typeof this.alertInfo != 'function') { // 这段代码只执行了一次 alert('exe time'); Blog.prototype.alertInfo = function() { alert(thia.name + this.url); } } } var blog = new Blog('wuyuchang', 'http://tools.jb51.net'), blog2 = new Blog('wyc', 'http:***.com');
위의 예에서 창은 '실행 시간', 즉 블로그가 초기화될 때 한 번만 나타나는 것을 볼 수 있습니다. 이런 식으로 blog2는 더 이상 프로토타입을 초기화할 필요가 없습니다. 이 모드를 사용하여 객체를 생성합니다.
이 블로그 게시물은 "JavaScript를 사용한 고급 프로그래밍 " 제3판을 참조하고 있지만, 언어를 단순화하고 예제를 다시 작성했습니다. 이해가 안 되는 부분이 있으면 남겨주세요. 답장을 보내면 작성자가 블로그를 업데이트할 것입니다.