用JavaScript构建类的正确方法?
我不熟悉JavaScript,并试图理解如何编写类(我的“常规”OO语言背景,如java和c++) 我知道我有两个选择:用JavaScript构建类的正确方法?,javascript,prototype-programming,Javascript,Prototype Programming,我不熟悉JavaScript,并试图理解如何编写类(我的“常规”OO语言背景,如java和c++) 我知道我有两个选择: 如果我希望我的类有私有方法和成员,我不能在原型中定义它们。但在这种情况下,它们将为创建的每个新对象构建(内存问题) 如果我在类原型中定义方法,我将没有封装(这对我来说很奇怪,作为java/c++开发人员:p) 你用哪两种方法?为什么?所以,我不认为这个问题有一个“正确的答案”…它基本上是你喜欢的,并且认为最适合你的特定用途。我的许多类都是“静态类”,例如 因为我从来不需要实例
你用哪两种方法?为什么?所以,我不认为这个问题有一个“正确的答案”…它基本上是你喜欢的,并且认为最适合你的特定用途。我的许多类都是“静态类”,例如 因为我从来不需要实例化它们。当我需要实例化多个实例时,我使用prototype方法 如果需要私有变量,可以定义一个函数/类来执行私有变量,以及需要访问该函数/类中的那些私有变量的方法。然后,对所有不需要访问私有变量的方法使用原型方法。例如
var PageClass = function() {
var _birthdate;
this.getBirthdate = function() {
return typeof(_birthdate) == "undefined" ? null : _birthdate;
}
this.setBirthdate = function( date ) {
if( typeof(date) == 'object' && date.constructor == Date ) {
_birthdate = date;
}
else {
throw "Invalid Argument Exception: PageClass.setBirthdate expects parameter of type 'Date'";
}
}
}
PageClass.prototype.doSomething = function() {
alert("DOING SOMETHING");
}
这两种方法都可以使您的实例化稍微轻一些,但仍然可以提供一些封装。到目前为止,我从未为私有变量烦恼过。如果使用原型框架,最好使用它们实现类和继承的方式。你可能指的是 通常我认为javascript中不使用私有成员。(edit:不在实例化类中。我经常在我们的代码库中看到一些“模块”,它们确实持有私有状态,但可以被视为单例) 凯文的回答大致概括了这一点。从技术上讲,解决该语言缺乏封装的问题是可能的,但如果要大量实例化类,则需要付出代价。此外,我认为如果要使用继承,您需要做一些工作来获得受保护的可见性 例如,我认为我在查看ext源时没有看到任何私人内容。它们确实将“//private”放在了应该是私有的方法之上,这意味着不应该直接调用它们。 这确实意味着,如果要以这种方式编写代码,您需要更多的“规程”来编写getter/setter。 为什么会有。。。现在 以上答案对他们的时间来说是正确的 以下是新的解决方案:
'use strict';
// Declare our class
class Metadata {
// Declare the constructor and pass it some values - a and b are "defaults"
constructor( ninfo, a = 1.0, b = 1.0 )
{
// Set our class variables
this.ninfo = ninfo;
this.a = a;
this.b = b;
// Define our "secret" or nonenumerable options
Object.defineProperty( this, 'addA', {
enumerable: false,
writable: false,
// Have it add our passed in value
value: n => this.a += n
} );
}
}
// Call our class and pass in some variables
let x = new Metadata( "we have a and b", 1.0 );
// Log our result if we call "addA"
console.log( x.addA( 3 ) ); // => 4
// Log our object
console.log( x ); // => Metadata { ninfo: 'we have a and b', a: 4, b: 2 }
// Log our object 'for real'
console.log( require( 'util' ).inspect( x, { showHidden: true, depth: null } ) );
// result
// Metadata {
// ninfo: 'we have a and b',
// a: 4,
// b: 2,
// [addA]: { [Function: value] [length]: 1, [name]: 'value' } }
阅读这里:还有这个:看看
'use strict';
// Declare our class
class Metadata {
// Declare the constructor and pass it some values - a and b are "defaults"
constructor( ninfo, a = 1.0, b = 1.0 )
{
// Set our class variables
this.ninfo = ninfo;
this.a = a;
this.b = b;
// Define our "secret" or nonenumerable options
Object.defineProperty( this, 'addA', {
enumerable: false,
writable: false,
// Have it add our passed in value
value: n => this.a += n
} );
}
}
// Call our class and pass in some variables
let x = new Metadata( "we have a and b", 1.0 );
// Log our result if we call "addA"
console.log( x.addA( 3 ) ); // => 4
// Log our object
console.log( x ); // => Metadata { ninfo: 'we have a and b', a: 4, b: 2 }
// Log our object 'for real'
console.log( require( 'util' ).inspect( x, { showHidden: true, depth: null } ) );
// result
// Metadata {
// ninfo: 'we have a and b',
// a: 4,
// b: 2,
// [addA]: { [Function: value] [length]: 1, [name]: 'value' } }