programación orientada a objetos javasript

Introducción orientada a objetos

¿Qué es un objeto?

Todo es objeto

Qué es el objeto, lo podemos entender desde dos niveles.

(1) Un objeto es una abstracción de una sola cosa.

Un libro, un automóvil o una persona pueden ser un objeto, y una base de datos, una página web o una conexión a un servidor remoto también pueden ser un objeto. Cuando lo real se abstrae en un objeto, la relación entre lo real se convierte en la relación entre los objetos, de modo que puede simular la situación real y programar el objeto.

(2) Un objeto es un contenedor que encapsula propiedades y métodos.

Los atributos son el estado del objeto y los métodos son el comportamiento del objeto (para completar una determinada tarea). Por ejemplo, podemos abstraer animales como objetos animales, usar "atributos" para registrar qué tipo de animal es y usar "métodos" para representar ciertos comportamientos de los animales (correr, cazar, descansar, etc.).

En el desarrollo real, un objeto es un concepto abstracto, que puede entenderse simplemente como un conjunto de datos o un conjunto de funciones.

ECMAScript-262 define un objeto como: una colección de atributos desordenados, cuyos atributos pueden contener valores, objetos o funciones básicos. Estrictamente hablando, esto equivale a decir que un objeto es un conjunto de valores sin ningún orden en particular. Cada propiedad o método de un objeto tiene un nombre y cada nombre se asigna a un valor.

Sugerencia: Cada objeto se crea en función de un tipo de referencia. Estos tipos pueden ser los tipos nativos integrados en el sistema o los tipos definidos por el desarrollador.

Que es orientado a objetos

La orientación a objetos no es algo nuevo, es solo un código de procedimiento altamente encapsulado, el propósito es mejorar la eficiencia del desarrollo y la capacidad de mantenimiento del código.

Programación orientada a objetos: la programación orientada a objetos, OOP para abreviar, es una idea de desarrollo de programación. Abstrae varias relaciones complejas del mundo real en objetos y luego completa la simulación del mundo real mediante la división del trabajo y la cooperación entre los objetos.

En la idea del desarrollo de un programa orientado a objetos, cada objeto es un centro funcional, con una clara división del trabajo, y puede completar tareas como recibir información, procesar datos y enviar información. Por lo tanto, la programación orientada a objetos tiene las características de flexibilidad, reutilización de código y alta modularidad. Es fácil de mantener y desarrollar. En comparación con la programación de procedimientos tradicional que consta de una serie de funciones o instrucciones, es más adecuada para la cooperación de varias personas Proyectos de software a gran escala.

Orientado a objetos y orientado a procesos:

Enfrentar el proceso es hacerlo tú mismo, no importa cuán grande o pequeño sea, todo es integral, sigue cada paso y sé metódico

Orientado a objetos es encontrar un objeto y ordenar el resultado

Orientado a objetos transforma a los ejecutores en comandantes

Orientado a objetos no es un reemplazo para el encapsulado orientado a procesos, sino orientado a procesos

Funciones orientadas a objetos:

1. Encapsulación

2. Herencia

3. [Polimorfismo] Resumen

La realización básica de la orientación a objetos en el programa.

En JavaScript, todos los tipos de datos pueden considerarse objetos y, por supuesto, los objetos también pueden personalizarse. El tipo de datos de objeto personalizado es el concepto de clase (Clase) en la orientación a objetos.

Usamos un ejemplo para ilustrar la diferencia en el flujo del programa entre orientado a procesos y orientado a objetos.

Supongamos que queremos procesar la hoja de puntuación de un estudiante. Para representar la puntuación de un estudiante, un programa orientado a procesos se puede representar mediante un objeto:

 var std1 = { name: 'Michael', score: 98 }
 var std2 = { name: 'Bob', score: 81 }
 而处理学生成绩可以通过函数实现,比如打印学生的成绩:
  function printScore (student) {
   console.log('姓名:' + student.name + '  ' + '成绩:' + student.score)
   }

