search
HomeWeb Front-endJS TutorialSeveral ways to define classes and objects in JavaScript_js object-oriented

You can take a look at this example:

Copy the code The code is as follows:

var a = 'global' ;
(function () {
alert(a);
var a = 'local';
})();


Everyone first When you see this example, what do you think the output is? 'global'? Or 'local'? In fact, it is not the case. The output is undefined. Don’t be confused. My digression is just to talk about this thing.
In fact, it is very simple. You will understand it if you take a look at the JavaScript operating mechanism. We can think of this phenomenon as "pre-statement". But if you dig a little deeper, you will understand it more clearly.
This actually involves the object property binding mechanism. Because all JavaScript functions are an object. Variables declared in a function can be regarded as "similar properties" of this object. The binding of object properties is divided into "early binding" and "late binding" in the language.

[Early Binding]
refers to defining the properties and methods of an object before instantiating it. It can be converted to machine code in advance when parsing the program. Commonly typed languages ​​such as C, Java, etc. all use early binding mechanisms. And JavaScript is not a strongly typed language. It uses a "late binding" mechanism.
【Late Binding】
means that before running the program, there is no need to check the object type, just check whether the object supports properties and methods. A large number of operations can be performed on the object before binding without penalty.
The "pre-declaration" phenomenon in the above code can be explained by the "late binding" mechanism. Within a function's scope, all variables are "late bound". That is, the statement is top-level. So the above code is consistent with the following:
Copy the code The code is as follows:

var a = 'global';
(function () {
var a;
alert(a);
a = 'local';
})();

Before alert(a), only a was declared without assigning a value. So the results can be imagined.


 RT: What this article is going to talk about is the several ways I know of defining classes and objects in JavaScript:
 【Direct Quantity Method】
 Using direct quantities to construct objects is the most basic way, but There are also many disadvantages.
Copy code The code is as follows:

var Obj = new Object;
Obj.name = 'sun';
Obj.showName = function() {
alert('this.name');
}

We construct an object Obj, which has An attribute name and a method showName. But what if we want to build another similar object? Do we have to repeat it again?
NO! , we can implement it with a factory function that returns an object of a specific type. Just like a factory, the pipeline outputs the specific type of results we want.
 【Factory method】
Copy code The code is as follows:

function createObj(name) {
var tempObj = new Object;
tempObj.name = name;
tempObj.showName = function () {
alert(this.name);
};
return tempObj ;
}
var obj1 = createObj('obj_one');
var obj2 = createObj('obj_two');

Many people don’t use this factory function As a form of constructing objects. Part of the reason is semantics: it's not as formal as building with operator new. There is another bigger reason, because every time this factory produces an object, it creates a new function showName(), that is, each object has a different version, but in fact they share the same function.
Some people define showName outside the factory function, and then point to the method through attributes, which can avoid this problem:
Copy code The code is as follows:

function showName () {
alert(this.name);
}
function createObj(name) {
var tempObj = new Object ;
tempObj.name = name;
tempObj.showName = showName;
return tempObj;
}
var obj1 = createObj('obj_one');
var obj2 = createObj( 'obj_two');

Unfortunately, this method makes the showName() function not look like a method of the object.
 [Constructor method]
This method is to solve the first problem of the factory function above, that is, the problem of no new operator. But it still cannot solve the second problem. Let's take a look.
Copy code The code is as follows:

function Obj(name) {
this.name = name;
this.showName = function () {
alert(this.name);
}
}
var obj1 = new Obj('obj_one');
var obj2 = new Obj('obj_two');

The advantage is that there is no need to create a new object in the constructor, because the new operator will automatically create an object when it is executed, and only through this to access this object. So we can assign a value to this object directly through this. And there is no need to return, because this points to the return value of the constructor by default.
At the same time, using the new keyword to create the object we want feels more "formal".
Unfortunately, it still cannot solve the problem of repeatedly generating method functions, which is the same as factory functions.

[Prototype method]
Compared with the above methods, this method has a great advantage, that is, it solves the problem of method functions being generated multiple times. It makes use of the prototype property of the object. We rely on prototypes to override object instances.
Copy code The code is as follows:

var Obj = function () {}
Obj .prototype.name = 'me';
Obj.prototype.showName = function () {
alert(this.name);
}
var obj1 = new Obj();
var obj2 = new Obj();

We rely on the prototype to rewrite the constructor. Both properties and methods are given to the newly created objects through prototype references, so they will only be created. once. Unfortunately, this method has two fatal problems:
1. There is no way to write the desired properties when the object is constructed, because the prototype is outside the scope of the constructor, and there is no way to write the property values ​​when the object is created by passing parameters. Values ​​can only be overridden after the object has been created.
2. The fatal problem is that when a property points to an object, the object will be shared by multiple instances. Consider the following code:
Copy code The code is as follows:

var Obj = function () { }
Obj.prototype.name = 'me';
Obj.prototype.flag = new Array('A', 'B');
Obj.prototype.showName = function () {
alert(this.name);
}
var obj1 = new Obj();
var obj2 = new Obj();
obj1.flag.push('C');
alert(obj1.flag); // A,B,C
alert(obj2.flag); //A,B,C

Yes, when the flag attribute points to the object , then both instances obj1 and obj2 share it, even if we only change the flag attribute of obj1, its change is still visible in instance obj2.
Faced with this problem, we have to think about whether we should combine [constructor method] and [prototype method] to make them complementary. . .

 [Constructor and prototype mixed method]
We let the properties be created using the constructor method, and the methods can be created using the prototype method:
Copy Code The code is as follows:

