среда, 24 апреля 2013 г.

4 способа создания и 5 способов наследования классов в JavaScript

4 способа создания объектов в JavaScript

1. Factory Pattern

function createPerson(name, age, job){
    var o = new Object();
         o.name = name;
         o.age = age;
         o.job = job;
         o.sayName = function(){
             alert(this.name);
         };
    return o;
}

var person1 = createPerson('Nicholas', 29, 'Software Engineer');
var person2 = createPerson('Greg', 27, 'Doctor');

2. Constructor Pattern

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        alert(this.name);
    };
}

var person1 = new Person('Nicholas', 29, 'Software Engineer');
var person2 = new Person('Greg', 27, 'Doctor');

alert(person1.constructor == Person); //true
alert(person2.constructor == Person); //true

alert(person1 instanceof Object); //true
alert(person1 instanceof Person); //true
alert(person2 instanceof Object); //true
alert(person2 instanceof Person); //true

3. Prototype Pattern

function Person(){} // или var Person = function(){}

Person.prototype.name = 'Nicholas';
Person.prototype.age = 29;
Person.prototype.job = 'Software Engineer';
Person.prototype.sayName = function(){
    alert(this.name);
};

Или другой вариант

function Person(){}

Person.prototype = {
    name : 'Nicholas',
    age : 29,
    job : 'Software Engineer',
    sayName : function () {
        alert(this.name);
    }
};

var person1 = new Person();
var person2 = new Person();

person1.sayName(); // "Nicholas"
person2.sayName(); // "Nicholas"

alert(person1.sayName == person2.sayName); //true

alert(Person.prototype.isPrototypeOf(person1)); //true
alert(Person.prototype.isPrototypeOf(person2)); //true

4. Module Pattern

var MyClass = (function($, _){

    // Определение свойств класса
    var prop1 = 1;
    var prop2 = 2;

    // Определение частных (private - закрытых для внешнего доступа) методов
   function private_method1() {return 4};
   function private_method2() {return 5};

    // Определение публичных (public - доступных для внешнего доступа) методов класса
    return {
         method1: function(){console.log(prop1);},
         method2: function(){console.log(prop2);},
         method3: function(){prop1 = 3;},
         method4: function(){return private_method1() + private_method2();}
    };

})(jQuery, underscore);

MyClass.method1(); // 1
MyClass.method2(); // 2
MyClass.method3(); // prop1 = 3
MyClass.method1(); // 3
MyClass.method4(); // 9

Или другой вариант

var Greeter = (function () {

    // Название класса Greeter
    function Greeter(message) { // message - переменная, подставляемая при создании объекта класса
        this.greeting = message;   // Определение атрибута greeting класса Greeter
    }

    // Метод класса Greeter
    Greeter.prototype.greet = function () { // Метод greet
        return "Hello, " + this.greeting;
    };

    return Greeter; // Инициализация класса Greeter

})();

var greeter = new Greeter("world"); // Создание объекта из класса Greeter

greeter.greet();

5 способов наследование классов в JavaScript

1. Наследование через прототип

function object(o){
    function F(){}
    F.prototype = o;
    return new F();
}

var person = {
    name: 'Nicholas',
    friends: ['Shelby', 'Court', 'Van']
};

var anotherPerson = object(person);
     anotherPerson.name = 'Greg';
     anotherPerson.friends.push('Rob');

2. Улучшенное наследование через прототип

function ExtendClass (ChildClass, ParentClass)
{
    var BaseParentClass = function(){};
          BaseParentClass.prototype = ParentClass.prototype;

    var TemporaryParentClass = new BaseParentClass();
   
    for (var property in ChildClass.prototype) {
        TemporaryParentClass[property] = ChildClass.prototype[property];
    }

    ChildClass.prototype = TemporaryParentClass;
    ChildClass.prototype.super = ParentClass.prototype;
}

3. Наследование внутри модуля

var ExtendClass = this.ExtendClass || function (ChildClass, ParentClass) {

    function F() { this.constructor = ChildClass; }
    F.prototype = ParentClass.prototype;
    ChildClass.prototype = new F();

};


var ManlyTruck = (function (ParentClass) {

    ExtendClass(ManlyTruck, ParentClass);

    function ManlyTruck(engine, bigTires) {

        ParentClass.call(this, engine);

        this.bigTires = bigTires;

    }

    return ManlyTruck;

})(Auto);


var Auto = (function () {

    function Auto(engine) {
        this.engine = engine;
    }

    return Auto;

})();

4. Наследование через new Object.create()

Object.create() поддерживается только в Internet Explorer 9+, Firefox 4+, Safari 5+, Opera 12+ и Chrome.

var person = {
    name: 'Nicholas',
    friends: ['Shelby', 'Court', 'Van']
};

var anotherPerson = Object.create(person, {
    name: {
        value: 'Greg'
    }
});

alert(anotherPerson.name); // "Greg"

5. Комбинированный способ наследования

Функция Extend() возвращает вновь созданный объект, наследующий свойства родителя.
Внутри используется функция Object.create() из ECMAScript 5, если она определена, иначе используется старый метод.

function Extend(Parent){

    if (Parent == null) {throw TypeError(); // Родитель не может быть значением Null

    if (Object.create){return Object.create(Parent);} // Наследовать свойства родителя, если  Object.create() определена

    var ParentType = typeof Parent; // Иначе выяснить тип родителя
    if (ParentType !== 'object' && ParentType !== 'function') {throw TypeError();}
   
    // Использовать старый метод наследования
    function F(){}
    F.prototype = Parent;
    return new F():
   
}

var Parent = {a: 1};

var Child = Extend(Parent);

Child.a;

Работа со свойствами класса

Копирование перечислимых свойств из объекта родителя в объект потомок c затиранием свойства потомка.

Если родитель и потомок имеют свойства с одинаковыми именами, то значение свойства потомка затирается свойством родителя.
Эта функция не учитывает наличие методов доступа и не копирует атрибуты.

function Extend(Child, Parent){
    for (property in Parent){
        Child[property] = Parent[property];
    }
    return Child;
}

Копирование перечислимых свойств из объекта родителя в объект потомок c сохранением исходных свойств потомка.

Если родитель и потомок имеют свойства с одинаковыми именами, то значение свойства потомка остаются неизменными.
Эта функция не учитывает наличие методов доступа и не копирует атрибуты.

function Extend(Child, Parent){
    for (property in Parent){
        if (Child.hasOwnProperty[property]) {continue;}
        Child[property] = Parent[property];
    }
    return Child;
}

Удаление из объекта потомка свойств, отсутствующих в объекте родителе.

function Deletion(Child, Parent){
    for (property in Child){
        if (!(property in Parent)) {delete Child[property];}
    }
    return Child;
}

Удаление из объекта потомка свойств, присутсвующих в объекте родителе.

function Deletion(Child, Parent){
    for (property in Parent){
        delete Child[property];
    }
    return Child;
}

Комментариев нет:

Отправить комментарий