Si adoptamos ideas de programación orientada a objetos, nuestra primera opción no es pensar en el proceso de ejecución del programa, sino que el tipo de datos Student debe tratarse como un objeto, que tiene dos propiedades (propiedad) nombre y puntuación. Si desea imprimir la puntuación de un alumno, primero debe crear un objeto correspondiente al alumno y luego enviar un mensaje printScore al objeto y dejar que el objeto imprima sus propios datos.

抽象数据行为模板(Class):
 function Student(name, score) {
 this.name = name;
 this.score = score;
 this.printScore = function() {
 console.log('姓名:' + this.name + '  ' + '成绩:' + this.score);
 }
  }
  根据模板创建具体实例对象(Instance):
   var std1 = new Student('Michael', 98)
   var std2 = new Student('Bob', 81)
   实例对象具有自己的具体行为(给对象发消息):
   std1.printScore() // => 姓名:Michael  成绩:98
   std2.printScore() // => 姓名:Bob  成绩 81

Las ideas de diseño orientadas a objetos provienen de la naturaleza, porque en la naturaleza, los conceptos de Clase e Instancia son naturales. Clase es un concepto abstracto. Por ejemplo, nuestra definición de Clase —— Estudiante se refiere al concepto de estudiantes, mientras que las Instancias son estudiantes específicos. Por ejemplo, Michael y Bob son dos estudiantes específicos.

Por tanto, la idea de diseño orientado a objetos es:

Resumen de clase (constructor)

Crear instancia según la clase (constructor)

Instancia de comando para obtener el resultado

El grado de abstracción orientada a objetos es mayor que el de las funciones, porque una clase contiene tanto datos como métodos para manipular datos.

创建对象
简单方式
我们可以直接通过 new Object() 创建:

 var person = new Object()
 person.name = 'Jack'
 person.age = 18
 ​
 person.sayName = function () {
    
    
   console.log(this.name)
 }
每次创建通过 new Object() 比较麻烦,所以可以通过它的简写形式对象字面量来创建:

 var person = {
    
    
   name: 'Jack',
   age: 18,
   sayName: function () {
    
    
     console.log(this.name)
   }
 }
对于上面的写法固然没有问题,但是假如我们要生成两个 person 实例对象呢?

 var person1 = {
    
    
   name: 'Jack',
   age: 18,
   sayName: function () {
    
    
     console.log(this.name)
   }
 }var person2 = {
    
    
   name: 'Mike',
   age: 16,
   sayName: function () {
    
    
     console.log(this.name)
   }
 }
通过上面的代码我们不难看出,这样写的代码太过冗余,重复性太高。

简单方式的改进:工厂函数
我们可以写一个函数,解决代码重复问题:

 function createPerson (name, age) {
    
    
   return {
    
    
     name: name,
     age: age,
     sayName: function () {
    
    
       console.log(this.name)
     }
   }
 }
然后生成实例对象:

 var p1 = createPerson('Jack', 18)
 var p2 = createPerson('Mike', 18)
这样封装确实爽多了,通过工厂模式我们解决了创建多个相似对象代码冗余的问题, 但却没有解决对象识别的问题(即怎样知道一个对象的类型)。

Constructor

Guía de contenido:

Sintaxis del constructor

Constructor de análisis

La relación entre el constructor y el objeto de instancia.

El atributo constructor de la instancia

instancia de operador

La diferencia entre la llamada a la función ordinaria y la llamada al constructor

El valor de retorno del constructor.

El problema con el constructor

更优雅的工厂函数:构造函数
一种更优雅的工厂函数就是下面这样,构造函数:

 function Person (name, age) {
    
    
   this.name = name
   this.age = age
   this.sayName = function () {
    
    
     console.log(this.name)
   }
 }var p1 = new Person('Jack', 18)
 p1.sayName() // => Jackvar p2 = new Person('Mike', 23)
 p2.sayName() // => Mike
