Home  >  Article  >  Web Front-end  >  Detailed explanation of creating objects based on object-oriented JavaScript

Detailed explanation of creating objects based on object-oriented JavaScript

PHPz
PHPzOriginal
2016-05-16 15:26:231354browse

Every function we create has a prototype attribute, which is an object whose purpose is to contain properties and methods that can be shared by all instances of a specific type. Logically it can be understood this way: prototype is the prototype object of the object created by using the constructor. The advantage of using a prototype is that all object instances can share the properties and methods it contains. In other words, you don’t have to define object information in the constructor, but add this information directly to the prototype

The prototype method makes use of the prototype attribute of the object, which can be regarded as the method used to create a new object. Dependent prototype. Here, first use an empty constructor to set the function name. Then all properties and methods are assigned directly to the prototype attribute. I rewrote the previous example and the code is as follows:

function Car() { }; 
//将所有的属性的方法都赋予prototype属性 
Car.prototype.color = "blue"; 
Car.prototype.doors = 4; 
Car.prototype.mpg = 25; 
Car.prototype.showColor = function() { 
  return this.color; 
}; 
var Car1 = new Car(); 
var Car2 = new Car(); 
document.write(Car1.showColor()+"
");//输出:blue 
document.write(Car2.showColor());//输出:blue

In this code, first define the constructor Car() without any code. The next few lines of code define the properties of the Car object by adding properties to the Car's prototype property. When new Car() is called, all properties of the prototype are immediately assigned to the object to be created, which means that all Car instances store pointers to the showColor() function. Semantically speaking, all properties appear to belong to one object, thus solving the problems of the previous factory method and constructor method

In addition, using this method, you can also use the instanceof operator Check the type of object pointed to by a given variable:

The code is as follows:
document.write(Car1 instanceof Car);    //输出:tru

The prototype approach seems like a good solution. Sadly, it's not all that satisfying. First, this constructor has no parameters. Using the prototype method, you cannot initialize the attribute values ​​by passing parameters to the constructor, because the color attribute of Car1 and Car2 is equal to "blue", the doors attribute is equal to 4, and the mpg attribute is equal to 25. This means that you have to change the default value of a property after the object is created, which is annoying, but that's not the end of it. The real problem arises when properties point to objects rather than functions. Function sharing does not cause problems, but objects are rarely shared among multiple instances. Please consider the following example:

function Car() { };//定义一个空构造函数,且不能传递参数 
Car.prototype.color = "blue"; 
Car.prototype.doors = 4; 
Car.prototype.mpg = 25; 
Car.prototype.drivers = new Array("Mike","John"); 
Car.prototype.showColor = function() { 
  return this.color; 
}; 
var Car1 = new Car(); 
var Car2 = new Car(); 
Car1.drivers.push("Bill"); 
document.write(Car1.drivers+"
");//输出:Mike,John,Bill 
document.write(Car2.drivers);//输出 :Mike,John,Bill

In the above code, the attribute drivers is a pointer to an Array object containing the two names "Mike" and "John". Since drivers are reference values, both instances of Car point to the same array. This means adding the value "Bill" to Car1.drivers, which is also visible in Car2.drivers. Outputting either of these pointers results in the string "Mike,John,Bill" being displayed. Since there are so many problems when creating objects, you must be wondering, is there a reasonable way to create objects? The answer is yes, you need to use a combination of constructor and prototype methods

mixed constructor/prototype method (recommended to use

By mixing the constructor method and the prototype method, you can create objects just like other programming languages. The concept is very simple, that is, use the constructor to define all non-functional properties of the object, and use the prototype method to define the functional properties of the object ( method). The result is that all functions are created only once, and each object has its own object property instance. We rewrite the previous example as follows:

function Car(Color,Doors,Mpg) { 
 this.color = Color; 
 this.doors = Doors; 
 this.mpg = Mpg; 
 this.drivers = new Array("Mike","John"); 
}; 
Car.prototype.showColor = function() { 
   return this.color; 
}; 
var Car1 = new Car("red",4,23); 
var Car2 = new Car("blue",3,25); 
Car1.drivers.push("Bill"); 
document.write(Car1.drivers+"
");//输出:Mike,John,Bill 
documnet.write(Car2.drivers);//输出:Mike,John

Now it is more like creating a normal object. All non-function properties are created in the constructor, which means that the default value of the property can be assigned with the parameters of the constructor because only one instance of the showColor() function is created. , so there is no memory waste. In addition, adding the "Bill" value to the drivers array of Car1 will not affect the array of Car2, so when the values ​​of these arrays are output, Car1.drivers displays "Mike, John, Bill", and Car2.drivers displays "Mike, John". Because the prototype method is used, the instanceof operator can still be used to determine the type of the object.

This method is the main method used by ECMAScript, and it has other methods. However, some developers still feel that this method is not perfect.

For developers who are used to other languages, using a hybrid constructor/prototype approach may feel less harmonious. After all, most object-oriented languages ​​have a visual representation of properties and methods when defining classes. Encapsulation. Consider the following Java class:


Java很好地打包了Car类的所有属性和方法,因此看见这段代码就知道它要实现什么功能,它定义了一个对象的信息。批评混合的构造函数/原型方式的人认为,在构造函数内部找属性,在其外部找方法的做法不合逻辑。因此,他们设计了动态原型方法,以提供更友好的编码风格。

动态原型方法的基本想法与混合的构造函数/原型方式相同,即在构造函数内定义非函数属性,而函数属性则利用原型属性定义。唯一的区别是赋予对象方法的位置。下面是用动态原型方法重写的Car:

function Car(Color,Doors,Mpg) { 
 this.color = Color; 
 this.doors = Doors; 
 this.mpg = Mpg; 
 this.drivers = new Array("Mike","John"); 
 //如果Car对象中的_initialized为undefined,表明还没有为Car的原型添加方法 
 if (typeof Car._initialized == "undefined") { 
   Car.prototype.showColor = function() { 
    return this.color; 
   }; 
   Car._initialized = true; //设置为true,不必再为prototype添加方法 
 } 
} 
var Car1 = new Car("red",4,23);//生成一个Car对象 
var Car2 = new Car("blue",3,25); 
Car1.drivers.push("Bill");//向Car1对象实例的drivers属性添加一个元素 
document.write(Car1.drivers+"
");//输出:Mike,John,Bill 
document.write(Car2.drivers);//输出:Mike,John

 直到检查typeof Car._initialize是否等于"undefined"之前,这个构造函数都未发生变化。这行代码是动态原型方法中最重要的部分。如果这个值未定义,构造函数将用原型方式继续定义对象的方法,然后把 Car._initialized设置为true。如果这个值定义了(它的值为 true时,typeof 的值为Boolean),那么就不再创建该方法。简而言之,该方法使用标志(_initialized)来判断是否已给原型赋予了任何方法。该方法只创建并赋值一次,传统的 OOP开发者会高兴地发现,这段代码看起来更像其他语言中的类定义了。 

我们应该采用哪种方式呢?      

如前所述,目前使用最广泛的是混合的构造函数/原型方式。此外,动态原型方式也很流行,在功能上与构造函数/原型方式等价。可以采用这两种方式中的任何一种。不过不要单独使用经典的构造函数或原型方式,因为这样会给代码引入问题。总之JS是基于面向对象的一门客户端脚本语言,我们在学习它的面向对象技术的时候要的留意JS与其他严谨性高的程序语言的不同。也要正确使用JS创建对象的合理的方式,推荐使用构造函数与原型方式的混合方式创建对象实例。这样可以避免许多不必要的麻烦。

以上就是JavaScript基于面向对象之创建对象的全部内容,希望对大家的学习有所帮助。

【相关教程推荐】

1. JavaScript视频教程
2. JavaScript在线手册
3. 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