面向对象编程 FreeCodeCamp

软件开发的核心是解决问题或通过计算获得结果。软件开发过程首先定义一个问题,然后提出一个解决方案。面向对象编程是软件开发过程的几种主要方法之一。
顾名思义,面向对象编程将代码组织成对象定义。这些有时被称为类,它们将数据和相关行为组合在一起。数据是对象的属性,行为(或函数)是方法
对象结构能够在程序中灵活使用,比如对象可以通过调用数据并将数据传递给另一个对象的方法来传递信息。此外,新对象可以从基类(或父类)接收或继承所有功能,这有助于减少重复代码。
对于编程方法的选择取决于几个因素,其中包括问题的类型、如何构造数据以及算法等。本节将介绍 JavaScript 中面向对象的编程原则。

面向对象编程:创建一个基本的 JavaScript 对象

想想我们在生活中每天都可见到的事物:比如汽车、商店以及小鸟等。它们都是物体:即人们可以观察和与之互动的实体事物。

那么这些物体都有哪些特征呢?比如汽车的特征是有轮子,商店是用来出售商品的,而小鸟的特征是有翅膀。

这些特征,或者说是属性定义了一个物体由什么构成的。需要注意的是:那些相似的物体可以拥有相同的属性,但是这些属性可能会有不同的值。举个例子:所有的汽车都有轮子,但并不是所有汽车的轮子个数都是一样的。

JavaScript 中的对象可以用来描述现实世界中的物体,并赋予他们属性和行为,就像它们在现实世界中的对应物一样。下面是使用这些概念来创建一个duck 对象的示例:

let duck = {
   
  name: "Aflac",
  numLegs: 2
};

这个duck 对象有两组键值对:一个是name属性,它的值是 “Aflac”;另一个是numLegs属性,它的值是 2。

Object Oriented Programming: Create a Basic JavaScript Object
Think about things people see every day, like cars, shops, and birds. These are all objects: tangible things people can observe and interact with.

What are some qualities of these objects? A car has wheels. Shops sell items. Birds have wings.

These qualities, or properties, define what makes up an object. Note that similar objects share the same properties, but may have different values for those properties. For example, all cars have wheels, but not all cars have the same number of wheels.

Objects in JavaScript are used to model real-world objects, giving them properties and behavior just like their real-world counterparts. Here’s an example using these concepts to create a duck object:

let duck = {
   
  name: "Aflac",
  numLegs: 2
};

This duck object has two property/value pairs: a name of “Aflac” and a numLegs of 2.

面向对象编程:使用点符号来访问对象的属性

在上一个挑战中,我们创建了一个拥有不同属性的对象,现在我们来看看该如何访问这些属性:

let duck = {
   
  name: "Aflac",
  numLegs: 2
};
console.log(duck.name);

// 这段代码会在控制台中输出 “Aflac”
我们可以用“点号表示法”来访问对象的属性,只需要在对象名称后面加上.以及属性名即可。比如,duck.name就可以访问到 “Aflac”。

Object Oriented Programming: Use Dot Notation to Access the Properties of an Object
The last challenge created an object with various properties. Now you’ll see how to access the values of those properties. Here’s an example:

let duck = {
   
  name: "Aflac",
  numLegs: 2
};
console.log(duck.name);

// This prints “Aflac” to the console
Dot notation is used on the object name, duck, followed by the name of the property, name, to access the value of “Aflac”.

面向对象编程:在对象上创建方法

对象可以有一个叫做方法的特殊属性。

方法其实是一个值为函数的属性,它可以为一个对象添加不同的行为。以下就是一个带有方法属性的duck示例:

let duck = {
   
  name: "Aflac",
  numLegs: 2,
  sayName: function() {
   return "The name of this duck is " + duck.name + ".";}
};
duck.sayName();

// 返回了: “The name of this duck is Aflac.”
这个例子给duck对象添加了一个sayName 方法,这个方法返回一个包含duck名字的句子。

注意:这个方法在返回语句中使用duck.name的方式来获取name的属性值。在下一个挑战中我们将会使用另外一种方法来实现。

Object Oriented Programming: Create a Method on an Object
Objects can have a special type of property, called a method.

