编写可维护面向对象的JavaScript代码[翻译]

Writing maintainable Object-Oriented (OO) JavaScript will save you money and make you popular. Don't believe me? Odds are that either you or someone else will come back and work with your code. Making that as painless an experience as possible will save time, which we all know equates to money. It will also win you the favor of those for whom you just saved a headache. But before we dive into writing maintainable OO JavaScript, let's just take a quick look at what OO is all about. If you know already about OO, feel free to skip the next section.

What is OO?
Object-oriented programming basically represents physical, real-world objects that you want to work with in code. In order to create objects, you need to first define them by writing what's called a class. Classes can represent pretty much anything: accounts, employees, navigation menus, vehicles, plants, advertisements, drinks, etc... Then, every time you want to create an object to work with, you instantiate one from a class. In other words, you create an instance of a class which gives you an object to work with. In fact, the best time to be using objects is when you'll be dealing with more than one of anything. Otherwise, a simple functional program will likely do just as well. Objects are essentially containers for data. So in the case of an employee object, you might store their employee number, name, start date, title, salary, seniority, etc... Objects also include functions (called methods) to handle that data. Methods are used as intermediaries to ensure data integrity. They're also used to transform data before storing it. For example, a method could receive a date in an arbitrary format then convert it to a standardized format before storing it. Finally, classes can also inherit from other classes. Inheritance allows you to reuse code across different types of classes. For example, both bank account and video store account classes could inherit from a base account class which would provide fields for profile information, account creation date, branch information, etc... Then, each would define its own transactions or rentals handling data structures and methods.

Warning: JavaScript OO is different
In the previous section I outlined the basics of classical object-oriented programming. I say classical because JavaScript doesn't quite follow those rules. Instead, JavaScript classes are actually written as functions and inheritance is prototypal. Prototypal inheritance basically means that rather than classes inheriting from classes, they inherit from objects using the prototype property.

Object Instantiation
Here's an example of object instantiation in JavaScript:

复制代码 代码如下:


// Define the Employee class
function Employee(num, fname, lname) {
this.getFullName = function () {
return fname + " " + lname;
}
};
// Instantiate an Employee object
var john = new Employee("4815162342", "John", "Doe");
alert("The employee's full name is " + john.getFullName());


There are three important things to note here:

I uppercased the first letter of my "class" function. That important distinction lets people know that it's for instantiation and not to be called as a normal function.
I use the new operator when instantiating. Leaving it out would simply call the function and result in problems.
Though getFullName is publicly available because it's assigned to the this operator, fname and lname are not. The closure created by the Employee function gives getFullName access to fname and lname while allowing them to remain private from everyone else.
Prototypal Inheritance
Now, here's an example of prototypal inheritance in JavaScript:

复制代码 代码如下:


// Define Human class
function Human() {
this.setName = function (fname, lname) {
this.fname = fname;
this.lname = lname;
}
this.getFullName = function () {
return this.fname + " " + this.lname;

}
}

// Define the Employee class
function Employee(num) {
this.getNum = function () {
return num;
}
};
// Let Employee inherit from Human
Employee.prototype = new Human();

// Instantiate an Employee object
var john = new Employee("4815162342");
john.setName("John", "Doe");
alert(john.getFullName() + "'s employee number is " + john.getNum());


This time, I've created a Human class which contains properties common to humans--I moved fname and lname there since all humans, not just employees have names. I then extended the Employee class by assigning a Human object to its prototype property.

Code Reuse Through Inheritance
In the previous example, I split the original Employee class in two. I moved out all the properties common to all humans into a Human class, and then caused Employee to inherit from Human. That way, the properties laid out in Human could be used by other objects such as Student, Client, Citizen, Visitor, etc... As you may have noticed by now, this is a great way to compartmentalize and reuse code. Rather than recreating all of those properties for every single type of object where we're dealing with a human being, we can just use what's already available by inheriting from Human. What's more, if we ever wanted to add a property like say, middle name, we'd do it once and it would immediately be available to everyone inheriting from Human. Conversely, if we only wanted to add a middle name property to just one object, we could do it directly in that object instead of adding it to Human.

Public and Private
I'd like to touch on the subject of public and private variables in classes. Depending on what you're doing with the data in an object, you'll want to either make it private or public. A private property doesn't necessarily mean that people won't have access to it. You may just want them to go through one of your methods first.

Read-only
Sometimes, you only want a value defined once at the moment the object is created. Once created, you don't want anyone changing that value. In order to do this, you create a private variable and have its value set on instantiation.

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdfjfx.html