解析构造函数代码的执行
在上面的示例中,Person() 函数取代了 createPerson() 函数,但是实现效果是一样的。 这是为什么呢?

我们注意到,Person() 中的代码与 createPerson() 有以下几点不同之处:

Objetos creados no mostrados

Asignar atributos y métodos directamente a este objeto

Sin declaración de devolución

El nombre de la función usa Person en mayúsculas

Para crear una instancia de Persona, debe utilizar el nuevo operador. Llamar al constructor de esta manera seguirá los siguientes 4 pasos:

Crea un nuevo objeto

Asignar el alcance del constructor al nuevo objeto (por lo que esto apunta a este nuevo objeto)

Ejecuta el código en el constructor.

Devolver nuevo objeto

El siguiente es el pseudocódigo específico:

 function Person (name, age) {
    
    
   // 当使用 new 操作符调用 Person() 的时候,实际上这里会先创建一个对象
   // var instance = {}
   // 然后让内部的 this 指向 instance 对象
   // this = instance
   // 接下来所有针对 this 的操作实际上操作的就是 instancethis.name = name
   this.age = age
   this.sayName = function () {
    
    
     console.log(this.name)
   }// 在函数的结尾处会将 this 返回,也就是 instance
   // return this
 }
构造函数和实例对象的关系
使用构造函数的好处不仅仅在于代码的简洁性,更重要的是我们可以识别对象的具体类型了。 在每一个实例对象中同时有一个 constructor 属性,该属性指向创建该实例的构造函数:

 console.log(p1.constructor === Person) // => true
 console.log(p2.constructor === Person) // => true
 console.log(p1.constructor === p2.constructor) // => true
对象的 constructor 属性最初是用来标识对象类型的, 但是,如果要检测对象的类型,还是使用 instanceof 操作符更可靠一些:

 console.log(p1 instanceof Person) // => true
 console.log(p2 instanceof Person) // => true

para resumir:

Constructor es una plantilla abstracta extraída de cosas concretas

El objeto de instancia es un objeto de instancia concreto obtenido de acuerdo con la plantilla de constructor abstracto

Cada objeto de instancia tiene un atributo de constructor, que apunta al constructor que creó la instancia.

Nota: El argumento de que el constructor es una propiedad de una instancia no es riguroso, el prototipo hablará de ello más adelante.

La relación entre la instancia y el constructor se puede juzgar a través del atributo constructor de la instancia.

Nota: Este método no es riguroso, se recomienda usar el operador instanceof, aprender el prototipo más tarde explicará por qué

El problema con el constructor

使用构造函数带来的最大的好处就是创建对象更方便了,但是其本身也存在一个浪费内存的问题:

 function Person (name, age) {
    
    
   this.name = name
   this.age = age
   this.type = 'human'
   this.sayHello = function () {
    
    
     console.log('hello ' + this.name)
   }
 }var p1 = new Person('Tom', 18)
 var p2 = new Person('Jack', 16)
在该示例中,从表面上好像没什么问题,但是实际上这样做,有一个很大的弊端。 那就是对于每一个实例对象,type 和 sayHello 都是一模一样的内容, 每一次生成一个实例,都必须为重复的内容,多占用一些内存,如果实例对象很多,会造成极大的内存浪费。

 console.log(p1.sayHello === p2.sayHello) // => false
对于这种问题我们可以把需要共享的函数定义到构造函数外部:

 function sayHello = function () {
    
    
   console.log('hello ' + this.name)
 }function Person (name, age) {
    
    
   this.name = name
   this.age = age
   this.type = 'human'
   this.sayHello = sayHello
 }var p1 = new Person('Top', 18)
 var p2 = new Person('Jack', 16)
 ​
 console.log(p1.sayHello === p2.sayHello) // => true
这样确实可以了,但是如果有多个需要共享的函数的话就会造成全局命名空间冲突的问题。

