我更喜欢在大型项目中使用OOP,比如我现在正在做的项目。我需要在JavaScript中创建几个类,但是,如果我没有弄错的话,至少有几种方法可以做到这一点。它的语法是什么,为什么要这样做?
我希望避免使用第三方库——至少一开始是这样。 为了寻找其他答案,我找到了一篇文章《JavaScript面向对象编程,第一部分:继承- JavaScript文档》,它讨论了JavaScript中的面向对象编程。是否有更好的继承方式?
我更喜欢在大型项目中使用OOP,比如我现在正在做的项目。我需要在JavaScript中创建几个类,但是,如果我没有弄错的话,至少有几种方法可以做到这一点。它的语法是什么,为什么要这样做?
我希望避免使用第三方库——至少一开始是这样。 为了寻找其他答案,我找到了一篇文章《JavaScript面向对象编程,第一部分:继承- JavaScript文档》,它讨论了JavaScript中的面向对象编程。是否有更好的继承方式?
当前回答
代码高尔夫@liammclennan的答案。
var Animal = function (args) { 返回{ 名称:args.name, getName:函数{ 返回this.name;//成员访问 }, callGetName:函数(){ 返回this.getName ();//方法调用 } }; }; var cat =动物({名字:'老虎'}); console.log (cat.callGetName ());
其他回答
你可能想通过使用折叠模式来创建一个类型:
// 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折叠模式
在JavaScript中定义类的最好方法是不定义类。
认真对待。
面向对象有几种不同的风格,其中一些是:
基于类的OO(首先由Smalltalk引入) 基于原型的OO(由Self首次引入) 基于多方法的面向对象(我认为是由CommonLoops首次引入的) 基于谓词的OO(不知道)
可能还有一些我不知道的。
JavaScript实现了基于原型的OO。在基于原型的OO中,通过复制其他对象来创建新对象(而不是从类模板实例化),方法直接存在于对象中而不是类中。继承是通过委托完成的:如果一个对象没有方法或属性,它会在它的原型(即它被克隆的对象)中查找,然后是原型的原型,以此类推。
换句话说:没有阶级。
JavaScript actually has a nice tweak of that model: constructors. Not only can you create objects by copying existing ones, you can also construct them "out of thin air", so to speak. If you call a function with the new keyword, that function becomes a constructor and the this keyword will not point to the current object but instead to a newly created "empty" one. So, you can configure an object any way you like. In that way, JavaScript constructors can take on one of the roles of classes in traditional class-based OO: serving as a template or blueprint for new objects.
JavaScript是一种非常强大的语言,因此如果您愿意,可以很容易地在JavaScript中实现基于类的OO系统。但是,只有在确实需要时才应该这样做,而不是仅仅因为Java就是这样做的。
我认为你应该阅读Douglas Crockford的《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的网站上找到许多例子。
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的方式。
代码高尔夫@liammclennan的答案。
var Animal = function (args) { 返回{ 名称:args.name, getName:函数{ 返回this.name;//成员访问 }, callGetName:函数(){ 返回this.getName ();//方法调用 } }; }; var cat =动物({名字:'老虎'}); console.log (cat.callGetName ());