当前位置:网站首页>JS encapsulation at a glance
JS encapsulation at a glance
2022-07-28 13:21:00 【CCC Chen Chen】
You'll see it JS encapsulation
Recently on js Class encapsulation is used more and more frequently , I often have a headache because I don't know which way to package , Now let's make a summary
Basic concepts
encapsulation : Encapsulate objective things into abstract classes , Hide attributes and methods , Only public interfaces
attribute 、 Methods classification :
- Private properties and methods : Can only be accessed inside the constructor , Can't be accessed from outside ( Used in constructors var Declared properties )
- Public properties and methods : Outside the object, you can access the properties and methods inside the object ( Used in constructors this, Set the constructor prototype object, such as Person.prototype.xxx)
- Static properties and methods : Methods defined on constructors , such as Person.xxx, You can call... Without an instance
ES6 Front packaging
function (function)– The simplest packaging
「 Preface :」
First, the first question , Function is not a kind of encapsulation ?
Of course, it is encapsulated .《JavaScript Advanced programming 》 A book says :
Function is a core concept for any language . You can encapsulate any number of statements through functions , And it can be anywhere 、 Call execution at any time .
「 How to package :」 Write scattered statements into curly brackets of functions , Become the body of the function , Then you can call .
「 Unpacked code :」
var oDiv = document.getElementsByTagName("div")[0];
var p = document.createElement("p");
body.style.backgroundColor = "green";
p.innerText =" I am the new label content "; oDiv.appendChild(p);
shortcoming :
This code will be executed every time , Waste resources to be overwritten by variables with the same name —— Because it is declared under the global scope , Therefore, it is easy to be overwritten by variables with the same name
「 Encapsulated code :」
function createTag() {
var oDiv = document.getElementsByTagName("div")[0];
var p = document.createElement("p");
body.style.backgroundColor = "green";
p.innerText = " I am the new label content ";
oDiv.appendChild(p);
}
advantage :
Improved code reusability ; Execute on demand —— The parser reads here , Functions don't execute immediately , Avoid global variables only when called —— Because there is a problem of function
Generate the original schema of the instance object
If we regard people as an object , Have a name and gender 2 Attributes ;
var person = {
name: '',
sex: ''
}
According to the properties of the object , Generate 2 Instance objects :
var P1 = {
};
P1.name = 'Jack';
P1.sex = 'boy';
var P2 = {
};
P2.name = 'lisa';
P2.sex = 'girl'
Okay , This is the simplest encapsulation .
Have you found that this is the first 2 A big disadvantage :
Generate several instances , It's very troublesome to write , Duplicate code ; And there is no connection between similar object instances and prototypes ;
Improvements to the original pattern —— Factory mode
function Person(name, sex) {
return {
name, sex }
}
let p1 = new Person('Jack','boy');
let p2 = new Person('lisa','girl');
console.log(p1) //{name: "Jack", sex: "boy"}
console.log(p2) //{name: "lisa", sex: "girl"}
advantage :
Solve the problem of code duplication .
shortcoming : p1 and p2 There is no internal connection between , It does not reflect that they are instances of the same prototype object .
Constructor Pattern
So-called " Constructors ", It's just a normal function , But it's used internally this Variable . Use for constructors new Operator , You can generate instances , also this Variables are bound to instance objects .
such as Person The prototype object of is written like this :
function Person(name, sex) {
this.name = name;
this.sex = sex;
}
Now you can generate instances :
let p1 = new Person('Jack','boy');
let p2 = new Person('lisa','girl');
console.log(p1) //{name: "Jack", sex: "boy"}
console.log(p2) //{name: "lisa", sex: "girl"}
constructor It is a property in the constructor prototype object , Normally, it points to the prototype object Person.
At this time p1 and p2 Will automatically contain a constructor attribute , Constructors that point to them .
alert(p1.constructor == Person); //true
alert(p2.constructor == Person); //true
instanceof Operator is used to detect the prototype Whether the attribute appears on the prototype of an instance object .
usage : object instanceof constructor
object: Refers to an instance object ;
constructor: Some constructor ;
instanceof Operator to detect constructor.prototype Does it exist in parameter object On the prototype chain .
alert(p1 instanceof Person); //true
alert(p2 instanceof Person); //true
Does it feel that the constructor mode is not bad 🤪
In fact, there are still some problems with the constructor pattern
Please read on
Problems with constructor patterns
Constructor method is easy to use , But there is a problem of wasting memory . Now let's give Person Object to add a property age And a way getName, And then generate instance objects :
function Person(name, sex) {
this.name = name;
this.sex = sex;
this.age = 20;
this.getName = function () {
console.log('name') } }
let p1 = new Person('Jack','boy');
let p2 = new Person('lisa','girl');
console.log(p1)
console.log(p2)
Don't you see anything wrong :
There seems to be no problem on the surface , But actually doing it , There is a big drawback . That is, for each instance object ,age Properties and getName() Methods are as like as two peas. , Generate one instance at a time , All have to be repeated for content , Use more memory . It's not environmentally friendly , It's also inefficient
console.log(p1.getName == p2.getName) //false
Do you want to ask now ?(⊙ˍ⊙)?
Can you let age Properties and getName() Method is generated only once in memory Then all instances point to that memory address ?
Of Course
So let's look down
Prototype Pattern
Javascript Regulations , Each constructor has one prototype attribute , Point to another object . All the properties and methods of this object , Will be inherited by an instance of the constructor .
It means , We can put those invariant properties and methods , Directly defined in prototype On the object .
function Person(name, sex) {
this.name = name;
this.sex = sex;
}
Person.prototype.age = 20;
Person.prototype.getName = function(){
console.log('name')
}
let p1 = new Person('Jack','boy');
let p2 = new Person('lisa','girl');
console.log(p1)
console.log(p2)
p1.getName()
At this point, the age And a way getName Method , It's all the same memory address , Point to prototype object , Therefore, the operation efficiency is improved .
console.log(p1.getName == p2.getName) //true
「isPrototypeOf()」 This method is used to judge a proptotype The relationship between an object and an instance .
alert(Person.prototype.isPrototypeOf(p1)); //true
alert(Person.prototype.isPrototypeOf(p2)); //true
「hasOwnProperty()」 Each instance object has a hasOwnProperty() Method , Used to determine whether a property is a local property , Or inherit from prototype Object properties .
alert(p1.hasOwnProperty("name")); // true
alert(p1.hasOwnProperty("age")); // false
「in Operator 」 Can be used to judge , Whether an instance contains a property , Whether it's local or not .
alert("name" in p1); // true
alert("age" in p1); // true
//in Operator can also be used to traverse all properties of an object .
or(var prop in p1) {
alert("p1["+prop+"]="+p1[prop]); }
A complete example :
function Person(name, age) {
// Private properties and methods
var sex = ' Secret ';
var getSex = function () {
console.log(sex)
}
// Public properties and methods
this.name = name;
this.age = age;
this.descript = ' I have a common attribute '
this.getInfo = function () {
getSex()
console.log(this.name, this.age)
}
}
// Static properties and methods
Person.descript = ' I like hot pot ...';
Person.work = function () {
console.log(' I am a front-end development engineer ')
}
// Add properties and methods to prototype objects
Person.prototype.descript = ' I am an attribute on the prototype '
Person.prototype.hobby = [' swimming ', ' running '];
Person.prototype.getHobby = function () {
console.log(p1.hobby)
}
var p1 = new Person(' Lisa ',23);
console.log(p1)
console.log(p1.sex) // Private property undefined
console.log(p1.descript) // I have a common attribute
// Because I have descript attribute , So use your own attributes directly
console.log(p1.hobby) // Attributes in prototypes [" swimming ", " running "]
console.log(Person.descript) // Static attribute I like hot pot ...
Person.work() // Static methods I am a front-end development engineer
p1.getInfo() // There is a common way Secret Lisa 23
p1.getHobby() // The method in the prototype Print hobby
// I don't have this method , But found on the prototype , So you can print it out
// p1.getSex() // Private property Report errors
// p1.work(); // Static methods Report errors
console.log(Person.sex) // Report errors Static attribute
summary
「 One 、 Private property 、 Public attribute 、 Static attribute concept :」
Private properties and methods : It can only be accessed inside the constructor and cannot be accessed externally ( Use... Within the constructor var Declared properties );
Public properties and methods ( Or instance method ): Outside the object, you can access the properties and methods inside the object ( Use... Within the constructor this Set up , Or set it on the constructor prototype object, such as Person.prototype.xxx);
Static properties and methods : Methods defined on constructors ( such as Person.xxx), You can call... Without an instance ;
「 Two 、 Properties on instance objects and properties on constructor prototypes :」
Although the properties and methods defined on the constructor prototype object cannot be directly expressed on the instance object , But instance objects can access or call them .
When accessing the properties of an object Or method , It doesn't just look up on that object , It also looks for the prototype of the object , And the prototype of the object , Look up layer by layer , Until you find a property or method with a matching name or reach the end of the prototype chain (null)–( Prototype chain search );
「 3、 ... and 、 Three methods of traversing instance object properties :」
Use for…in… You can get the attributes of the instance object itself and the attributes on the prototype chain ; Use Object.keys() and Object.getOwnPropertyNames() You can only get the properties of the instance object itself ;hasOwnProperty() Method to determine whether an attribute is the attribute of the instance itself ;
「 Four 、 Be careful 」
this.xxx It means adding properties or methods to the instances created by using constructors , Instead of adding ; Only Person.xxx Is to add attributes or methods to the constructor ; If you have this attribute or method , Use your own attributes or methods , If you don't have one, look it up level by level .
ES6 Later packaging
stay ES6 after , Added class This keyword .
class It's class , and ES5 The constructors in are very similar , Most of the functions are consistent , however class Writing , It can make the function of object prototype clearer , More in line with the characteristics of object-oriented language .
And ES5 Differences in encapsulation writing :
「ES5 Writing :」
function Person (name, age){
this.name = name;
this.age = age;
}
Person.prototype.getInfo = function(){
console.log(this.name,this.age)
}
「ES6 Writing :」
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
getInfo(){
console.log(this.name,this.age)
}
}
「 difference :」
class All of the internal defined methods , It's all inestimable . The methods defined in the prototype can be enumerated .
function Person (name, age){
this.name = name;
this.age = age;
}
Person.prototype.getInfo = function(){
console.log(this.name,this.age)
}
console.log( Object.keys(Person.prototype)) //["getInfo"]
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
getInfo(){
console.log(this.name,this.age)
}
}
console.log( Object.keys(Person.prototype)) //[]
「 Be careful :」
constructor Namely ES5 How to write a constructor , and this Keyword represents instance object . That is to say ES5 Constructor for Person Corresponding ES6 Of Person Construction method of class constructor. When defining a class, there is no need to add function This reserved word , Just put the function definition directly in ok 了 . There is no need to add commas between methods , Otherwise, an error will be reported ; The data type of a class is a function , The class itself points to the constructor
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
}
console.log(Person ===Person.prototype.constructor ) //true
「 All methods of a class are defined in the prototype Attribute 」
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
getName(){
console.log(this.name)
}
getAge(){
console.log(this.age)
}
}
// Equate to
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
}
Person.prototype= {
getInfo(){
console.log(this.name,this.age)
},
getAge(){
console.log(this.age)
}
}
hasOwnProperty()
javascript This method is provided in , Detect whether the attribute of the object itself contains the specified attribute , Returns a Boolean value .
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
}
Person.prototype= {
getInfo(){
console.log(this.name,this.age)
},
getAge(){
console.log(this.age)
}
}
var p = new Person('lisa', 23)
console.log(p.hasOwnProperty('getInfo')) //false
console.log(p.hasOwnProperty('name')) // true
constructor Method
constructor Method is the default method of a class , adopt new This method is called automatically when the command generates an object instance . A class must have constructor Method , If no definition is displayed , Will add an empty constructor Method .
class Person {
}
// Equate to
class Person {
constructor(){
}
}
「 Be careful :」
constructor Method returns the instance object by default, that is this, However, you can specify to return another object ; Class must use new To call , Otherwise, the report will be wrong .
Static properties and static methods (static)
The class is the stereotype of the instance , All methods defined in the class will be inherited by the instance .
But
When static attributes or static methods refer to class Its own properties or methods , Not an instance property or method , therefore class Can be called directly .
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
static descript = ' I am a static attribute ';
static getDescript(){
console.log(" I'm a static method ")
}
}
console.log(Person.descript) // I am a static attribute
Person.getDescript() // I'm a static method
class The essence of is also an object , So you can use it Person.xxx Methods of define static properties and static methods .
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
}
Person.descript = ' I am a static attribute ';
Person.getDescript=function (){
console.log(" I'm a static method ")
}
console.log(Person.descript) // I am a static attribute
Person.getDescript() // I'm a static method
Instance properties of class
stay class in , Use = To define an attribute and method , Effect and this The definition is the same , Will be defined on the instance .
class Person{
constructor(name, age){
this.name = name;
this.age = age;
this.getName = function () {
console.log(this.name)
}
}
myProp = ' I am an instance property '; // Properties of instances
getMyProp = function() {
// Example method
console.log(this.myProp)
}
getInfo(){
// Methods belonging to the prototype of a class
console.log(' pick up information ')
}
}
let p = new Person('lisa', 23)
console.log(p.myProp) // I am an instance property
p.getMyProp() // I am an instance property
console.log(p)
console.log(p.hasOwnProperty('getName')) //true
console.log(p.hasOwnProperty('getMyProp')) //true
console.log(p.hasOwnProperty('getInfo')) //false
this The direction of
Class if contains this, It will point to the instance of the class by default .
class Person{
constructor(name, age){
this.name = name;
this.age = age;
var type = ' I am a private property '
this.desc = ' I'm through this Properties defined '
this.getName = function () {
console.log(this.name)
}
}
desc = ' I define the attribute through the equals sign '; // Properties of instances
getMyProp = function() {
console.log(this) // Instance object
console.log(this.desc) // I'm through this Properties defined
console.log(desc) // I'm defined outside
}
}
var desc = ' I'm defined outside '
let p = new Person('lisa', 23)
console.log(p)
p.getMyProp()
「 analysis :」
because constructor Own desc This attribute , So the instance uses this attribute first , If constructor No such attribute , Will use = Properties defined .this By default, it points to the instance of the class .
Print desc This variable is , Find yourself without this variable , So look up layer by layer , Until I found window This variable exists in , Before printing out the variable .
No variable promotion
new Foo();
class Foo{}
In the above code ,Foo Class is used before , The definition is after , This will give you an error . because ES6 Do not promote variables to the code header .
ES5 There is variable promotion , You can use it first and define it later .
var p = new Person()
function Person () {}
summary
class If there is an attribute or method with the same name in , use this The defined method will override the = Defined properties or methods ;
All methods of a class are defined in the prototype Attribute ;
class No variable promotion ;
When static attributes or static methods refer to class Its own properties or methods , Not an instance property or method , therefore class Can be called directly . Class if contains this, It will point to the instance of the class by default .
边栏推荐
- 【C语言易错点】第4篇:结构体在内存中存储规则详讲
- .NET的求复杂类型集合的差集、交集、并集
- 什么叫杂谈(e网杂谈)
- Databinding+livedata can easily realize skin changing without restart
- 2020jenkins study notes
- Original juice multifunctional Juicer touch chip-dlt8t02s-jericho
- 拥有游戏的一部分,写在我的世界禁用NFT之后
- RGB game atmosphere light touch chip-dlt8s04a-jericho
- Aragon creates Dao polygon BSC test network
- Pointnet++ Chinese Translation
猜你喜欢

