Comunidad de diseño web y desarrollo en internet online

Creación de métodos/atributos en objetos

Citar            
MensajeEscrito el 15 May 2014 07:48 pm
Hola amigos, mi duda es la siguiente:

He visto que utilizando la palabra prototype, se pueden asignar métodos/atributos a un objeto de la siguiente manera:

Código Javascript :

var fn = new Function();
Function.prototype.attribute = "Este es un atributo";
Function.prototype.method = function(){
    return "Este es un método";
};

console.log(fn.attribute); //Imprime "Este es un atributo"
console.log(fn.method()); //Imprime "Este es un método"


También de esta otra forma:

Código Javascript :

var fn = function(){
    if (this === window)
        return new fn();
    return this;
};
fn.prototype = {
    attribute: "Este es un atributo",
    method: function(){
        return "Este es un método";
    }
};

console.log(fn().attribute); //Imprime "Este es un atributo"
console.log(fn().method()); //Imprime "Este es un método"


Pero he visto que de este modo también es posible:

Código Javascript :

var fn = function(){
    if (window == this)
        return new fn();
    this.attribute = "Este es un atributo";
    this.method = function(){
        return "Este es un método";
    };
    return this;
};

console.log(fn().attribute); //Imprime "Este es un atributo"
console.log(fn().method()); //Imprime "Este es un método"


Y también de esta otra forma:

Código Javascript :

var fn = new Function();
fn.attribute = "Este es un atributo";
fn.method = function(){
    return "Este es un método";
};

console.log(fn.attribute); //Imprime "Este es un atributo"
console.log(fn.method()); //Imprime "Este es un método"


Entonces, mi duda y pregunta es, ¿cuál de estas formas es la más adecuada y qué diferencias hay entre ellas, además de la sintaxis? Estoy elaborando una pequeña librería guiándome con este artículo y es por eso que empecé a indagar sobre prototype y surgió esta duda.

Saludos

Por Alexis88

21 de clabLevel



Genero:Masculino  

Web developer

chrome
Citar            
MensajeEscrito el 16 May 2014 12:22 pm
La diferencia entre el primero código y el resto de los códigos que has puesto es que al usar la palabra reservada prototype en un tipo de dato como function, estás creando nuevos métodos y atributos para TODAS las functions a partir de allí, no solo para la function "fn" que está declarada más arriba.

Esto no ocurre con el resto de las declaraciones que has puesto.

Un ejemplo:

Código Javascript :

var fn = new Function();
Function.prototype.attribute = "Este es un atributo";
Function.prototype.method = function(){
    return "Este es un método";
};

var fn1 = new Function();

console.log(fn1.attribute);

Verás que la función fn1 también tiene el atributo "attribute".

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 16 May 2014 09:30 pm
Hola DriverOp, gracias por responder.

Lo que dices es verdad, de hecho, también lo leí en la documentación existente. Sin embargo, mi duda persiste. Entre los 3 ejemplo restantes de creación de métodos y atributos, ¿Qué diferencias existen, además de la sintaxis? ¿Cuál es la manera más adecuada de crear/asignar métodos y atributos a un objeto de las 3 que muestro? Porque como comenté, estoy elaborando una librería en JS en base al artículo que adjunté en el mensaje anterior y pues, lo estoy haciendo de la segundo forma, es decir, así:


Código Javascript :

var fn = function(id){
    if (this === window)
        return new fn(id);
    return this;
};

fn.prototype = {
    attribute: "Este es un atributo",
    method: function(){
        return "Este es un método";
    }
};


Y cada vez que quiero aplicar un método al objeto cuyo Id envío a la función fn, lo hago de la siguiente manera:

Código Javascript :

fn("id del elemento").metodo();


Pero también probé creando métodos sin prototype, de esta forma:

Código Javascript :

fn.nuevoMetodo = function(){
    //Instrucciones
};


Y para aplicar el nuevo método a un elemento del DOM, lo hago así:

Código Javascript :

fn.nuevoMetodo(fn("id del elemento"));


Para lo cual, fn devuelve al elemento que seleccionó por su Id y este es accesible dentro del nuevo método. Entonces, mi duda aparece al ver estos dos tipos de invocación de métodos:

Código Javascript :

fn("id del elemento").metodo(); //Método asignado con prototype
fn.nuevoMetodo(fn("id del elemento")); //Método asignado sin prototype