你肯定想到了可以把多个函数放到一个对象中用来避免全局命名空间冲突的问题:

 var fns = {
    
    
   sayHello: function () {
    
    
     console.log('hello ' + this.name)
   },
   sayAge: function () {
    
    
     console.log(this.age)
   }
 }function Person (name, age) {
    
    
   this.name = name
   this.age = age
   this.type = 'human'
   this.sayHello = fns.sayHello
   this.sayAge = fns.sayAge
 }var p1 = new Person('lpz', 18)
 var p2 = new Person('Jack', 16)
 ​
 console.log(p1.sayHello === p2.sayHello) // => true
 console.log(p1.sayAge === p2.sayAge) // => true
至此,我们利用自己的方式基本上解决了构造函数的内存浪费问题。 但是代码看起来还是那么的格格不入,那有没有更好的方式呢?


Sintaxis del constructor de resumen

Constructor de análisis

La relación entre el constructor y el objeto de instancia.

El atributo constructor de la instancia

instancia de operador

El problema con el constructor


Guía de contenido de prototipos :

Utilice el objeto prototipo prototipo para resolver el problema del constructor.

Analizar la relación entre constructor, objeto prototipo y objeto de instancia.

Principio de búsqueda de miembros de propiedad: cadena de prototipos

El objeto de instancia lee y escribe miembros en un objeto prototipo

Forma corta de objeto prototipo

Prototipo de objeto nativo

Objeto

Formación

Cuerda

...

El problema con los objetos prototipo

Sugerencias sobre el uso de funciones construidas y objetos prototipo.

Una mejor solución: el
JavaScript prototipo estipula que cada constructor tiene una propiedad prototipo que apunta a otro objeto. Todas las propiedades y métodos de este objeto serán propiedad del constructor.

Esto también significa que podemos definir directamente las propiedades y métodos que todas las instancias de objetos necesitan compartir en el objeto prototipo.

la función Person (nombre, Edad) { this.name name = this.age = Age } the console.log (Person.prototype) Person.prototype.type = 'Human' Person.prototype.sayName = function () { Console. log (this.name) } var new new P1 = la Persona (...) var new new P2 = la Persona (...) a true the console.log (p1.sayName === p2.sayName) // => cuando todas las instancias El atributo type y el método sayName () son en realidad la misma dirección de memoria, apuntando al objeto prototipo, por lo que se mejora la eficiencia operativa.
















La relación entre constructor, instancia y prototipo

Inserte la descripción de la imagen aquí

Cualquier función tiene una propiedad de prototipo, que es un objeto.

F. function () {}
the console.log (F.prototype) // => Object F.prototype.sayHi = function () { the console.log ('¡Hola!') } El constructor del objeto prototipo tiene un constructor predeterminado Propiedad, que apunta a la función donde se encuentra el objeto prototipo.




console.log (F.prototype.constructor === F) // => true
El objeto de instancia obtenido mediante la función constructora contendrá un proto puntero al objeto prototipo de la función constructora .

new new instance F. = var ()
the console.log (instance. proto === F.prototype) // => a true son propiedades no estándar.

__proto__


Los ejemplos de objetos pueden acceder directamente a los miembros del objeto prototipo.

instance.sayHi () // => ¡hola!
Resumen:

Cualquier función tiene una propiedad de prototipo, que es un objeto.

El objeto prototipo del constructor tiene un atributo de constructor por defecto, que apunta a la función donde se encuentra el objeto prototipo.

El objeto de instancia obtenido a través del constructor contendrá un puntero al objeto prototipo del constructor proto

Todas las instancias heredan directa o indirectamente los miembros del objeto prototipo

El principio de búsqueda de miembros de atributo: cadena de prototipos Después de
comprender la relación entre el objeto constructor-instancia-prototipo, expliquemos por qué el objeto de instancia puede acceder a los miembros en el objeto prototipo.

Siempre que el código lea un atributo de un objeto, realizará una búsqueda, el objetivo es el atributo con el nombre dado

La búsqueda comienza desde la propia instancia del objeto.

Si se encuentra un atributo con el nombre dado en la instancia, se devuelve el valor del atributo

