Un artículo para comprender la forma de creación de objetos JS [organizar notas]

Generalmente, los objetos se crean directamente en forma de literales, pero este método de creación generará una gran cantidad de código repetitivo al crear una gran cantidad de objetos similares. Pero js es diferente de los lenguajes generales orientados a objetos, no tiene el concepto de clase antes de ES6. Sin embargo, las funciones se pueden utilizar para la simulación para generar métodos de creación de objetos reutilizables.Los más comunes son los siguientes:

1. Modo de fábrica

//搞一个工厂函数反复调用
function createPerson(name, job) { 
     var o = new Object();
     o.name = name;
     o.job = job;
     o.sayName = function() { 
        console.log(this.name); 
     } 
     return o;
} 
var person1 = createPerson('Mike', 'student');
var person2 = createPerson('X', 'engineer');
//总结:工厂模式虽然解决了创建多个相似对象的问题,但是没有解决对象识别问题,即不能知道一个对象的类型

2. Modo constructor

//没有显示的创建对象,使用new来调用这个构造函数,使用new后会自动执行如下操作:
/*  
    ①创建一个新对象;
    ②将构造函数的作用域赋给新对象(因此this就指向了这个新对象);
    ③执行构造函数中的代码(为这个新对象添加属性);
    ④返回新对象。
*/
function Person(name, job) { 
     this.name = name;
     this.job = job;
     this.sayName = function() { 
      console.log(this.name);
 } 
}
var person1 = new Person('Mike', 'student');
var person2 = new Person('X', 'engineer');
/*************************************************************************************/
//缺点:每个方法都要在每个实例上重新创建一遍。解决方法如下:
//创建两个完成同样任务的的 Function 实例的确没有必要。况且有 this 对象在,根本不用在执行代码前就把函数绑定到特定的对象上
function Person( name, age, job ){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = sayName;//函数指针,这样实例就会共享一个函数地址
}
function sayName(){
    alert( this.name );
}
//这样也有问题
//1.全局作用域中定义的函数(sayName)实际上只能被某个对象调用,这让全局作用域有点名不副实。
//2.如果对象需要定义很多方法,那么就需要定义很多个全局函数,这样一来,我们自定义的这个引用类型就毫无封装性可言了。
//这些问题可以通过使用原型模式来解决。⬇

3. Patrón de prototipo

//将信息直接添加到原型对象上。
//使用原型的好处是可以让所有的实例对象共享它所包含的属性和方法,不必在构造函数中定义对象实例信息,而是可以将这些信息直接添加到原型对象中。
function Person() { }
    Person.prototype.name = 'Mike';//这样可就每个人都叫MIKE了哈
    Person.prototype.job = 'student';
    Person.prototype.sayName = function() { 
        console.log(this.name) 
    } 
var person1 = new Person();
//还有更简单的写法
function Person(){ }
Person.prototype = {
    constructor = Person()//设置新原型,再将constructor指回构造函数
    name : "Mike",
    age : 29,
    job : "engineer",    
    syaName : function(){
        alert( this.name );
    }
};

Falibilidad del prototipo

Cada vez que se crea una nueva función, se crea una propiedad prototipo para esa función de acuerdo con un conjunto específico de reglas. De forma predeterminada, todas las propiedades de prototipo obtienen automáticamente una propiedad de constructor (función de constructor), que contiene un puntero a la función donde reside la propiedad de prototipo.

Cada vez que el código lee una propiedad de un objeto, se realiza una búsqueda dirigida a la propiedad con el nombre dado. La búsqueda comienza con la instancia del objeto en sí. Si se encuentra un atributo con el nombre dado en la instancia, devuelva el valor del atributo; si no lo encuentra, continúe buscando el objeto prototipo señalado por el puntero y busque el atributo con el nombre dado en el objeto prototipo. Si la propiedad se encuentra en el objeto prototipo, se devuelve el valor de la propiedad.

Aunque se puede acceder a los valores almacenados en el prototipo a través de la instancia del objeto, los valores del prototipo no se pueden sobrescribir a través de la instancia del objeto. Si agregamos una propiedad en la instancia que tiene el mismo nombre que una propiedad en la instancia, esa propiedad se creará en la instancia y esa propiedad sombreará la del prototipo.

Incluso establecer la propiedad en nulo solo hará que el valor de la propiedad sea nulo en la instancia. Sin embargo, las propiedades de la instancia se pueden eliminar por completo mediante el operador de eliminación, lo que permite volver a acceder a las propiedades en el prototipo. Utilice el método hasOwnProperty() para detectar si existe una propiedad en la instancia o en el prototipo. Este método solo devolverá verdadero si la propiedad dada existe en la instancia del objeto.

4. Combinando el modo constructor y el modo prototipo

//组合使用构造函数模式和原型模式是使用最为广泛、认同度最高的一种创建自定义类型的方法。
function Person(name) { 
     this.name = name; 
     this.friends = ['Jack', 'Merry']; 
} 
Person.prototype.sayName = function() { 
     console.log(this.name); 
}
var person1 = new Person(); 
var person2 = new Person(); 
person1.friends.push('Van'); 
console.log(person1.friends); //["Jack", "Merry", "Van"] 
console.log(person2.friends); // ["Jack", "Merry"] 
console.log(person1.friends === person2.friends); //false
//值得注意,sayName中的this指向调用它的对象,可不是指向定义它的作用域,箭头函数的this指向定义它的作用域。

5. Modo de prototipo dinámico

//动态原型模式将所有信息都封装在了构造函数中,初始化的时候,可以通过检测某个应该存在的方法是否有效,来决定是否需要初始化原型。
//特点:节约第二次及以后调用的时间
function Person(name, job) {
  // 属性 
 this.name = name;
 this.job = job;
 // 方法 
 if(typeof this.sayName !== 'function') { 
      Person.prototype.sayName = function() { 
            console.log(this.name) 
      } 
 }
} 
var person1 = new Person('Mike', 'Student');
person1.sayName();
//只有在 sayName() 方法不存在的时候,才会将它添加到原型中。这段代码只会初次调用构造函数的时候才会执行。此后原型已经完成初始化,不需要在做什么修改了,这里对原型所做的修改,能够立即在所有实例中得到反映。
//意思就是只要有一个if在这了,只有第一次调用Person时候才给原型绑定,避免重复操作。

6. Modo constructor parásito

function Person(name, job) { 
      var o = new Object();
      o.name = name;
      o.job = job;
      o.sayName = function() { 
            console.log(this.name) 
      } 
      return o;
}
var person1 = new Person('Mike', 'student');
person1.sayName();
//这个模式,除了使用 new 操作符并把使用的包装函数叫做构造函数之外,和工厂模式几乎一样。
//原理:
//构造函数如果不返回对象,默认也会返回一个新的对象,通过在构造函数的末尾添加一个 return 语句,可以重写调用构造函数时返回的值。原本构造函数返回的是this
//注意:
//这样创建出来的对象与构造函数之间没有什么关系, instanceof 操作符对他们没有意义。

Supongo que te gusta

Origin blog.csdn.net/qq_42533666/article/details/129082794
Recomendado
Clasificación