我更喜欢在大型项目中使用OOP,比如我现在正在做的项目。我需要在JavaScript中创建几个类,但是,如果我没有弄错的话,至少有几种方法可以做到这一点。它的语法是什么,为什么要这样做?
我希望避免使用第三方库——至少一开始是这样。 为了寻找其他答案,我找到了一篇文章《JavaScript面向对象编程,第一部分:继承- JavaScript文档》,它讨论了JavaScript中的面向对象编程。是否有更好的继承方式?
我更喜欢在大型项目中使用OOP,比如我现在正在做的项目。我需要在JavaScript中创建几个类,但是,如果我没有弄错的话,至少有几种方法可以做到这一点。它的语法是什么,为什么要这样做?
我希望避免使用第三方库——至少一开始是这样。 为了寻找其他答案,我找到了一篇文章《JavaScript面向对象编程,第一部分:继承- JavaScript文档》,它讨论了JavaScript中的面向对象编程。是否有更好的继承方式?
当前回答
以下是在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's 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();
保持答案与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());
其他回答
一个基地
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"
以下是在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's 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();
保持答案与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());
你可能想通过使用折叠模式来创建一个类型:
// 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折叠模式
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.`;
}
}
好处
主要的好处是静态分析工具发现更容易定位这种语法。对于那些来自基于类的语言的人来说,使用这种语言作为一种多语言也更容易。
警告
要警惕它目前的局限性。要实现私有属性,必须使用符号或弱映射。在未来的版本中,类很可能会被扩展,以包含这些缺失的特性。
支持
目前浏览器的支持还不是很好(除了IE,几乎所有浏览器都支持),但是现在你可以通过像Babel这样的编译器来使用这些特性。
资源
ECMAScript 6中的类(最终语义) 什么?等待。真的吗?哦,不!(一篇关于ES6类和隐私的文章) 兼容性表-类 巴别塔-班级
基于tritych的例子,这可能更简单:
// 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看到为什么这不使用原型的东西。