GameStop熊市杀入NFT交易,老牌游戏零售商借Web3焕发第二春

一根筋教育PHP培训 知行合一收热捧

leetcode-136.只出现一次的数字

Led aquarium lamp touch chip-dlt8t02s-jericho

【嵌入式C基础】第5篇:原码/反码/补码

The essence of enterprise Digitalization

JVM 内存管理 你知道多少

Chinese translation of pointnet:deep learning on point sets for 3D classification and segmentation
![[embedded C foundation] Part 6: super detailed explanation of common input and output functions](/img/eb/69264bc0d8e9349991b7b9e1b8ca22.png)
[embedded C foundation] Part 6: super detailed explanation of common input and output functions

Leetcode daily question (2196. create binary tree from descriptions)
随机推荐
Understanding of vite2
黑猫带你学eMMC协议第26篇:eMMC的硬件复位操作(H/W reset)
管理区解耦架构见过吗?能帮客户搞定大难题的
Brother bird talks about cloud native security best practices
Chapter 6 promotion
Le transaction
[error prone points of C language] Part 4: detailed rules for storing structures in memory
Chapter 6 提升
8、 Kubernetes network and load balancing
夜神模拟器抓包微信小程序
2020-12-13
Li FuPan: application practice of kata safety container in ant group
Black cat takes you to learn EMMC Protocol Part 26: hardware reset operation of EMMC (h/w reset)
企业数字化本质
Black cat takes you to learn EMMC Protocol Part 24: detailed explanation of EMMC bus test program (cmd19 & cmd14)
Getderivedstatefromprops lifecycle
With 433 remote control UV lamp touch chip-dlt8sa20a-jericho
【嵌入式C基础】第8篇:C语言数组讲解
RGB game atmosphere light touch chip-dlt8s04a-jericho
Aragon creates Dao polygon BSC test network