JavaScript面向对象
# JavaScript面向对象
# 1. JS对象定义
# 1.1 对象的定义
在 JavaScript 中,对象是王。如果您理解了对象,就理解了 JavaScript。
在 JavaScript 中,几乎“所有事物”都是对象。
- 布尔是对象(如果用 new 关键词定义)
- 数字是对象(如果用 new 关键词定义)
- 字符串是对象(如果用 new 关键词定义)
- 日期永远都是对象
- 算术永远都是对象
- 正则表达式永远都是对象
- 数组永远都是对象
- 函数永远都是对象
- 对象永远都是对象
所有 JavaScript 值,除了原始值,都是对象。
对比Java的面向对象
在Java的面向对象中,把构成问题的事物分解成一个个对象
,其中类是面向对象中的一个很重要的概念,因为类是很多个具有相同属性和行为特征的对象所抽象出来的,对象是类的一个实例。
类具有三个特性:封装、继承和多态。
封装
:核心思想就是“隐藏细节”、“数据安全”,将对象不需要让外界访问的成员变量和方法私有化,只提供符合开发者意愿的公有方法来访问这些数据和逻辑,保证了数据的安全和程序的稳定。继承
:子类可以继承父类的属性和方法,并对其进行拓展。多态
:同一种类型的对象执行同一个方法时可以表现出不同的行为特征。通过继承的上下转型、接口的回调以
# 1.2 JavaScript 原始值
原始值指的是没有属性或方法的值。
原始数据类型指的是拥有原始值的数据。
JavaScript 定义了 5 种原始数据类型:
string
number
boolean
null
undefined
# 1.3 创建JavaScript对象
通过 JavaScript,您能够定义和创建自己的对象。
有不同的方法来创建对象:
- 定义和创建单个对象,使用对象文字。
- 定义和创建单个对象,通过关键词 new。
- 定义对象构造器,然后创建构造类型的对象。
var Person = {
name : "Bobo",
age : 20,
add : "北京",
info : function (){
return "name=" + this.name + ",age=" + this.age + ",add=" + this.add;
}
};
// 这不会创建 person 的副本。
var bobo = Person;
console.log(bobo.info());
// 直接使用花括号 {}
var Person = {name:"Bobo",age:20,add:"北京",info:function(){return "name=" + this.name + ",age=" + this.age + ",add=" + this.add;}};
# 1.4 New关键词和易变性
new的关键词使用,出于简易性、可读性和执行速度的考虑不建议使用这种方式
var person = new Object();
person.firstName = "Bill";
person.lastName = "Gates";
person.age = 50;
person.eyeColor = "blue";
易变性
对象是易变的:它们通过引用来寻址,而非值。
如果 person 是一个对象,下面的语句不会创建 person 的副本:
var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"}
var x = person;
x.age = 10; // 这将同时改变 both x.age 和 person.age
# 2. JS对象的属性
# 2.1 访问属性
属性指的是与 JavaScript 对象相关的值。
JavaScript 对象是无序属性的集合。
属性通常可以被修改、添加和删除
,但是某些属性是只读的。
1.访问对象属性的语法是:
objectName.property // person.age
2.其他方式访问
objectName["property"] // person["age"]
objectName[expression] // x = "age"; person[x]
# 2.2 遍历循环
JavaScript for...in
语句遍历对象的属性。
for (variable in object) {
要执行的代码
}
for...in
循环中的代码块会为每个属性执行一次。
var Person = {
name : "Bobo",
age : 20,
add : "北京",
info : function (){
return "name=" + this.name + ",age=" + this.age + ",add=" + this.add;
}
}
var bobo = Person;
for (var boboKey in bobo) {
console.log(bobo[boboKey])
}
# 2.3 增删属性
您可以通过简单的赋值,向已存在的对象添加新属性。删除是有delete
关键字
假设 person 对象已存在 - 那么您可以为其添加新属性:
// 增加属性
person.nationality = "English";
// 删除属性
var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"};
delete person.age; // 或 delete person["age"];
# 2.4 对象的方法
this 关键词
在 JavaScript 中,被称为 this
的事物,指的是拥有该 JavaScript 代码的对象。
this
的值,在函数中使用时,是“拥有”该函数的对象。
请注意 this
并非变量。它是关键词。您无法改变 this
的值。
语法:
// 对象方法
methodName : function() { 代码行 }
// 调用方法
objectName.methodName()
创建一个对象赋值方法和获取属性的方法
// 创建一个新的猫对象
var Cat = {
name : "",
age : null,
color: "",
// 这是全部变量赋值方法
fullName : function (name,age,color){
this.name= name;
this.age = age;
this.color = color;
},
// 这是获取所有属性方法
getAll : function (){
return "name=" + this.name + ",age=" + this.age + ",color=" + this.color;
}
}
var cat = Cat;
cat.fullName("小白",1,"黄色");
console.log(cat.getAll())
# 2.5 对象的显示
显示 JavaScript 对象的一些常见解决方案是:
- 按名称显示对象属性
- 循环显示对象属性
- 使用
Object.values()
显示对象 - 使用
JSON.stringify()
显示对象
1.Object.values()
使用
const person = {
name: "Bill",
age: 19,
city: "Seattle"
};
const myArray = Object.values(person);
console.log(myArray);
2.JSON.stringify()
使用
任何 JavaScript 对象都可以使用 JavaScript 函数 JSON.stringify()
进行字符串化(转换为字符串):
const person = {
name: "Bill",
age: 19,
city: "Seattle"
};
let myString = JSON.stringify(person);
console.log(myString);
# 3. JS的访问器和构造器
# 3.1 访问器
JavaScript 访问器(Getter 和 Setter)
ECMAScript 5 (2009) 引入了 Getter 和 Setter。
Getter 和 Setter 允许您定义对象访问器(被计算的属性)。
与众多语言一样,Java有其对应的JavaBean,也有相同的Get和Set方法,目的就是保护数据的传参,保护权限。JavaScript的将Get和Set可以用来设置访问的权限。
# 3.2 Set和Get关键词
使用 getter 和 setter 时,JavaScript 可以确保更好的数据质量。
在本例中,使用 getName
属性以大写形式返回 name
属性的值:
var Person = {
name : "Tom",
age : 20,
city : "China",
set setName(name){
this.name = name;
},
set setAge(age){
this.age = age;
},
set setCity(city){
this.city = city;
},
get getName(){
return this.name;
}
};
为什么使用 Getter 和 Setter?
- 它提供了更简洁的语法
- 它允许属性和方法的语法相同
- 它可以确保更好的数据质量
- 有利于后台工作
# 3.3 构造器
有时我们需要创建相同“类型”的许多对象的“蓝图”。
创建一种“对象类型”的方法,是使用对象构造器函数。
在上面的例子中,函数 Person() 就是对象构造器函数。
通过 *new* 关键词调用构造器函数
可以创建相同类型的对象:
function Person(first, last, age, eye) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eye;
}
var person1 = new Person2("lisi","Z",20,"blue");
var person2 = new Person2("zhangsan","Z",20,"blue");
console.log(person1);
console.log(person2);
# 4. JS的对象原型
所有 JavaScript 对象都从原型继承属性和方法。
# 4.1原型继承
所有 JavaScript 对象都从原型继承属性和方法。
日期对象继承自 Date.prototype
。数组对象继承自Array.prototype
。Person 对象继承自Person.prototype
。
Object.prototype
位于原型继承链的顶端:
日期对象、数组对象和 Person 对象都继承自Object.prototype
。
向对象添加属性和方法
有时,您希望向所有给定类型的已有对象添加新属性(或方法)。
有时,您希望向对象构造器添加新属性(或方法)。
1.使用 prototype
属性
JavaScript prototype 属性也允许您为对象构造器添加新方法:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
Person.prototype.name = function() {
return this.firstName + " " + this.lastName;
};
# 5.JS的类
ECMAScript 2015,也称为 ES6,引入了 JavaScript 类。
JavaScript 类是 JavaScript 对象的模板。
# 5.1 JavaScript类的语法
请使用关键字 class
创建一个类。这点和Python比较相似。
请始终添加一个名为 constructor()
的方法:
语法:
class ClassName {
constructor() { ... }
}
class Car {
constructor(name, year) {
this.name = name;
this.year = year;
}
}
- 上面的例子创建了一个名为 "Car" 的类。
- 该类有两个初始属性:"name" 和 "year"。
- JavaScript 类不是对象。
- 它是 JavaScript 对象的模板。
使用类
当您有了一个类时,可以使用该类来创建对象:
let myCar1 = new Car("Ford", 2014);
let myCar2 = new Car("Audi", 2019);
# 5.2 构造方法
构造方法是一种特殊的方法:
- 它必须有确切的名称的
“constructor”
- 创建新对象时自动执行
- 用于初始化对象属性
- 如果您没有定义构造方法,JavaScript 会添加一个空的构造方法。
# 5.3 类方法
- 创建类方法的语法与对象方法相同。
- 请使用关键字 class 创建一个类。
- 请始终添加
constructor()
方法。 - 然后添加任意数量的方法。
class ClassName {
constructor() { ... }
method_1() { ... }
method_2() { ... }
method_3() { ... }
}
# 5.4 示例
计算买车的时间已经多少年了
class Car {
constructor(name, year) {
this.name = name;
this.year = year;
}
age() {
let date = new Date();
return date.getFullYear() - this.year;
}
}
let myCar = new Car("Ford", 2014);
document.getElementById("demo").innerHTML =
"My car is " + myCar.age() + " years old.";
# 5.5 类的继承
如需创建类继承,请使用 extends
关键字。
使用类继承创建的类继承了另一个类的所有方法:
创建一个名为 "Model" 的类,它将继承 "Car" 类的方法:
class Car {
constructor(brand) {
this.carname = brand;
}
present() {
return 'I have a ' + this.carname;
}
}
class Model extends Car {
constructor(brand, mod) {
super(brand);
this.model = mod;
}
show() {
return this.present() + ', it is a ' + this.model;
}
}
let myCar = new Model("Ford", "Mustang");
document.getElementById("demo").innerHTML = myCar.show();
super()
方法引用父类。
通过在 constructor 方法中调用 super()
方法,我们调用了父级的 constructor 方法,获得了父级的属性和方法的访问权限。
继承对于代码可重用性很有用:在创建新类时重用现有类的属性和方法。
# 5.6 Getter和Setter
类还允许您使用 getter 和 setter。
为您的属性使用 getter 和 setter 很聪明,特别是如果您想在返回它们之前或在设置它们之前对值做一些特殊的事情。
如需在类中添加 getter 和 setter,请使用 get
和 set
关键字。
为 "carname"
属性创建 getter 和 setter:
class Car {
constructor(brand) {
this.carname = brand;
}
get cnam() {
return this.carname;
}
set cnam(x) {
this.carname = x;
}
}
let myCar = new Car("Ford");
document.getElementById("demo").innerHTML = myCar.cnam;