JavaScript OOP类和声明

问题描述 投票:5回答:6

我发现很难用javascript掌握OOP。

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

但是,根据一个教程,以下内容是一个对象。

var egg = {}

我不仅没有实际创建类就制作了一个名为egg的对象。

如果是这种情况,我将如何从一个对象中创建多个对象:S

也根据另一本教程,对象是像下面这样制作的,这与上面我所讲的完全不同:S

var Block = function(){

}

[谁能帮我解决我的困惑:(

javascript jquery oop
6个回答
3
投票

Java语言与到目前为止所学的语言不同。您不能指望在更改语言时一切都能像它们一样正常工作。

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

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

回到您的问题:在javascript中,没有“真实的类”。只有对象。我知道一开始听起来可能会令人困惑。

Javascript的对象模型称为“原型继承”。它与“经典”(双关语意味)继承不同。而且它也是not very cleanly implemented

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

由于没有类,因此无法创建它们。但是您可以创建一个常规对象,将其分配给变量Car,然后想到“我将使用该对象创建许多其他对象。这些其他对象默认具有一些属性,例如方法和内容,使其表现得像汽车”。语言允许您做到这一点。 Car的行为将类似于类在其他语言中的行为,并且它产生的对象将像“ Car的实例”。

不过,对于javascript,它们看起来像是对象,它们之间具有某些关系。

从某种意义上说,原型继承是经典继承的“超集”。您可以进行经典继承,也可以进行其他事情。


12
投票

以上两个示例都是正确的。简而言之,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和一个称为“方法”的公共方法


3
投票

我不仅没有真正创建一个名为egg的对象,课。

是的。您在此所做的全部工作都是实例化基础Object对象-您尚未做出可以使实例of变为实例的任何内容。

在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!";

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

因此在JavaScript中,类和函数都只是函数。没有new运算符可以阻止旨在用于实例化的函数被调用的固有方法,反之亦然。

在前一种情况下,常见的解决方法是检查构造函数是否为'class'(如果被调用且未实例化,则构造函数将为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

3
投票

var 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

而更传统的object类型将使它成为可以实例化的函数:

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

2
投票

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


0
投票

[创建一个面向jQuery的对象。利用builder()方法,从类范围内访问公共和私有方法。

/*
 * 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();
© www.soinside.com 2019 - 2024. All rights reserved.