var Obj = function (name) {
this.name = name;
this.flag = new Array(' A', 'B');
}
Obj.prototype = {
showName : function () {
alert(this.name);
}
}
var obj1 = new Obj();
var obj2 = new Obj();
obj1.flag.push('C');
alert(obj1.flag); // A,B,C
alert(obj2.flag); //A,B

This method effectively combines the advantages of prototypes and constructors. It is currently the most used method and has the least side effects.
However, some people who pursue perfection are still not satisfied because visually they have not yet met their requirements, because the process of creating methods through prototypes still visually makes people feel that it does not look like instance methods (especially For developers of traditional OOP languages. )
Therefore, we can make the prototype active and add it to the constructor to make the constructor more visually unified. This series of processes can be completed with only one judgment.
Copy code The code is as follows:

var Obj = function (name) {
this.name = name;
this.flag = new Array('A', 'B');
if (typeof Obj. _init == 'undefined') {
Obj.prototype = {
showName : function () {
alert(this.name);
}
};
Obj._init = true;
}
}

As above, use _init as a flag to determine whether a method has been created for the prototype. If so then it will not be executed. In fact, there is no change in essence. The method is still created through the prototype. The only difference is that this constructor looks "unified".
However, there are problems with this dynamic prototyping method, which is not discussed in depth in "JavaScript Advanced Programming". When you create the first object, the prototype is not built before the object is instantiated, so it is not accessible at all. So the first object cannot access the prototype method. At the same time, this method will also have problems in subclass inheritance.
I will explain the solution in the next article.

In fact, in terms of ease of use, I personally feel that there is no need to make this judgment. . . Haha ^_^
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
使用PHP的json_encode()函数将数组或对象转换为JSON字符串使用PHP的json_encode()函数将数组或对象转换为JSON字符串Nov 03, 2023 pm 03:30 PM

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,已经成为Web应用程序之间数据交换的常用格式。PHP的json_encode()函数可以将数组或对象转换为JSON字符串。本文将介绍如何使用PHP的json_encode()函数,包括语法、参数、返回值以及具体的示例。语法json_encode()函数的语法如下:st

源码探秘:Python 中对象是如何被调用的?源码探秘:Python 中对象是如何被调用的?May 11, 2023 am 11:46 AM

楔子我们知道对象被创建,主要有两种方式,一种是通过Python/CAPI,另一种是通过调用类型对象。对于内置类型的实例对象而言,这两种方式都是支持的,比如列表,我们即可以通过[]创建,也可以通过list(),前者是Python/CAPI,后者是调用类型对象。但对于自定义类的实例对象而言,我们只能通过调用类型对象的方式来创建。而一个对象如果可以被调用,那么这个对象就是callable,否则就不是callable。而决定一个对象是不是callable,就取决于其对应的类型对象中是否定义了某个方法。如

使用Python的__contains__()函数定义对象的包含操作使用Python的__contains__()函数定义对象的包含操作Aug 22, 2023 pm 04:23 PM

使用Python的__contains__()函数定义对象的包含操作Python是一种简洁而强大的编程语言,提供了许多强大的功能来处理各种类型的数据。其中之一是通过定义__contains__()函数来实现对象的包含操作。本文将介绍如何使用__contains__()函数来定义对象的包含操作,并且给出一些示例代码。__contains__()函数是Pytho

使用Python的__le__()函数定义两个对象的小于等于比较使用Python的__le__()函数定义两个对象的小于等于比较Aug 21, 2023 pm 09:29 PM

标题:使用Python的__le__()函数定义两个对象的小于等于比较在Python中,我们可以通过使用特殊方法来定义对象之间的比较操作。其中之一就是__le__()函数,它用于定义小于等于比较。__le__()函数是Python中的一个魔法方法,并且是一种用于实现“小于等于”操作的特殊函数。当我们使用小于等于运算符(<=)比较两个对象时,Python

详解Javascript对象的5种循环遍历方法详解Javascript对象的5种循环遍历方法Aug 04, 2022 pm 05:28 PM

Javascript对象如何循环遍历?下面本篇文章给大家详细介绍5种JS对象遍历方法,并浅显对比一下这5种方法,希望对大家有所帮助!

Python中如何使用getattr()函数获取对象的属性值Python中如何使用getattr()函数获取对象的属性值Aug 22, 2023 pm 03:00 PM

Python中如何使用getattr()函数获取对象的属性值在Python编程中,我们经常会遇到需要获取对象属性值的情况。Python提供了一个内置函数getattr()来帮助我们实现这个目标。getattr()函数允许我们通过传递对象和属性名称作为参数来获取该对象的属性值。本文将详细介绍getattr()函数的用法,并提供实际的代码示例,以便更好地理解。g

使用Python的isinstance()函数判断对象是否属于某个类使用Python的isinstance()函数判断对象是否属于某个类Aug 22, 2023 am 11:52 AM

使用Python的isinstance()函数判断对象是否属于某个类在Python中,我们经常需要判断一个对象是否属于某个特定的类。为了方便地进行类别判断,Python提供了一个内置函数isinstance()。本文将介绍isinstance()函数的用法,并提供代码示例。isinstance()函数可以判断一个对象是否属于指定的类或类的派生类。它的语法如下

Python中如何使用__add__()函数定义两个对象的加法运算Python中如何使用__add__()函数定义两个对象的加法运算Aug 22, 2023 am 11:12 AM

Python中如何使用__add__()函数定义两个对象的加法运算在Python中,可以通过重载运算符来为自定义的对象添加对应的运算功能。__add__()函数是用于定义两个对象的加法运算的特殊方法之一。在本文中,我们将学习如何使用__add__()函数来实现对象的加法运算。在Python中,可以通过定义一个类来创建自定义的对象。假设我们有一个叫做"Vect

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 Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.