Methods are properties that are functions. This adds different behavior to an object. Here is the duck example with a method:

let duck = {
   
  name: "Aflac",
  numLegs: 2,
  sayName: function() {
   return "The name of this duck is " + duck.name + ".";}
};
duck.sayName();

// Returns “The name of this duck is Aflac.”
The example adds the sayName method, which is a function that returns a sentence giving the name of the duck. Notice that the method accessed the name property in the return statement using duck.name. The next challenge will cover another way to do this.

面向对象编程:使用 this 关键字使代码更加可重用

在上一个挑战中我们了解了该如何给duck对象设置一个方法属性。然后我们通过使用“点号表示法”duck.name来获取name的属性值而不需要使用return语句:

sayName: function() {return "The name of this duck is " + duck.name + “.”;}

虽然这是访问对象属性的有效方法,但是这里有一个陷阱。如果变量名发生了改变,那么引用了原始名称的任何代码都需要更新。在一个简短的对象定义中这并不是问题,但是如果对象有很多对其属性的引用,那么发生错误的可能性就更大了。

我们可以使用this关键字这个方法来避免这一问题:

let duck = {
   
  name: "Aflac",
  numLegs: 2,
  sayName: function() {
   return "The name of this duck is " + this.name + ".";}
};

this是一个很复杂的知识点,而上面那个例子也只是使用this的一种方法而已。在当前的上下文环境中,this指向的就是与这个方法有关联的duck对象。

如果把对象的变量名改为mallard,那使用this就没有必要在代码中找到所有指向duck的部分,这样可以使得代码更具有可读性和复用性。

Object Oriented Programming: Make Code More Reusable with the this Keyword
The last challenge introduced a method to the duck object. It used duck.name dot notation to access the value for the name property within the return statement:

sayName: function() {return "The name of this duck is " + duck.name + “.”;}

While this is a valid way to access the object’s property, there is a pitfall here. If the variable name changes, any code referencing the original name would need to be updated as well. In a short object definition, it isn’t a problem, but if an object has many references to its properties there is a greater chance for error.

A way to avoid these issues is with the this keyword:

let duck = {
   
  name: "Aflac",
  numLegs: 2,
  sayName: function() {
   return "The name of this duck is " + this.name + ".";}
};

this is a deep topic, and the above example is only one way to use it. In the current context, this refers to the object that the method is associated with: duck. If the object’s name is changed to mallard, it is not necessary to find all the references to duck in the code. It makes the code reusable and easier to read.

面向对象编程:定义构造函数

构造函数用以创建一个新对象,并给这个新对象定义属性和行为。因此这是创建新对象的一个最基本的方式。

以下就是一个构造函数的示例:

function Bird() {
   
  this.name = "Albert";
  this.color = "blue";
  this.numLegs = 2;
}

这个构造函数定义了一个Bird对象,其属性name、color和numLegs的值分别被设置为Albert、blue和 2。

构造函数遵循一些惯例规则:

  • 构造函数函数名的首字母最好大写,这是为了方便我们区分构造函数和其他非构造函数。
  • 构造函数使用this关键字来给它将创建的这个对象设置新的属性。在构造函数里面,this指向的就是它新创建的这个对象。
  • 构造函数定义了属性和行为就可创建对象,而不是像其他函数一样需要设置返回值。

Object Oriented Programming: Define a Constructor Function
Constructors are functions that create new objects. They define properties and behaviors that will belong to the new object. Think of them as a blueprint for the creation of new objects.

Here is an example of a constructor:

function Bird() {
   
  this.name = "Albert";
  this.color = "blue";
  this.numLegs = 2;
}

This constructor defines a Bird object with properties name, color, and numLegs set to Albert, blue, and 2, respectively. Constructors follow a few conventions:

Constructors are defined with a capitalized name to distinguish them from other functions that are not constructors.
Constructors use the keyword this to set properties of the object they will create. Inside the constructor, this refers to the new object it will create.
Constructors define properties and behaviors instead of returning a value as other functions might.

面向对象编程:使用构造函数创建对象