Si no lo encuentra, continúe buscando el objeto prototipo al que apunta el puntero y busque el atributo con el nombre dado en el objeto prototipo

Si esta propiedad se encuentra en el objeto prototipo, se devuelve el valor de la propiedad

En otras palabras, cuando llamamos person1.sayName (), se realizarán dos búsquedas sucesivamente:

Primero, el analizador preguntará: "¿La instancia person1 tiene un atributo sayName?" Respuesta: "No.

Luego, continuó buscando y luego preguntó: "¿El prototipo de person1 tiene un atributo sayName?" "Respuesta:" Sí.

"Entonces lee la función almacenada en el objeto prototipo.

Cuando llamemos person2.sayName (), se repetirá el mismo proceso de búsqueda y se obtendrán los mismos resultados.

Y este es el principio básico de que varias instancias de objetos comparten las propiedades y los métodos guardados por el prototipo.

para resumir:

Encuéntrate primero en ti mismo y vuelve cuando lo encuentres

Si no puede encontrarlo por su cuenta, buscará a lo largo de la cadena de prototipos y regresará cuando lo encuentre.

Si no se ha encontrado hasta el final de la cadena del prototipo, devuelve undefined

El objeto de instancia lee y escribe miembros del objeto prototipo
Leer:

Encuéntrate primero en ti mismo y vuelve cuando lo encuentres

Si no puede encontrarlo por su cuenta, buscará a lo largo de la cadena de prototipos y regresará cuando lo encuentre.

Si no se ha encontrado hasta el final de la cadena del prototipo, devuelve undefined

Escritura de miembro de tipo de valor (objeto de instancia. Miembro de tipo de valor = xx):

Cuando la instancia espera reescribir un miembro de datos ordinario en el objeto prototipo, en realidad agregará el miembro a sí misma.

En otras palabras, el comportamiento bloqueará el acceso a los miembros del objeto prototipo.

Escritura de miembro de tipo de referencia (objeto de instancia. Miembro de tipo de referencia = xx):

Lo mismo que arriba

Modificación de tipo complejo (objeto de instancia. Member.xx = xx):

También encontrará primero el miembro en su propio cuerpo y lo modificará directamente si lo encuentra en su propio cuerpo.

Si no puede encontrarlo por su cuenta, continúe buscando a lo largo de la cadena de prototipos, si lo encuentra, modifíquelo

Si el miembro no se encuentra hasta el final de la cadena del prototipo, se informa de un error (instancia objeto.undefined.xx = xx)

Sintaxis de prototipo más simple
Notamos que en el ejemplo anterior, debe escribir Person.prototype cada vez que agrega una propiedad y un método. Para reducir la entrada innecesaria, es más común reescribir todo el objeto prototipo con un objeto literal que contenga todas las propiedades y métodos:

la función Person (nombre, Edad) { this.name name = this.age = Age } Person.prototype = { type: 'Human', the sayHello: function () { the console.log ('I'm' + this .name + ', I am this year' + this.age + 'year old') } } En este ejemplo, restablecemos Person.prototype a un nuevo objeto. La ventaja de esto es que agregar miembros a Person.prototype es simple, pero también trae un problema, es decir, el objeto prototipo pierde el miembro constructor.










Por lo tanto, para mantener correcto el puntero del constructor, la forma recomendada de escritura es:

la función Person (nombre, Edad) { this.name name = this.age = Age } Person.prototype = { constructor: the Person, // => El constructor manual apuntará al tipo de constructor correcto : 'Human', el sayHello : function () { console.log ('Mi nombre es' + this.name + ', soy este año' + this.age + 'año de edad') } } Prototipo de objeto nativo Todas las funciones tienen prototipos de objetos de propiedad.













Object.prototype

Función.prototipo

Array.prototype

String.prototype

Número.prototipo

Fecha.prototipo

Supongo que te gusta

Origin blog.csdn.net/weixin_43131046/article/details/113740718
Recomendado
Clasificación