基础JavaScript OO

时间:2012-11-19 09:55:37

标签: javascript

好的我知道答案,但由于某种原因,我从未真正了解或需要真正了解JavaScript。

  

我的问题是:查看下面的代码示例,我的理解是正确的,或者我错过了一些信息。


示例1

需要实例化函数(或类)才能使用IsOld方法,并且将为每个实例创建IsOld函数的单独副本。

function MyClass1() {
    this.IsOld = function (age) {
        if (age > 40) {
            return true;
        }
        return false;
    };
}

// sample usage
var m1 = new MyClass1();
console.log(m1.IsOld(34));

示例2

需要实例化,但与MyClass1不同,脚本引擎不需要为每个类实例创建方法IsOld的副本。

var MyClass2 = (function () {
    function MyClass2() { }

    MyClass2.prototype.IsOld = function (age) {
        if (age > 40) {
            return true;
        }
        return false;
    };

    return MyClass2;
})();

// sample usage
var m2 = new MyClass2();
console.log(m2.IsOld(34));

示例3

无需实例化函数/类来访问IsOld方法。所有调用都使用IsOld方法的单个实例。

var MyClass3 = {
    IsOld: function (age) {
        if (age > 40) {
            return true;
        }
        return false;
    },
};

// sample uage
console.log(MyClass3.IsOld(34));

注意:我猜这里有很多类似的问题/答案,但由于某种原因,我找不到一个对我有意义的问题。

3 个答案:

答案 0 :(得分:2)

您的理解似乎是正确的。

如果“需要实例化”是指使用“新”关键字,我想在此处添加一些内容。

在JavaScript中使用new关键字不是创建新实例的唯一方法。 (根据评论编辑) 任何函数都可以充当构造函数。

当您使用'new'关键字后跟任何函数(比如'x')时,它的作用是

  1. 创建新对象(比如'y'),并将函数x的原型设置为新对象(y')原型。
  2. 在新创建的对象y的上下文中调用函数'x',即这将在函数'x'中引用这个新对象'y'
  3. 如果函数没有返回对象,则返回new运算符创建的新对象'x'作为新表达式的结果。
  4. 这是Douglas Crockford学习JavaScript的好资料(http://javascript.crockford.com/

    因此,如果您关注内存(应该是这样),请使用构造函数,并将所有常用方法添加到函数原型中,就像在示例2中所做的那样。

    然后,所有这些方法都将继承到使用此函数创建的所有对象作为构造函数。但是,如前所述,我认为样本2可以更简单:

    var MyClass2 = function MyClass2() { };
    
    MyClass2.prototype.IsOld = function (age) {
        if (age > 40) {
            return true;
        }
        return false;
    };
    
    var obj = new MyClass2();
    

答案 1 :(得分:1)

据我所知,在所有3个案例中你都是对的。

  1. 是否需要实例化IsOld并且每个实例都会创建新函数。
  2. 不需要像原型一样实例化IsOld
  3. 不需要实例化IsOld,因为MyClass3已经是一个实例(一个对象不是一个函数)。

答案 2 :(得分:1)

在我看来,对于类的结构和Javascript的动态性质存在一些误解:对于所有呈现的情况,“类”的每个实例都会创建一个新的未命名函数。

如果你想以更传统的方式(比如C ++或Java)声明“类”,你最好:

1)定义功能:

function MyClass_IsOld(age) {
    return (age > 40);
} 

2)创建“类”并定义其原型:

function MyClass() { /* put any instance constructor logic here */ };
MyClass.prototype.IsOld = MyClass_IsOld;

3)使用课程:

var myInstance = new MyClass();
console.log(myInstance.IsOld(37));

如果要将“方法”用作常规函数,请将其全局声明,如:

function MyClass_IsOld(age) {
    return (age > 40);
} 
function MyClass() { /* put any instance constructor logic here */ };
MyClass.prototype.IsOld = MyClass_IsOld;

var myInstance = new MyClass();
console.log(myInstance.IsOld(37));        // use as a method
console.log(MyClass_IsOld(37));           // use as a function

如果要隐藏实现细节,请创建一个闭包:

var MyClass = (function () {
    function _MyClass_IsOld(age) {
        return (age > 40);
    } 
    function _MyClass() { /* put any instance constructor logic here */ };
    _MyClass.prototype.IsOld = _MyClass_IsOld;  // use as a method

    return _MyClass;
})();

var myInstance = new MyClass();
console.log(myInstance.IsOld(37));        // use as a method
console.log(MyClass_IsOld(37));           // ERROR: undefined function