在上一个挑战中,我们用所学到的知识创建了一个Bird构造函数:

function Bird() {
   
  this.name = "Albert";
  this.color = "blue";
  this.numLegs = 2;
  // 构造函数里面的 "this" 总是指向新创建的实例。
}

let blueBird = new Bird();
注意:通过构造函数创建对象的时候要使用new操作符。因为只有这样,JavaScript 才知道要给Bird这个构造函数创建一个新的实例:blueBird。如果不使用new操作符来新建对象,那么构造函数里面的this就无法指向新创建的这个对象实例,从而产生不可预见的错误。

现在blueBird这个实例就继承了Bird这个构造函数的所有属性,如下:

blueBird.name; // => Albert
blueBird.color; // => blue
blueBird.numLegs; // => 2

由构造函数创建的实例也和其他对象一样,它的属性可以被访问和修改:

blueBird.name = 'Elvira';
blueBird.name; // => Elvira

面向对象编程:扩展构造函数以接收参数

上一个挑战中Bird和Dog构造函数运行得不错。但是,注意到没有:所有通过Bird构造函数创建出来的实例Birds都自动的取名为 Albert,颜色都是蓝色,还都有两条腿。如果你想要新创建出来的小鸟们拥有不同的名字和颜色要怎么办呢?当然,手动的去修改每一个小鸟实例自己的属性也是可以实现的,只是会增加很多无谓的工作量:

let swan = new Bird();
swan.name = "Carlos";
swan.color = "white";

假如你写了一个程序来追踪一个鸟舍里面的几百只甚至几千只不同的小鸟,你将会花费很多时间去创建所有的小鸟实例并给它们的属性一一修改为不同的值。

为了减轻创建不同Bird对象的工作量,你可以给你的Bird设置为可以接收参数的构造函数:

function Bird(name, color) {
   
  this.name = name;
  this.color = color;
  this.numLegs = 2;
}

然后将值通过参数的方式传递给Bird构造函数来定义每一个唯一的小鸟实例:

let cardinal = new Bird("Bruce", "red");

这给Bird的名字和颜色属性分别赋值为 Bruce 和红色提供了另外一种方法。但numLegs属性被默认赋值为 2。

cardinal有以下这些属性:

cardinal.name // => Bruce
cardinal.color // => red
cardinal.numLegs // => 2

这样一来构造函数就变得很灵活了。现在可以直接定义每个Bird实例在创建时的属性,这是 JavaScript 构造函数非常实用的用法之一。它们根据共同或相似的属性和行为将对象归纳为一组,并能够自动的创建各自实例。

练习:
创建另一个Dog构造函数。这一次,给它设置两个参数:name和color,同时给numLegs赋值为 4。然后创建一个新Dog实例保存为变量名:terrier,再将两个字符串通过参数的形式传入name和color属性。

function Dog(name,color) {
   
  this.name = name;
  this.color = color;
  this.numLegs = 4;
}
let terrier = new Dog("ss","red");

面向对象编程:使用 instance of 验证对象的构造函数

凡是通过构造函数创建出的新对象,都叫做这个构造函数的实例。JavaScript 提供了一种很简便的方法来验证这个事实,那就是通过instanceof操作符。instanceof允许你将对象与构造函数之间进行比较,根据对象是否由这个构造函数创建的返回true或者false。以下是一个示例:

let Bird = function(name, color) {
   
  this.name = name;
  this.color = color;
  this.numLegs = 2;
}

let crow = new Bird("Alexis", "black");

crow instanceof Bird; // => true

如果一个对象不是使用构造函数创建的,那么instanceof将会验证这个对象不是构造函数的实例:

let canary = {
   
  name: "Mildred",
  color: "Yellow",
  numLegs: 2
};

canary instanceof Bird; // => false

练习:
给House构造函数创建一个新实例,取名为myHouse并且传递一个数字给bedrooms参数。然后使用instanceof操作符验证这个对象是否为House的实例。

function House(numBedrooms) {
   
  this.numBedrooms = numBedrooms;
}

// 请把你的代码写在这条注释以下
let myHouse = new House(3);
myHouse instanceof House;

Object Oriented Programming: Verify

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值