Home > Web Front-end > JS Tutorial > body text

Analysis of encapsulation in JS object-oriented programming

不言
Release: 2018-08-01 16:07:37
Original
2177 people have browsed it

This article introduces to you the analysis of encapsulation in JS object-oriented programming. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Our well-known object-oriented languages ​​such as C and Java all have the concept of classes. Classes are type templates of instances. For example, Student represents the type of student, not Represents any specific student, and the instance is a specific object created based on this type, such as zhangsan, lisi. The object generated by the class embodies the transformation from abstract template to concrete Process, this is called Class-based object-oriented approach, and JavaScript does not have the concept of classes, it is Prototype-based object-oriented approach (Although Es6 adds class, The essence is to encapsulate the prototype method). To sum up, the following two points are:

  • In the class-based object-oriented approach, objects (objects) rely on classes (classes) to generate.

  • In the prototype-based object-oriented approach, objects are constructed by relying on constructors and prototypes.

The first feature of object-oriented language is undoubtedly encapsulation. In JS, the process of encapsulation is to "wrap" some properties and methods into objects, then we How to encapsulate properties and methods, or how to create objects (hereinafter, we will talk about creating objects)? The following is explained in a step-by-step manner:

Object literal--> Factory pattern--> Constructor--> Prototype pattern--> Constructor prototype model

Object literal

There are two primitive ways to create objects in JS:

  • Object literal

var  person = {
    name: "leon",
    age: "20",

    greeting: function() {
      alert('Hi!');
    }
}
Copy after login
  • Add attribute methods to Object instances

var person = new Object();
person.name = "leon";
person.age = "20";

person.greeting = function() {
  alert('Hi!');
};
Copy after login
  • Advantages: Simple code

  • Disadvantages: Creating multiple objects will generate a lot of code, which is troublesome to write, and there is no concept of instances and prototypes.

  • Solution: Factory pattern.

Factory Pattern

The factory pattern is a well-known design pattern in the programming field, which abstracts the process of creating specific objects. Create a function in JS and put the process of creating new objects, adding object properties, and returning objects into this function. Users only need to call the function to generate objects without paying attention to the details of object creation. This is called the factory pattern:

function createPerson(name, age) {
  var person = new Object();
  person.name = name;
  person.age = age;

  person.greeting = function() {
    alert('Hi!');
  };
}

var person1 = createPerson("leon", "20");
Copy after login
  • Advantages: The factory pattern solves the problem of duplication of code for creating objects using object literals. The same API can be used to create similar objects.

  • Disadvantages: Because the object is created by calling a function, the type of the object cannot be identified.

  • Solution: Constructor function

Constructor function

The only difference between the constructor function and other functions in JS is that The way it is called is different. Any function can be used as a constructor as long as it is called through the new operator. Let’s look at the following example:

function Person(name, age) {
  this.name = name;
  this.age = age;
  
  this.greeting = function() {
    alert('Hi!');
  };
  // return this;
}

var person1 = new Person("leon", "20");
var person2 = new Person("jack", "21");
Copy after login

Through the constructor new An instance goes through four steps:

  1. Create a new object;

  2. Bind this in the constructor to the new object;

  3. Add properties and methods to the new object;

  4. Return a new object (JS engine will add return this; by default).

The objects created through the constructor have a constructor attribute, which is a pointer to the constructor itself, so the type of the object can be detected. :

alert(person1.constructor === Person) //true
alert(person1 instanceof Person) // true
Copy after login

But there is still a problem:

alert(person1.greeting == person2.greeting) //false
Copy after login

greeting() is defined in the same constructor, but functions with the same name on different instances are not equal, This means that the memory spaces of the two functions with the same name are inconsistent, that is, the method in the constructor must be recreated on each instance. This is obviously not cost-effective.

  • Advantages: Solve similar object creation problems and can detect object types.

  • Disadvantages: The constructor method needs to be created once on each instance.

  • Solution: Prototype mode.

Prototype pattern

Finally talked about the prototype pattern. Each constructor in JS has a prototype attribute, which is a pointer. Points to the prototype object, which contains the properties and methods shared by all instances of this constructor. There is a <em>proto</em> attribute in the instance object, which points to the prototype object, that is, constructor.prototype == prototype object == object._proto_, then the object You can get the properties and methods in the prototype object. At the same time, all objects have a constructor attribute, and the constructor of the prototype object points to its corresponding constructor.

使用原型,就意味着我们可以把希望实例共享的属性和方法放到原型对象中去,而不是放在构造函数中,这样每一次通过构造函数new一个实例,原型对象中定义的方法都不会重新创建一次。来看下面的例子:

function Person() {
}

Person.prototype.name = "leon";
Person.prototype.age = "20";
Person.prototype.greeting = function() {
  alert('Hi!');
};

var person1 = new Person();
var person2 = new Person();
alert(person1.name); //"leon"
alert(person2.name); //"leon"
alert(person1.greeting == person2.greeting); //true
Copy after login
  • 优点:与单纯使用构造函数不一样,原型对象中的方法不会在实例中重新创建一次,节约内存。

  • 缺点:使用空构造函数,实例 person1 和 person2 的 name都一样了,我们显然不希望所有实例属性方法都一样,它们还是要有自己独有的属性方法。

  • 解决办法:构造函数+原型模式组合使用。

另外 JS 中还定义了一些与原型相关的属性,这里罗列一下:

  • Object.getPrototypeOf(),取得实例的原型对象。

Object.getPrototypeOf(person1);
Copy after login
  • isPrototypeOf(),判断是不是一个实例的原型对象。

Person.prototype.isPrototypeOf(person1);
Copy after login
  • hasOwnProperty(),检测一个属性是否存在于实例中

person1.hasOwnProperty("name");
Copy after login
  • in,判断一个属性是否存在于实例和原型中。

"name" in person1;
Copy after login

构造函数+原型模式

最后一种方式就是组合使用构造函数和原型模式,构造函数用于定义实例属性,而共享属性和方法定义在原型对象中。这样每个实例都有自己独有的属性,同时又有对共享方法的引用,节省内存。

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype = {
  constructor: Person,
  nationality: "China",
  greeting: function() {
    alert(this.name);
  }
}

var person1 = new Person("leon", "20");
var person2 = new Person("jack", "21");
alert(person1.greeting == person2.greeting) //true
Copy after login

上面代码中用对象字面量的形式重写了原型对象,这样相当于创建了一个新的对象,那么它的constructor属性就会指向Object,这里为了让它继续指向构造函数,显示的写上了constructor: Person

这种构造函数与原型模式混成的模式,是目前在 JS 中使用最为广泛的一种创建对象的方法。

相关文章推荐:

jQuery自调用匿名函数是如何调用的?

JavaScript是否使用var定义变量的区别,举例说明

The above is the detailed content of Analysis of encapsulation in JS object-oriented programming. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!