5

我发现在 javascript 中掌握 OOP 真的很困难。

通常我希望必须创建一个类,然后从该类创建对象。

但是,根据一个教程,以下创建了一个对象。

var egg = {}

我不是只制作了一个名为 egg 的对象而没有实际制作一个类吗?

如果是这样,我将如何从一个对象制作多个对象:S

同样根据一个不同的教程,一个对象如下所示,这与我上面所说的完全不同:S

var Block = function(){

}

谁能帮我解开我的困惑:(

4

6 回答 6

14

上述两个例子都是正确的。简而言之,javascript中的一切都是一个对象。类不存在,但有很多方法可以模仿它们。我最喜欢的方法如下:

    var myClass = function() { <----------------------------- class declaration

            var prop1,   
                prop2,   <------------------------------------ private properties
                prop3;

            var addMe = function( arg1, arg2 ) { <------------ private method
                var result = arg1 + arg2;
                return result;
            }

            var obj = { <------------------------------------- constructor method 
                Prop1: prop1,
                Prop2: value2,  <----------------------------- public properties
                Prop3: value3,

                Method: function() { <------------------------ public method
                    obj.prop3 = obj.prop1 + obj.prop2;   
                    return obj.prop3;
                }
            }

            obj.Prop4 = addme( prop1, prop2 ); <-------------- public property set 
                                                               with the private method
            return obj;
    }

    var myClassObj = new myClass;

myClassObj 现在是 myClass 的一个对象,具有四个公共属性 Prop1、Prop2、Prop3、Prop4 和一个名为 Method 的公共方法

于 2012-07-13T22:35:44.640 回答
3

我不是只制作了一个名为 egg 的对象而没有实际制作一个类吗?

这是正确的。您所做的只是实例化基础对象Object- 您没有制作任何可以制作.

在 JavaScript 中,没有形式化的类概念——只有类的模拟,通过实例化而不是调用函数来实现。

function Animal() { this.animal = true; }
Animal.prototype.sayHi = function() { alert(this.name+' says hi!'); }
function Dog(name) { this.name = name; }
Dog.prototype = new Animal();
...
var fido = new Dog('Fido');
fido.sayHi(); //"Fido says hi!";

请注意,第 4 行只是模拟继承的几种方法之一。

所以在 JavaScript 中,类和函数都只是函数。没有任何东西可以阻止在没有操作员的情况下调用用于实例化的函数new,反之亦然。

在前一种情况下,常见的解决方法是检查构造函数是否为“类”(如果被调用但未实例化,构造函数将为Object)并根据需要重新路由:

function Dog(name) {
    //if we weren't instantiated, the constructor will be Object, not Dog
    if(this.constructor != Dog) return new Dog(name);
    this.name = name;
}
var fido = Dog(); //bad - invocation should be instantiation
于 2012-07-13T22:22:09.733 回答
3

Yesvar egg = {}是一个对象,但它不是一个对象的实例。

在 javascript 中,简单地这样说,基本上就是 js 的单例思想,意思就是它完全一样。

//this is a js singleton, and all properties of this object are public.
var egg = {
    name: 'humpty',
    smush: function() { console.log('splat!'); },
    weight: '4oz'
};
console.log(egg.weight); //4oz

而更传统的对象类型是将其设为一个函数,然后您可以实例化:

var Egg = function( name, weight ) {
    var name = name;
    this.smush = function() { console.log('splat!'); }
    this.weight = weight;
};
var e2 = new Egg('dumpty','6oz');
console.log(e2.name); //will not return name. (since i wrote var name and not this.name, its "private" and thus cannot be accessed.)
console.log(e2.weight); //4oz
于 2012-07-13T22:30:49.690 回答
3

Javascript 是一种与您目前所学的语言不同的语言。当您更改语言时,您不能期望事情会完全按照它们的方式工作。

快速预览:在 javascript 中,您可以将函数分配给变量。我敢打赌你用过的其他语言,那是不可能的:

var myCounter = 1;
var myFunction = function(x){ return x + 1; };

回到你的问题:在 javascript 中没有“真正的类”。只有对象。我知道这起初可能听起来令人困惑。

Javascript 的对象模型称为“原型继承”。它不同于“经典”(双关语)继承。而且它也不是很干净地实现

基本上,您从一组减少的对象(数组、函数、对象等是对象,而不是类)开始,然后使用这些对象来构建其他对象。它们之间的关系可以是“类和实例的”,但它们不是必须的。它们也可以是其他类型的关系。

由于没有类,因此您无法创建它们。但是你可以创建一个常规对象,将它分配给变量 Car,然后想“我将使用这个对象来创建许多其他对象。这些其他对象默认情况下会有一些属性,比如方法和东西,使它们表现得像汽车”。语言允许你这样做。Car 的行为就像其他语言中的类一样,它产生的对象将“像 Car 的实例”。

但是,对于 javascript,它们看起来像对象,它们之间有一些关系。

在某种程度上,原型继承是经典继承的“超集”。你可以做经典继承,也可以做其他事情。

于 2012-07-13T22:54:07.093 回答
2

您想查看 JavaScript 的“原型继承”。 http://www.crockford.com/javascript/inheritance.html

于 2012-07-13T22:51:14.583 回答
1

使用 jQuery 创建面向对象。利用 constructor() 方法并从类范围内访问公共和私有方法。

/*
 * myClass
 */
var myClass = function(options){

    /*
     * Variables accessible
     * in the class
     */
    var vars = {
        myVar  : ''
    };

    /*
     * Can access this.method
     * inside other methods using
     * root.method()
     */
    var root = this;

    /*
     * Constructor
     */
    this.construct = function(options){
        $.extend(vars , options);
    };

    /*
     * Public method
     * Can be called outside class
     */
    this.myPublicMethod = function(){
        console.log(vars.myVar);

        myPrivateMethod();
    };

    /*
     * Private method
     * Can only be called inside class
     */
    var myPrivateMethod = function() {
        console.log('private method called');
    };


    /*
     * Pass options when class instantiated
     */
    this.construct(options);

};


/*
 * USAGE
 */

/*
 * Set variable myVar to new value
 */
var newMyClass = new myClass({ myVar : 'new Value' });

/*
 * Call myMethod inside myClass
 */
newMyClass.myPublicMethod();
于 2019-11-25T01:59:10.430 回答