我更喜欢在大型项目中使用OOP,比如我现在正在做的项目。我需要在JavaScript中创建几个类,但是,如果我没有弄错的话,至少有几种方法可以做到这一点。它的语法是什么,为什么要这样做?
我希望避免使用第三方库——至少一开始是这样。 为了寻找其他答案,我找到了一篇文章《JavaScript面向对象编程,第一部分:继承- JavaScript文档》,它讨论了JavaScript中的面向对象编程。是否有更好的继承方式?
我更喜欢在大型项目中使用OOP,比如我现在正在做的项目。我需要在JavaScript中创建几个类,但是,如果我没有弄错的话,至少有几种方法可以做到这一点。它的语法是什么,为什么要这样做?
我希望避免使用第三方库——至少一开始是这样。 为了寻找其他答案,我找到了一篇文章《JavaScript面向对象编程,第一部分:继承- JavaScript文档》,它讨论了JavaScript中的面向对象编程。是否有更好的继承方式?
当前回答
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的方式。
其他回答
MooTools(我的面向对象工具)以类的思想为中心。您甚至可以通过继承来扩展和实现。
一旦掌握了它,就会产生可重用的强大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中没有类这种东西。JavaScript使用基于原型的继承方案。
此外,还有许多流行的JavaScript库,它们在JavaScript中具有类似类的功能。您至少需要了解Prototype和jQuery。
决定哪一个是“最好的”是在Stack Overflow上开始一场圣战的好方法。如果您正在着手一个较大的javascript较多的项目,那么学习一个流行的库并按照它们的方式来做绝对是值得的。我是一个原型的人,但Stack Overflow似乎倾向于jQuery。
至于只有“一种方法可以做到这一点”,不依赖任何外部库,我写的方法就差不多了。
你可能想通过使用折叠模式来创建一个类型:
// 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的类型。它将有内部私有字段toggle和text。它还将有这些公开的成员:字段count和numbers;属性toggle, text和numberLength;方法incrementNumbersByCount和tweak。
折叠模式的详细信息如下: Javascript折叠模式
一个基地
function Base(kind) {
this.kind = kind;
}
一个类
// 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"
我更喜欢使用Daniel X. Moore的{SUPER: SYSTEM}。这是一个提供诸如真正的实例变量、基于特征的继承、类层次结构和配置选项等好处的规程。下面的例子说明了真正实例变量的使用,我认为这是最大的优势。如果你不需要实例变量,并且只喜欢公共或私有变量,那么可能有更简单的系统。
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"
另一个优点是能够拥有基于模块和trait的继承。
// 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);
});
}
},
};
}
一个让person类包含可绑定模块的例子。
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!
披露:我是丹尼尔·x·摩尔,这是我的{SUPER: SYSTEM}。这是用JavaScript定义类的最佳方式。