search
HomeWeb Front-endJS TutorialIn-depth understanding of javascript constructors and prototype objects_javascript skills

Several commonly used object creation modes

Create using the new keyword
The most basic method of object creation is nothing more than the same as in most other languages: there is no object, you create a new one!

var gf = new Object();
gf.name = "tangwei";
gf.bar = "c++";
gf.sayWhat = function() {
  console.log(this.name + "said:love you forever");
}

Create using literals

This seems appropriate, but how can geeks like such a complicated and low-key way of defining variables? As a scripting language, it should have the same style as other brothers, so it appeared. How object literals are defined:

var gf = {
  name : "tangwei",
  bar : "c++",
  sayWhat : function() {
    console.log(this.name + "said:love you forever");
  }
}

Factory Mode

Actually, this is the most commonly used way to define objects in practice, but what should I do if I want to have many objects with similar properties (thinking about it is exciting...)? If we define them one by one, a lot of code will be generated. Why not build a factory and produce our objects in batches? Hence, the first inflatable baby in the JavaScript world. . . No, the "factory model" was born!

function createGf(name, bar) {
  var o = new Object();
  o.name = name;
  o.bar = bar;
  o.sayWhat = function() {
    alert(this.name + "said:love you forever");
  }
  return o;
}
var gf1 = createGf("bingbing","d");
var gf2 = createGf("mimi","a");

Constructor

The factory pattern solves the problem of creating multiple similar objects, but the problem comes again. These objects are all created from Object. How to distinguish their specific object types? At this time we need to switch to another mode, constructor mode:

function Gf(name,bar){
  this.name = name;
  this.bar = bar;
  this.sayWhat = function(){
    alert(this.name + "said:love you forever");
  }
}
var gf1 = new Gf("vivian","f");
var gf2 = new Gf("vivian2","f");

Here we use a constructor starting with a capital letter to replace createGf in the above example. Note that according to the convention, the first letter of the constructor must be capitalized. Here we create a new object, then assign the scope of the constructor to the new object and call the methods in the constructor.
There seems to be nothing wrong with the above method, but we can find that the sayWhat method in the constructor called in the two instances is not the same Function instance:

console.log(gf1.sayWhat == gf2.sayWhat); //false

Calling the same method but declaring different instances is a waste of resources. We can optimize and declare the sayWhat function outside the constructor:

function Gf(name,bar){
  this.name = name;
  this.bar = bar;
  this.sayWhat = sayWhat
}
function sayWhat(){
  alert(this.name + "said:love you forever");
}

This solves the problem of multiple instances defining the same method instance multiple times, but a new problem arises. The sayWhat we defined is a global scope method, but this method cannot be called directly. This is a bit contradictory. How to define an object with certain encapsulation properties more elegantly? Let’s take a look at the JavaScript prototype object pattern.

Prototype Object Pattern

Understanding prototype objects
When we create a function, the function will have a prototype attribute, which points to the prototype object of the function created through the constructor. In layman's terms, a prototype object is an object in memory that provides shared properties and methods for other objects.

In prototype mode, there is no need to define instance attributes in the constructor, and attribute information can be directly assigned to the prototype object:

function Gf(){
  Gf.prototype.name = "vivian";
  Gf.prototype.bar = "c++";
  Gf.prototype.sayWhat = function(){
    alert(this.name + "said:love you forever");
  }
}
var gf1 = new Gf();
gf1.sayWhat();
var gf2 = new Gf();

The difference from the constructor is that the properties and methods of the new object here can be shared by all instances. In other words, gf1 and gf2 access the same properties and methods. In addition to the attributes we assign to the prototype object, there are also some built-in attributes. All prototype objects have a constructor attribute, which is a pointer to a function containing the prototype attribute (dare you go further!). Let’s clearly understand this tongue-twisting process through a picture:

All objects have a prototype object (prototype). The prototype object has a constructor attribute pointing to the function containing the prototype attribute. Gf instances gf1 and gf2 both contain an internal attribute pointing to the prototype object (shown in the firefox browser is a private property proto), when we access a property in an object, we will first ask whether the property exists in the instance object, and if not, continue to look for the prototype object.

Use prototype objects
In the previous example, we noticed that when adding attributes to prototype objects, we need to add Gf.prototype to each one. This work is very repetitive. In the above object creation mode, we know that we can use literals. Create an object, we can also improve it here:

function Gf(){}
Gf.prototype = {
  name : "vivian",
  bar : "c++",
  sayWhat : function(){
    alert(this.name + "said:love you forever");
  }
} 

There is one thing that needs special attention here. The constructor attribute no longer points to the object Gf, because every time a function is defined, a prototype object will be created for it at the same time. This object will also automatically obtain a new constructor attribute. This is We use Gf.prototype to essentially overwrite the original prototype object, so the constructor becomes the constructor property of the new object, no longer pointing to Gf, but Object:

var gf1 = new Gf();
console.log(gf1.constructor == Gf);//false
console.log(gf1.constructor == Object)//true

一般情况下,这个微妙的改变是不会对我们造成影响的,但如果你对constructor有特殊的需求,我们也可以显式的指定下Gf.prototype的constructor属性:

Gf.prototype = {
  constructor : Gf,
  name : "vivian",
  bar : "c++",
  sayWhat : function() {
    alert(this.name + "said:love you forever");
  }
}
var gf1 = new Gf();
console.log(gf1.constructor == Gf);//true

通过对原型对象模式的初步了解,我们发现所有的实例对象都共享相同的属性,这是原型模式的基本特点,但往往对于开发者来说这是把“双刃剑”,在实际开发中,我们希望的实例应该是具备自己的属性,这也是在实际开发中很少有人单独使用原型模式的主要原因。

构造函数和原型组合模式

在实际开发中,我们可以使用构造函数来定义对象的属性,使用原型来定义共享的属性和方法,这样我们就可以传递不同的参数来创建出不同的对象,同时又拥有了共享的方法和属性。

function Gf(name,bar){
  this.name = name;
  this.bar = bar;
}
Gf.prototype = {
  constructor : Gf,
  sayWhat : function() {
    alert(this.name + "said:love you forever");
  }
}
var gf1 = new Gf("vivian", "f");
var gf2 = new Gf("vivian1", "c");

在这个例子中,我们再构造函数中定义了对象各自的属性值,在原型对象中定义了constructor属性和sayWhat函数,这样gf1和gf2属性之间就不会产生影响了。这种模式也是实际开发中最常用的对象定义方式,包括很多js库(bootstrap等)默认的采用的模式。

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Tools

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.