2011-05-13 16 views
6

我是JavaScript新手,并试图了解我应该如何编写类(我的背景是'常规'OO语言,如java和C++)。在JavaScript中构建类的正确方法?

我明白,我有两个选择:

  1. 如果我想我的类有私有方法和成员,我不能在原型定义它们。但在这种情况下,它们将针对每个新创建的对象(内存问题)进行构建。

  2. 如果我在类原型定义方法,我将没有封装(这是奇怪对我来说,作为一个Java/C++显影剂:P)。

你使用了哪两种方法?为什么?

+0

这里阅读:http://www.crockford.com/javascript/inheritance.html –

+0

另外这款:http://javascript.crockford.com/ private.html –

+0

看看[OOP基础知识](http://stackoverflow.com/questions/5134208/jquery-oop-basics/5134494#5134494) – Raynos

回答

7

所以,我不认为有一个“正确答案”这个问题......它基本上是你喜欢什么,并认为这是最适合您的特定用途。我的许多课程都是“静态课程”,例如

var MyClassName = { 
    methodName: function() { }, 
    //... 
} 

因为我从不需要实例化它们。当我需要实例化多个实例时,我使用原型方法。

如果需要私有变量,你可以定义一个函数/类做私有变量,以及需要该函数/类中访问这些私有瓦尔方法。然后,对所有不需要访问私人变量的方法使用原型方法。例如。

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"); 
} 

做这两个应该使你保持你的实例化轻量级,但仍然给你一些封装。到目前为止,我从来没有与私人股票打扰。

0

如果您使用的原型框架,你会使用他们的实现类和继承的方式会更好。你可能是指this article

通常我不认为私有成员在JavaScript中使用。 (编辑:没有在实例化的类中,我经常在我们的代码库中看到一些“模块”,它们保持私有状态,但可以看作单例)。在技​​术上可以解决语言缺乏封装的问题,但是如果您的类将被实例化,则需要付出代价。另外我认为如果你打算使用继承,你需要一些工作来获得受保护的可见性。

我不认为在查看ext源代码时看到任何私人内容。他们确实将“// private”放在应该是私有的方法上,这暗示着不应该直接调用它们。 这意味着如果你要这样编写代码,你需要更多的“纪律”来编写getter/setters。

0

为什么是有...现在。

上面的答案对他们的时间是正确的。

这里是解决方案:

'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' } } 
相关问题