Re-understand object-oriented
In order to illustrate that JavaScript is a completely object-oriented language, it is first necessary to start with the concept of object-oriented and discuss several concepts in object-oriented:
Based on these three points, C is a semi-object-oriented and semi-procedural language, because although it implements class encapsulation, inheritance and polymorphism, there are non-object global functions and variables. Java and C# are completely object-oriented languages. They organize functions and variables in the form of classes so that they cannot exist without objects. But here the function itself is a process, just attached to a certain class.
However, object-oriented is just a concept or programming idea, and it should not depend on a certain language for its existence. For example, Java uses object-oriented thinking to construct its language, and it implements mechanisms such as classes, inheritance, derivation, polymorphism, and interfaces. However, these mechanisms are only a means to implement object-oriented programming, not necessary. In other words, a language can choose an appropriate way to implement object orientation based on its own characteristics. Therefore, since most programmers first learn or use high-level compiled languages such as Java and C (although Java is semi-compiled and semi-interpreted, it is generally explained as a compiled language), they preconceivedly accept the term "class". Object-oriented implementation method, so when learning scripting languages, it is customary to use the concepts in class-based object-oriented languages to judge whether the language is an object-oriented language or whether it has object-oriented characteristics. This is also one of the important reasons that hinders programmers from learning and mastering JavaScript in depth.
In fact, the JavaScript language implements object-oriented programming through a method called prototype. Let's discuss the differences between the two methods of constructing the objective world, class-based object-oriented and prototype-based object-oriented.
Comparison between class-based object-oriented and prototype-based object-oriented approaches
In the class-based object-oriented approach, objects are generated based on classes. In the prototype-based object-oriented approach, objects are constructed using constructors and prototypes. Give an example from the objective world to illustrate the difference between the two ways of cognition. For example, when a factory builds a car, on the one hand, workers must refer to an engineering drawing and the design stipulates how the car should be manufactured. The engineering drawings here are like classes in language, and cars are manufactured according to this class; on the other hand, workers and machines (equivalent to constructors) use various parts such as engines, tires, The steering wheel (equivalent to each attribute of the prototype) constructs the car.
In fact, there is still debate about which of the two methods expresses object-oriented ideas more thoroughly. But the author believes that prototype object-oriented is a more thorough object-oriented approach for the following reasons:
First of all, the creation of objects in the objective world is the result of the construction of other physical objects, and abstract "drawings" cannot produce "cars". In other words, a class is an abstract concept rather than an entity, and the creation of objects is The creation of an entity;
Secondly, according to the most basic object-oriented rule that everything is an object, the class itself is not an object. However, the constructor and prototype in the prototype method are themselves other objects through the prototype method. Constructed object.
Thirdly, in a class-based object-oriented language, the state of an object is held by the object instance, and the behavior method of the object is held by the class that declares the object, and only the structure and Methods can be inherited; in prototype object-oriented languages, the behavior and status of the object belong to the object itself and can be inherited together (reference resources), which is closer to objective reality.
Finally, class-based object-oriented languages such as Java allow static properties and static methods to be declared in classes in order to make up for the inconvenience of not being able to use global functions and variables in procedural languages. In fact, there is no so-called static concept in the objective world, because everything is an object! In a prototype object-oriented language, except for built-in objects, global objects, methods or properties are not allowed to exist, and there is no static concept. All language elements (primitives) must depend on objects for their existence. However, due to the characteristics of functional languages, the objects on which language elements depend change with changes in the runtime context, which is specifically reflected in changes in the this pointer. It is this characteristic that is closer to the natural view that "everything belongs to something, and the universe is the foundation for the survival of all things."
JavaScript object-oriented basic knowledge
Although JavaScript itself does not have the concept of classes, it still has object-oriented characteristics, although it is different from common object-oriented languages.
The simple way to create an object is as follows:
function myObject() { }; JavaScript 中创建对象的方法一般来说有两种:函数构造法和字面量法,上面这种属函数构造法。下面是一个字面量法的例子: var myObject = { };
If you only need one object and do not need other instances of the object, it is recommended to use the literal method. If multiple instances of an object are required, the function constructor is recommended.
Define properties and methods
Function construction method:
function myObject() { this.iAm = 'an object'; this.whatAmI = function() { console.log('I am ' + this.iAm); }; };
Literal method:
var myObject = { iAm : 'an object', whatAmI : function() { console.log('I am ' + this.iAm); } };
The objects created by the above two methods have a property named "iAm" and a method named "whatAmI". Properties are variables in an object, and methods are functions in an object.
How to get attributes and call methods:
var w = myObject.iAm; myObject.whatAmI();
When calling a method, you must add parentheses after it. If you do not add parentheses, then it will just return a reference to the method.
The difference between the two methods of creating objects
For objects created by literal method, you can directly call its properties or methods using the reference of the object:
myObject.whatAmI();
For the function constructor, you need to create an instance of the object before you can call its properties or methods:
var myNewObject = new myObject(); myNewObject.whatAmI();
Use constructor
Now let’s return to the previous function construction method:
function myObject() { this.iAm = 'an object'; this.whatAmI = function() { console.log('I am ' + this.iAm); }; };
Actually, it looks like a function. Since it is a function, can I pass parameters to it? Modify the code slightly:
function myObject(what) { this.iAm = what; this.whatAmI = function(language) { console.log('I am ' + this.iAm + ' of the ' + language + ' language'); }; };
Then instantiate the object and pass in the parameters:
var myNewObject = new myObject('an object'); myNewObject.whatAmI('JavaScript');
The final output of the program is I am an object of the JavaScript language.
There are two ways to create objects, which one should I use?
For literal methods, because it does not require instantiation, if the value of an object is modified, the value of the object is permanently modified, and any other access will be the modified value. . For the function constructor, when modifying the value, the value of its instance is modified. It can instantiate N objects, and each object can have its own different value without interfering with each other. Compare the following code snippets.
Let’s look at the literal method first:
var myObjectLiteral = { myProperty : 'this is a property' }; console.log(myObjectLiteral.myProperty); // log 'this is a property' myObjectLiteral.myProperty = 'this is a new property'; console.log(myObjectLiteral.myProperty); // log 'this is a new property'
Even if a new variable is created to point to this object, the result is still the same:
var myObjectLiteral = { myProperty : 'this is a property' }; console.log(myObjectLiteral.myProperty); // log 'this is a property' var sameObject = myObjectLiteral; myObjectLiteral.myProperty = 'this is a new property'; console.log(sameObject.myProperty); // log 'this is a new property'
Look at the function construction method again:
// 用函数构造法 var myObjectConstructor = function() { this.myProperty = 'this is a property' }; // 实例化一个对象 var constructorOne = new myObjectConstructor(); // 实例化第二个对象 var constructorTwo = new myObjectConstructor(); // 输出 console.log(constructorOne.myProperty); // log 'this is a property' // 输出 console.log(constructorTwo.myProperty); // log 'this is a property' 和预期一样,两个对象的属性值是一样的。如果修个其中一个对象的值呢? // 用函数构造法 var myObjectConstructor = function() { this.myProperty = 'this is a property'; }; // 实例化一个对象 var constructorOne = new myObjectConstructor(); // 修改对象的属性 constructorOne.myProperty = 'this is a new property'; // 实例化第二个对象 var constructorTwo = new myObjectConstructor(); // 输出 alert(constructorOne.myProperty); // log 'this is a new property' // 输出 alert(constructorTwo.myProperty); // log 'this is a property'
As you can see, different objects instantiated using the function constructor are independent of each other and can each have different values. Therefore, which method to use to create objects depends on the actual situation.