JavaScript Introduction to Object-oriented Tutorial

Source: Internet
Author: User
Tags constructor hasownproperty

So what should we do if we're going to encapsulate the property and method (methods) into an object and even generate an instance object from a prototype object?

In general, the object-oriented approach that you are familiar with is based on class-oriented objects, declares a class, and then creates objects based on the description of the class declaration, using the inheritance and combinatorial relationships between classes and classes to use code. In most cases, class-oriented object-oriented languages (C++,c#,java, and so on) incorporate classes into their own type systems, where each class is also a variable type (Variable type) and allows the value of the subclass type to be assigned to the parent class type variable.

And JS design uses a completely different way of thinking. The first type of JS is not extensible (that is, the user of the language cannot add a new type) so that the language cannot be used. According to language standards, JS designed 6 types of data users can use (because JS is weak type, so the variable has no type, only data have type):
Boolean number String Null Undefined Object

In order to achieve object-oriented, JS put all the objects into the object type, so that JS has 6 types of data users can use. In addition to the UNDEFINED,JS for all types of literals (literal) syntax, now, JS's object face value represents a very successful design, and now even become a data interchange format, which is familiar with the JSON.

Now start writing object-oriented JS (OO js), if you have any questions or I missed something, in the comments below tell me.

Literal notation
Literal notation is just one way to create objects in JavaScript, yes, there are more ways to do this. Literal notation is the preferred method when you intend to create an object instance.


var bill = {};

The code above is not very useful, just creating an empty object. Let's add some properties and methods dynamically to this object.

View Source code Printing Help
Bill.name = "Bill E Goat";

Bill.sound = function () {

Console.log (' bahhh! ');

};
Here we add the "name" attribute and assign it to "Bill E Goat". We don't have to create empty objects before, and we can do all of the above with just one step.


var bill = {

Name: "Bill E Goat",

Sound:function () {

Console.log (' bahhh! ');

}

};

It's pretty neat, isn't it? Accessing properties and methods is just as easy.

View Source code Printing Help
1 bill.name; "Bill E Goat."

2 Bill.sound (); "Bahhh"

If the property name is not a valid identifier we can also access it like this:

View Source code Printing Help
1 bill[' name ']; "Bill E Goat."
Notice that when we call a method, we add a pair of parentheses after the method name to invoke it. Let's rewrite the current sound method and pass it a parameter to call it:


Bill.sound = function (noise) {

Console.log (Noise);

};

Bill.sound ("brrr!"); "Brrr!" He ' s cold

Well, we passed in a parameter (noise) and accessed it inside the method. Here we continue to add a method to access the Name property:


Bill.sayname = function () {

Console.log ("Hello" + this.name);

};

Bill.sayname (); "Hello Bill E Goat"

We can access the property through This.propertyname within a method


Bill.sayname; function

What the results of this code will be. We do not call Sayname with parentheses, it returns a method definition. Keep Exploring!


var sound = bill.sound;

Sound (' moo! '); "Moo!"

We assign a local method called sound to an object sound, and now you can add parentheses after sound and pass in the argument to call that method. What happens if we try to clone bill?

var sally = Bill;
Sally.name; "Bill E Goat", But her name is Sally silly
Sally.name = "Sally";
Sally.name; "Sally," Better.
Bill.name; "Sally", Oh no what happened to Bill
In the example above we created a new variable, Sally, and let it be equal to Bill. Now Sally and Bill are referencing the same object in memory. Changes to one object can affect the other.

Look at another example here:

Bill.name = "Bill E Goat";
Bill.sayname (); "Hello Bill E Goat";
var sayname = Bill.sayname;
Sayname; function, OK so far so good
Sayname (); "Hello", huh why didn ' t it print out Bills name?

Bill's Name property is a local variable, and the Sayname method is created globally, so this.name finds the value of name in the global scope. But the problem is that name is not defined. Let's define a global variable name to see what happens:


var name = "Bearded Octo";

Sayname (); "Hello Bearded Octo"

Here we create a global variable name and assign "bearded Octo". When we call the Sayname method it looks for name in the global scope and accesses the value "bearded Octo", very well. Look below constructor notation.

Constructor notation
Constructor notation is another way to write object-oriented JavaScript. When you need to set initial property values and methods for an object or want to create a different instance of an object but their properties and methods are different, then the preferred constructor notation mode. The following starts with creating an empty object:

1 function Game () {};
Notice that the first letter capitalized is used to indicate that it is a class. Let's use this class to create a new object:

var zelda = new Game ();
var SMB = new Game ();
Zelda.title = "Legend of Zelda";
Smb.title = "Super Mario brothers";
Zelda.title; "Legend of Zelda"
Smb.title; "Super Mario Brothers"

Our object now has its own attributes! When we create an object, we can either pass the value in the attribute or modify it later.

function Game (title) {
This.title = typeof title!== ' undefined '? Title: "";
};
var zelda = new Game ("Legend of Zelda");
Zelda.title; "Legend of Zelda"
Zelda.title = "Ocarina of Time";
Zelda.title; "Ocarina of Time"
var blank = new Game ();
Blank.title; // ""
The second line may be a little hard to understand. We use a ternary operator, which is just a way to write an if Else statement block to one line. He is equivalent to the following:

if (typeof title!== ' undefined ') {
This.title = title;
} else {
This.title = "";
}
is the same as
This.title = typeof title!== ' undefined '? Title: "";
If the object is created with the title argument passed, the title property of the object is set. If it is not passed in, it is set to the default value "".

We can create a method to access this property:

Zelda.lovetitle = function () {
Console.log ("I Love" + this.title);
};
Zelda.lovetitle (); "I Love Ocarina of"
That would look neat, but it would be better. We can add a method to the game class so that all objects created from the game class have this method:

Game.prototype.heartIt = function () {
Console.log ("I Heart" + this.title);
};
Zelda.heartit (); "I Heart Ocarina of Time"
Smb.heartit (); "I Heart Super Mario Brothers"

A higher level of a squint

First, the original mode of the generated object

Suppose we look at a cat as an object, it has two attributes of "first name" and "Color".

var Cat = {

Name: ',

Color: "

}

Now, we need to generate two instance objects based on the specification (schema) of this prototype object.

var cat1 = {}; Create an empty object

Cat1.name = "hairy"; Assigning values to the properties of a prototype object

Cat1.color = "Yellow";

var cat2 = {};

Cat2.name = "Er mao";

Cat2.color = "BLACK";

OK, so this is the simplest package, which encapsulates two attributes in one object. However, there are two disadvantages to this writing, one is that if you generate more than a few instances, it is very troublesome to write, and the second is between the example and the prototype, there is no way to see what connection.

Ii. improvement of the original model

We can write a function that solves the problem of code duplication.

function Cat (name,color) {

return {

Name:name,

Color:color

}

}

Then the instance object is generated, which is tantamount to calling the function:

var cat1 = Cat ("hairy", "yellow");

var cat2 = Cat ("Er Mao", "Black");

The problem with this approach remains that there is no intrinsic connection between CAT1 and CAT2 and that they are not examples of the same archetypal object.

Third, the constructor function pattern

To solve the problem of generating an instance from a prototype object, JavaScript provides a constructor (constructor) pattern.

The so-called "constructor", in fact, is a normal function, but the internal use of the this variable. The new operator is used on the constructor to generate an instance, and the this variable is bound to the instance object.

For example, a cat's archetypal object can now be written like this,

function Cat (name,color) {

This.name=name;

This.color=color;

}

We can now generate the instance object.

var cat1 = new Cat ("hairy", "yellow");

var cat2 = new Cat ("Er Mao", "Black");

alert (cat1.name); Nagymaros

alert (Cat1.color); Yellow

Then CAT1 and Cat2 automatically contain a constructor attribute that points to their constructors.

Alert (Cat1.constructor = = Cat); True

Alert (Cat2.constructor = = Cat); True

JavaScript also provides a instanceof operator that verifies the relationship between a prototype object and an instance object.

Alert (cat1 instanceof Cat); True

Alert (cat2 instanceof Cat); True

Four, the problem of the constructor pattern

The constructor method works fine, but there is a problem with wasting memory.

See, we now add a invariant property "type" to the Cat object and add a method eat (eat the mouse). So, the prototype object cat becomes the following:

function Cat (name,color) {

THIS.name = name;

This.color = color;

This.type = "Feline animal";

This.eat = function () {alert ("Eat Mouse");

}

Or do you use the same method to generate an instance:

var cat1 = new Cat ("hairy", "yellow");

var cat2 = new Cat ("Er Mao", "Black");

alert (Cat1.type); Cat Family Animal

Cat1.eat (); Eat mice

There seems to be no problem on the surface, but in practice there is a big drawback. That is, for each instance object, the type attribute and the Eat () method are exactly the same, and each time an instance is generated, it must be duplicated, consuming some more memory. This is neither environmental protection nor efficiency.

Alert (cat1.eat = = cat2.eat); False

Can I have the type attribute and the Eat () method generate only once in memory, and then all instances point to that memory address? The answer is OK.

Five, prototype mode

JavaScript stipulates that each constructor has a prototype attribute that points to another object. All of the properties and methods of this object are inherited by the instance of the constructor.

This means that we can define the invariant properties and methods directly on the prototype object.

function Cat (name,color) {

THIS.name = name;

This.color = color;

}

Cat.prototype.type = "Feline animal";

Cat.prototype.eat = function () {alert ("Eat Mouse")};

Then, the instance is generated.

var cat1 = new Cat ("hairy", "yellow");

var cat2 = new Cat ("Er Mao", "Black");

alert (Cat1.type); Cat Family Animal

Cat1.eat (); Eat mice

The type attribute and the Eat () method of all instances are in fact the same memory address, pointing to the prototype object, thus increasing the efficiency of the operation.

Alert (cat1.eat = = cat2.eat); True

Vi. verification method of prototype mode

To match the prototype attribute, JavaScript defines some helper methods that help us to use it. ,

6.1 isprototypeof ()

This method is used to determine the relationship between a Proptotype object and an instance.

Alert (Cat.prototype.isPrototypeOf (CAT1)); True

Alert (Cat.prototype.isPrototypeOf (CAT2)); True

6.2 hasOwnProperty ()

Each instance object has a hasOwnProperty () method that is used to determine whether a property is a local property or a property that inherits from a prototype object.

Alert (Cat1.hasownproperty ("name")); True

Alert (Cat1.hasownproperty ("type")); False

6.3 In operator

The in operator can be used to determine whether an instance contains a property, whether it is a local property or not.

Alert ("name" in CAT1); True

Alert ("type" in CAT1); True

The in operator can also be used to traverse all the properties of an object.

For (Var prop in cat1) {alert ("cat1[" +prop+ "]=" +cat1[prop));

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.