JavaScript에서 클래스를 정의하기 위해 사용할 수 있는 기술과 그 단점은 무엇입니까?
저는 현재 진행 중인 프로젝트와 같은 대규모 프로젝트에서 OOP를 사용하는 것을 선호합니다.JavaScript에서 여러 개의 클래스를 만들어야 하는데, 제가 틀리지 않았다면 적어도 몇 가지 방법이 있습니다.구문은 무엇이고 왜 그런 방식으로 수행됩니까?
적어도 처음에는 서드파티 라이브러리의 사용을 피하고 싶습니다.
다른 답을 찾다가, 자바스크립트를 사용한 객체 지향 프로그래밍, Part I: Inheritance-Doc JavaScript라는 JavaScript의 객체 지향 프로그래밍에 대한 기사를 찾았습니다.상속을 할 수 있는 더 좋은 방법이 있을까요?
외부 라이브러리를 사용하지 않고 이를 수행하는 방법은 다음과 같습니다.
// Define a class like this
function Person(name, gender){
// Add object properties like this
this.name = name;
this.gender = gender;
}
// Add methods like this. All Person objects will be able to invoke this
Person.prototype.speak = function(){
alert("Howdy, my name is" + this.name);
};
// Instantiate new objects with 'new'
var person = new Person("Bob", "M");
// Invoke methods like this
person.speak(); // alerts "Howdy, my name is Bob"
진짜 답은 그것보다 훨씬 더 복잡합니다.자바스크립트는 JavaScript를 합니다.prototype
- scheme - "을 해 주세요.
또한 JavaScript에는 클래스 유사 기능의 근사 스타일을 가진 인기 있는 JavaScript 라이브러리가 많이 있습니다.최소한 프로토타입과 jQuery는 확인해야 합니다.
이 중 어느 것이 가장 좋은지 결정하는 것은 Stack Overflow에 대한 성전을 시작하는 좋은 방법입니다.더 큰 JavaScript 프로젝트를 시작할 경우, 인기 있는 라이브러리를 학습하고 그들의 방식대로 실행할 가치가 있습니다.저는 프로토타입이지만 스택 오버플로는 jQuery에 치우친 것 같습니다.
외부 도서관에 의존하지 않고 '한 가지 방법'밖에 없는 한, 내가 쓰는 방식은 거의 그것이다.
JavaScript에서 클래스를 정의하는 가장 좋은 방법은 클래스를 정의하지 않는 것입니다.
정말이에요.
객체 지향에는 다음과 같은 여러 가지 다른 맛이 있습니다.
- 클래스 베이스 OO(Smalltalk에서 처음 도입)
- 프로토타입 기반 OOO(Self가 처음 도입)
- 멀티모드 기반 OO(CommonLoops에 의해 처음 도입된 것 같습니다)
- 술어 기반 OO(모름)
아마 내가 모르는 다른 사람들도 있을 거야.
JavaScript는 프로토타입 기반의 OO를 구현합니다.프로토타입 기반 OO에서는 클래스 템플릿에서 인스턴스화되지 않고 다른 개체를 복사하여 새로운 개체가 생성되고 메서드는 클래스 대신 개체에서 직접 실행됩니다.상속은 위임을 통해 이루어집니다. 객체에 메서드나 속성이 없는 경우 해당 객체의 프로토타입(즉, 복제한 객체)을 조회한 후 프로토타입의 프로토타입 등을 조회합니다.
즉, 클래스는 없습니다.
JavaScript java java java java java java java::::: : java java java java java java java java java java java java java java java java java java java.기존 오브젝트를 복사하여 오브젝트를 작성할 수 있을 뿐만 아니라 "공기중에서" 작성할 수도 있습니다.「」가 .new
및 "컨스트럭터"가 .this
키워드는 현재 객체를 가리키는 것이 아니라 새로 생성된 "빈" 객체를 가리킵니다.따라서 원하는 방식으로 개체를 구성할 수 있습니다.이러한 방식으로 JavaScript 생성자는 기존 클래스 기반 OO에서 클래스의 역할 중 하나를 맡을 수 있습니다. 즉, 새 개체의 템플릿 또는 청사진 역할을 수행합니다.
현재 JavaScript는 매우 강력한 언어이기 때문에 원한다면 JavaScript 내에서 클래스 기반 OO 시스템을 구현하기가 매우 쉽습니다.단, 이 작업은 Java가 수행하는 방법뿐만 아니라 실제로 필요한 경우에만 수행해야 합니다.
ES2015 클래스
ES2015 사양에서는 클래스 구문을 사용할 수 있습니다. 클래스 구문은 프로토타입 시스템 위에 설탕처럼 표시됩니다.
class Person {
constructor(name) {
this.name = name;
}
toString() {
return `My name is ${ this.name }.`;
}
}
class Employee extends Person {
constructor(name, hours) {
super(name);
this.hours = hours;
}
toString() {
return `${ super.toString() } I work ${ this.hours } hours.`;
}
}
혜택들
주요 장점은 정적 분석 도구가 이 구문을 더 쉽게 대상으로 지정할 수 있다는 것입니다.또한 클래스 기반 언어에서 온 다른 언어들도 그 언어를 다국어로 사용하는 것이 더 쉽다.
주의사항
현재의 제한에 주의해 주세요.사유 재산을 얻으려면 기호 또는 WeakMaps를 사용해야 합니다.향후 릴리스에서는 이러한 기능을 포함하도록 클래스가 확장될 가능성이 높습니다.
지지하다
브라우저 지원은 현재 별로 좋지 않지만(IE를 제외한 거의 모든 사용자가 지원) Babel과 같은 트랜스필러로 이러한 기능을 사용할 수 있습니다.
자원.
나는 다니엘 엑스를 사용하는 것을 선호한다.무어의.이는 실제 인스턴스 변수, 특성 기반 상속, 클래스 계층 및 구성 옵션과 같은 이점을 제공하는 분야입니다.다음 예시는 가장 큰 장점이라고 생각되는 실제 인스턴스 변수를 사용하는 방법을 보여 줍니다.인스턴스 변수가 필요 없고 공용 변수 또는 개인 변수만 사용할 수 있다면 더 간단한 시스템이 있을 수 있습니다.
function Person(I) {
I = I || {};
Object.reverseMerge(I, {
name: "McLovin",
age: 25,
homeState: "Hawaii"
});
return {
introduce: function() {
return "Hi I'm " + I.name + " and I'm " + I.age;
}
};
}
var fogel = Person({
age: "old enough"
});
fogel.introduce(); // "Hi I'm McLovin and I'm old enough"
와, 그것만으로는 그다지 유용하지 않지만, 서브클래스를 추가하는 것을 검토해 주세요.
function Ninja(I) {
I = I || {};
Object.reverseMerge(I, {
belt: "black"
});
// Ninja is a subclass of person
return Object.extend(Person(I), {
greetChallenger: function() {
return "In all my " + I.age + " years as a ninja, I've never met a challenger as worthy as you...";
}
});
}
var resig = Ninja({name: "John Resig"});
resig.introduce(); // "Hi I'm John Resig and I'm 25"
또 다른 장점은 모듈 및 특성 기반 상속 기능을 사용할 수 있다는 것입니다.
// The Bindable module
function Bindable() {
var eventCallbacks = {};
return {
bind: function(event, callback) {
eventCallbacks[event] = eventCallbacks[event] || [];
eventCallbacks[event].push(callback);
},
trigger: function(event) {
var callbacks = eventCallbacks[event];
if(callbacks && callbacks.length) {
var self = this;
callbacks.forEach(function(callback) {
callback(self);
});
}
},
};
}
사용자 클래스의 예로는 바인딩 가능한 모듈을 들 수 있습니다.
function Person(I) {
I = I || {};
Object.reverseMerge(I, {
name: "McLovin",
age: 25,
homeState: "Hawaii"
});
var self = {
introduce: function() {
return "Hi I'm " + I.name + " and I'm " + I.age;
}
};
// Including the Bindable module
Object.extend(self, Bindable());
return self;
}
var person = Person();
person.bind("eat", function() {
alert(person.introduce() + " and I'm eating!");
});
person.trigger("eat"); // Blasts the alert!
공개:저는 다니엘 엑스입니다.무어와 이것은 나의 것이다.JavaScript에서 클래스를 정의하는 가장 좋은 방법입니다.
var Animal = function(options) {
var name = options.name;
var animal = {};
animal.getName = function() {
return name;
};
var somePrivateMethod = function() {
};
return animal;
};
// usage
var cat = Animal({name: 'tiger'});
지금까지 사용해 온 javascript로 오브젝트를 작성하는 방법은 다음과 같습니다.
예 1:
obj = new Object();
obj.name = 'test';
obj.sayHello = function() {
console.log('Hello '+ this.name);
}
예 2:
obj = {};
obj.name = 'test';
obj.sayHello = function() {
console.log('Hello '+ this.name);
}
obj.sayHello();
예 3:
var obj = function(nameParam) {
this.name = nameParam;
}
obj.prototype.sayHello = function() {
console.log('Hello '+ this.name);
}
예 4: Object.create()의 실제 이점 [이 링크]를 참조하십시오.
var Obj = {
init: function(nameParam) {
this.name = nameParam;
},
sayHello: function() {
console.log('Hello '+ this.name);
}
};
var usrObj = Object.create(Obj); // <== one level of inheritance
usrObj.init('Bob');
usrObj.sayHello();
예 5(Crockford의 Object.create 커스터마이즈):
Object.build = function(o) {
var initArgs = Array.prototype.slice.call(arguments,1)
function F() {
if((typeof o.init === 'function') && initArgs.length) {
o.init.apply(this,initArgs)
}
}
F.prototype = o
return new F()
}
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}} // For example
var userB = {
init: function(nameParam) {
this.id = MY_GLOBAL.nextId();
this.name = nameParam;
},
sayHello: function() {
console.log('Hello '+ this.name);
}
};
var bob = Object.build(userB, 'Bob'); // Different from your code
bob.sayHello();
To keep answer updated with ES6/ ES2015
클래스는 다음과 같이 정의됩니다.
class Person {
constructor(strName, numAge) {
this.name = strName;
this.age = numAge;
}
toString() {
return '((Class::Person) named ' + this.name + ' & of age ' + this.age + ')';
}
}
let objPerson = new Person("Bob",33);
console.log(objPerson.toString());
더글라스 크록포드의 JavaScript 프로토타입 상속과 JavaScript 클래식 상속을 읽어보셔야 할 것 같습니다.
그의 페이지의 예:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
효과? 보다 우아한 방법으로 메서드를 추가할 수 있습니다.
function Parenizor(value) {
this.setValue(value);
}
Parenizor.method('setValue', function (value) {
this.value = value;
return this;
});
그의 동영상도 추천한다.고도의 JavaScript.
당신은 그의 페이지에서 더 많은 비디오를 찾을 수 있다: http://javascript.crockford.com/ John Reisig 책에서는 Douglas Crockfor의 웹사이트에서 많은 예를 찾을 수 있다.
저는 YUI/Crockford 공장 계획을 인정하지 않을 것이며, 저는 물건을 스스로 억제하고 확장 가능한 상태로 유지하는 것을 좋아하기 때문에 이것이 저의 변형입니다.
function Person(params)
{
this.name = params.name || defaultnamevalue;
this.role = params.role || defaultrolevalue;
if(typeof(this.speak)=='undefined') //guarantees one time prototyping
{
Person.prototype.speak = function() {/* do whatever */};
}
}
var Robert = new Person({name:'Bob'});
이상적으로 테스트 유형은 첫 번째 방법 프로토타입과 같은 것에 있습니다.
심플하게 하려면 , 「new」키워드를 완전하게 사용하지 않고, 공장 출하시의 방법을 사용할 수 있습니다.JSON을 사용하여 오브젝트를 작성하는 것을 좋아하기 때문에, 이것을 선호할 때가 있습니다.
function getSomeObj(var1, var2){
var obj = {
instancevar1: var1,
instancevar2: var2,
someMethod: function(param)
{
//stuff;
}
};
return obj;
}
var myobj = getSomeObj("var1", "var2");
myobj.someMethod("bla");
하지만 큰 물체의 성능이 얼마나 좋은지는 잘 모르겠습니다.
var Student = (function () {
function Student(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
this.fullname = firstname + " " + lastname;
}
Student.prototype.sayMyName = function () {
return this.fullname;
};
return Student;
}());
var user = new Student("Jane", "User");
var user_fullname = user.sayMyName();
이것이 TypeScript가 클래스를 컨스트럭터와 JavaScript로 컴파일하는 방법입니다.
간단한 방법은 다음과 같습니다.
function Foo(a) {
var that=this;
function privateMethod() { .. }
// public methods
that.add = function(b) {
return a + b;
};
that.avg = function(b) {
return that.add(b) / 2; // calling another public method
};
}
var x = new Foo(10);
alert(x.add(2)); // 12
alert(x.avg(20)); // 15
이유that
라는 것이다.this
메서드를 이벤트핸들러로 지정하면 다른 것에 바인드 할 수 있기 때문에 인스턴스화 중에 값을 저장하고 나중에 사용합니다.
편집: 최적의 방법은 절대 아닙니다.단순한 방법입니다.나도 좋은 답변 기다리고 있어!
접이식 패턴을 사용하여 유형을 작성할 수 있습니다.
// Here is the constructor section.
var myType = function () {
var N = {}, // Enclosed (private) members are here.
X = this; // Exposed (public) members are here.
(function ENCLOSED_FIELDS() {
N.toggle = false;
N.text = '';
}());
(function EXPOSED_FIELDS() {
X.count = 0;
X.numbers = [1, 2, 3];
}());
// The properties below have access to the enclosed fields.
// Careful with functions exposed within the closure of the
// constructor, each new instance will have it's own copy.
(function EXPOSED_PROPERTIES_WITHIN_CONSTRUCTOR() {
Object.defineProperty(X, 'toggle', {
get: function () {
var before = N.toggle;
N.toggle = !N.toggle;
return before;
}
});
Object.defineProperty(X, 'text', {
get: function () {
return N.text;
},
set: function (value) {
N.text = value;
}
});
}());
};
// Here is the prototype section.
(function PROTOTYPE() {
var P = myType.prototype;
(function EXPOSED_PROPERTIES_WITHIN_PROTOTYPE() {
Object.defineProperty(P, 'numberLength', {
get: function () {
return this.numbers.length;
}
});
}());
(function EXPOSED_METHODS() {
P.incrementNumbersByCount = function () {
var i;
for (i = 0; i < this.numbers.length; i++) {
this.numbers[i] += this.count;
}
};
P.tweak = function () {
if (this.toggle) {
this.count++;
}
this.text = 'tweaked';
};
}());
}());
이 코드는 myType이라는 유형을 제공합니다.토글 및 텍스트라고 하는 내부 개인 필드가 있습니다.또한 필드 수와 숫자, 속성 전환, 텍스트 및 숫자 길이, 메서드 incrementNumbersByCount 및 tweak 등의 노출된 멤버도 있습니다.
접이식 패턴에 대한 자세한 내용은 여기를 참조하십시오.Javascript Folding Pattern
@liamclennan의 답변을 위한 코드 골프.
var Animal = function (args) {
return {
name: args.name,
getName: function () {
return this.name; // member access
},
callGetName: function () {
return this.getName(); // method call
}
};
};
var cat = Animal({ name: 'tiger' });
console.log(cat.callGetName());
MoTools(My Object Oriented Tools)는 클래스 개념에 중점을 두고 있습니다.상속을 통해 확장 및 구현할 수도 있습니다.
숙달되면 터무니없이 재사용이 가능하고 강력한 Javascript를 만들 수 있습니다.
상속이 있는 객체 기반 클래스
var baseObject =
{
// Replication / Constructor function
new : function(){
return Object.create(this);
},
aProperty : null,
aMethod : function(param){
alert("Heres your " + param + "!");
},
}
newObject = baseObject.new();
newObject.aProperty = "Hello";
anotherObject = Object.create(baseObject);
anotherObject.aProperty = "There";
console.log(newObject.aProperty) // "Hello"
console.log(anotherObject.aProperty) // "There"
console.log(baseObject.aProperty) // null
단순하고, 달콤하고, 그리고 끝내버리죠.
Triptich의 예에 따르면, 이것은 더 단순할 수 있습니다.
// Define a class and instantiate it
var ThePerson = new function Person(name, gender) {
// Add class data members
this.name = name;
this.gender = gender;
// Add class methods
this.hello = function () { alert('Hello, this is ' + this.name); }
}("Bob", "M"); // this instantiates the 'new' object
// Use the object
ThePerson.hello(); // alerts "Hello, this is Bob"
이렇게 하면 단일 개체 인스턴스만 생성되지만 클래스의 변수 및 메서드에 대해 여러 이름을 캡슐화할 경우 유용합니다.일반적으로 컨스트럭터에 대한 "Bob, M" 인수는 존재하지 않습니다. 예를 들어 메서드가 데이터베이스나 네트워크와 같은 자체 데이터를 가진 시스템에 대한 호출일 경우입니다.
저는 아직 JS에 익숙하지 않아서 왜 이 방법이prototype
것.
베이스
function Base(kind) {
this.kind = kind;
}
A클래스
// Shared var
var _greeting;
(function _init() {
Class.prototype = new Base();
Class.prototype.constructor = Class;
Class.prototype.log = function() { _log.apply(this, arguments); }
_greeting = "Good afternoon!";
})();
function Class(name, kind) {
Base.call(this, kind);
this.name = name;
}
// Shared function
function _log() {
console.log(_greeting + " Me name is " + this.name + " and I'm a " + this.kind);
}
액션.
var c = new Class("Joe", "Object");
c.log(); // "Good afternoon! Me name is Joe and I'm a Object"
JavaScript는 객체 지향적이지만 Java, C# 또는 C++와 같은 다른 OOP 언어와는 근본적으로 다릅니다.그렇게 이해하려고 하지 마세요.그 오래된 지식을 버리고 새롭게 시작하세요.JavaScript는 다른 생각을 필요로 한다.
나는 그 주제에 대한 좋은 설명서 같은 것을 얻을 것을 제안합니다.저는 ExtJs Tutorials를 읽기 전이나 읽은 후에 이 프레임워크를 사용해 본 적이 없지만, 이 튜토리얼이 저에게 가장 적합하다고 생각했습니다. 그러나 JavaScript 세계에 무엇이 있는지 잘 설명해 줍니다.죄송합니다, 그 내용은 삭제된 것 같습니다.대신 archive.org copy에 대한 링크가 있습니다.오늘 작동한다.:P
//new way using this and new
function Persons(name) {
this.name = name;
this.greeting = function() {
alert('Hi! I\'m ' + this.name + '.');
};
}
var gee=new Persons("gee");
gee.greeting();
var gray=new Persons("gray");
gray.greeting();
//old way
function createPerson(name){
var obj={};
obj.name=name;
obj.greeting = function(){
console.log("hello I am"+obj.name);
};
return obj;
}
var gita=createPerson('Gita');
gita.greeting();
언급URL : https://stackoverflow.com/questions/387707/what-techniques-can-be-used-to-define-a-class-in-javascript-and-what-are-their
'source' 카테고리의 다른 글
XAMPP에서 가상 호스트를 생성하는 방법 (0) | 2022.09.11 |
---|---|
휴지 상태를 사용하여 MariaDb 드라이버 속성을 설정하는 방법 (0) | 2022.09.11 |
명령줄에서 구현되지 않은 MySQL 쿼리를 지우려면 어떻게 해야 합니까? (0) | 2022.09.11 |
Spring JPA @Query 주석, SQL 위치 오류 (0) | 2022.09.11 |
MySQL 명령줄을 사용하여 SQL 파일을 가져오려면 어떻게 해야 합니까? (0) | 2022.09.11 |