La sintaxis es distinta, pero lo que me intriga saber es qué diferencia, además de la sintaxis, existe entre estas dos formas de crear/asignar métodos y atributos a un objeto. No menciono a la tercera forma restante pues tiene el mismo efecto que la que acabo de mostrar. A lo que voy es a lo siguiente; ¿Por qué en la primera forma, tengo que usar paréntesis luego de fn y en la segunda no si ambos son métodos del mismo objeto? ¿No debería poder accederse a ellos de la misma forma?

Agradeceré mucho si pudieran orientarme al respecto.

Saludos

Por Alexis88

21 de clabLevel



Genero:Masculino  

Web developer

chrome
Citar            
MensajeEscrito el 17 May 2014 06:00 pm
Estas mezclando demasiados temas, y para esto debes entender la Programación Orientada a Objetos y saber que esas funciones en si son Clases o Modelos para crear nuevos objetos.

Como vi que ya lo mencionas, existen metodos y metodos estaticos (o abstractos).

Por teoria, de los primeros debes crear una instancia del objeto para poder llamar al metodo.

Los estaticos o abstractos, podrás llamarlos directo sin necesidad de crear instancias.

fn("element") <-- ya es una instancia de un objeto

Al ser una instancia puedes ingresar a sus metodos mediante " . "

fn.nuevoMetodo(fn("element") <-- estas llamando a una clase abstracta o estatica que no necesita ser instanciada para poder realizar las funciones sobre el objeto que también estas introduciendo.

En si solo es el paradigma de la programacion orientada a objetos. Muchos la utilizan y pocos saben realmente lo que estan haciendo :)

Por elporfirio

Claber

652 de clabLevel

1 tutorial

Genero:Masculino  

FullStack Web Developer

chrome
Citar            
MensajeEscrito el 18 May 2014 05:38 am
Entiendo, es algo similar a lo que ocurre en otros lenguajes, como en PHP.

Código PHP :

$instancia = new miClase(); //Instancio a la clase
$instancia->metodo(); //Llamo a un método no estático

miClase::metodoEstatico(); //Llamo a un método estático

Esa era la duda que tenía, pues tengo entendido que si bien en JS prácticamente todo lo que hay son objetos, no existen clases propiamente dichas, como en PHP, por ejemplo; entonces, mi confusión estaba en dicha instanciación, pues he visto que para instanciar a una clase (que creo que mejor es llamarla objeto, pues al fin y al cabo, eso terminan siendo las clases) en JS, también se puede utilizar la palabra reservada new, pero también funciona sin ella.

Código Javascript :

var fn = function(){
        return console.log("Hola");
    },
    instancia = new fn(); //Muestra 'Hola'
    fn(); //Muestra 'Hola'

Como no veía palabras reservadas como static, protected, abstract, entre otras que se usan en PHP, pues me confundía con este asunto, pero con tu aclaración, mi duda ha sido resuelta.

Gracias, saludos.

Por Alexis88

21 de clabLevel



Genero:Masculino  

Web developer

chrome
Citar            
MensajeEscrito el 19 May 2014 01:31 pm
Bueno, la verdad sea dicha. JavaScript no es orientado a objeto, es un lenguaje prototipado. Por lo tanto no usa los mismos conceptos que la POO. Como se ha mencionado ya, no tiene herencia, ni poliformismo (dos conceptos fundamentales de la POO).
Tampoco existen los conceptos de propiedades protegidas, públicas o privadas.
En JS todo es público.
En JS tampoco existe el concepto de métodos setter y getter.
En vez de usar "clases" como en la POO, en JS se usan prototipos.
Debido a todo esto, es mejor que no pienses en POO cuando trabajes en JS. Usa su propio paradigma.

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 19 May 2014 09:56 pm
Eso ya era algo que tenía relativamente claro y fue por eso que realicé esta consulta, para que la claridad sobre el tema deje de ser relativa. Si bien no existe el polimofirmo, característica esencial de la POO, este puede ser emulado, como en PHP, que debido a su bajo tipado, no es una característica inherente al lenguaje. Y lo mismo va por métodos setter y getter, de hecho, hasta emulaciones de un método constructor (no la propiedad constructor) se pueden hacer.

Aunque no se traten propiamente de clases, finalmente vienen siendo objetos y por el tratamiento que se les puede dar, es el que permite esta emulación. El tema de los ámbitos y la accesibilidad, ya lo tenía claro, pero nunca está de más el recordarlo.

Gracias, saludos

Por Alexis88

21 de clabLevel



Genero:Masculino  

Web developer

chrome
Citar            
MensajeEscrito el 20 May 2014 05:42 pm

Por ignell

11 de clabLevel



Genero:Masculino  

Juegos con Html5

chrome

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.