两种编程思想
面向对象 | 面向过程 |
---|---|
创建对象,对象的属性和方法 | 面向步骤 |
低耦合,性能降低 | 性能高,耦合高 |
多人合作编程 | 简单编程 |
举例:
把大象放进冰箱
面向过程:1.打开冰箱门2.把大象放进去3.关上冰箱门
面向对象:1.创建对象:冰箱和大象
2.冰箱的方法:打开和关闭;大象的方法:放进去
对象和类(ES6)
类是对象的公共部分的抽象,对象是类的实例化。
比如:水果是一个类,苹果、香蕉、橘子是类的实例化对象
对象
对象具有属性和方法
对象的3大属性:封装,继承,多态
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>创建对象和类</title>
</head>
<body>
<script>
class Person {
constructor (uname,age,sex) {
this.name = uname;
this.age = age;
this.sex = sex; //构造函数中的this指向实例化对象
}
eat (food) {
console.log(this.name + food);
} //类中的函数不用加function,函数之间用逗号隔开
drink (drinks) {
console.log(this.name + drinks);
}
}
var gd = new Person('gd',31,'boy');
gd.eat('meat'); //记得加引号
gd.drink('beer');
var sr = new Person('sr',28,'boy');
sr.eat('sateberry');
sr.drink('cola');
</script>
</body>
</html>
继承extends和super
extends:继承父类的属性和方法
super:调用父类中的函数,包括普通函数和构造函数。在扩展子类的方法并继承父类的方法时,要把父亲的构造函数super()放在子类的构造函数之前。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>类的继承</title>
</head>
<body>
<script>
class Father {
constructor (x,y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
class Son extends Father {
constructor (x,y) {
super(x,y); //这里有一个疑惑为什么不直接删除Son的构造函数
// this.x = x;
// this.y = y;
}
}
var son = new Son(1,2);
son.sum();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>类的继承super调用父类构造函数时的位置</title>
</head>
<body>
<script>
class Father {
constructor (x,y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
class Son extends Father {
constructor (x,y) {
super(x,y); //父类的构造函数调用必须放在子类的构造函数之前
this.x = x;
this.y = y;
}
substract(){
console.log(this.x - this.y);
}
}
var son = new Son(1,2);
son.sum(); //3
son.substract(); //-1
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>类的继承super调用父类的普通函数</title>
</head>
<body>
<script>
class Father {
say() {
return '爸爸';
}
}
class Son extends Father {
say() {
console.log(super.say() + '的儿子');
//super.say()调用父类的普通函数say()
}
}
var son = new Son();
son.say(); //爸爸的儿子
</script>
</body>
</html>
ES6中类和对象的三个注意点
1.类没有变量提升,所以需要先创建类再实例化对象。
2.所有的共有属性和方法都需要加this。
3.this的指向:constructor 里面的this 指向的是 创建的实例对象
方法中的this指向调用该方法的对象。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>共有属性和方法都需要加this</title>
</head>
<body>
<script>
class Star {
constructor(uname, age) {
this.uname = uname;
this.age = age;
}
sing() {
console.log(thisuname);
//console.log(uname)会报错,因为sing函数中没有uname,他需要调用constructor中的uname,所以必须使用this
}
var ldh = new Star('刘德华');
ldh.sing();
//第二种调用后立即执行sing
class Star{
constructor(uname, age) {
this.uname = uname;
this.age = age;
this.sing();
}
sing() {
console.log(this.uname);
}
}
var ldh = new Star('刘德华');
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>this的指向</title>
</head>
<body>
<button>点击</button>
<script>
var that;
var _that;
class Star {
constructor(uname, age) {
// constructor 里面的this 指向的是 创建的实例对象
that = this;
console.log(this);
this.uname = uname;
this.age = age;
// this.sing();
this.btn = document.querySelector('button');
this.btn.onclick = this.sing;
}
sing() {
// 这个sing方法里面的this 指向的是 btn 这个按钮,因为这个按钮调用了这个函数
console.log(this);
console.log(that.uname); // that里面存储的是constructor里面的this
}
dance() {
// 这个dance里面的this 指向的是实例对象 ldh 因为ldh 调用了这个函数
_that = this;
console.log(this);
}
}
var ldh = new Star('刘德华');
console.log(that === ldh);
ldh.dance();
console.log(_that === ldh);
// 1. 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象
// 2. 类里面的共有的属性和方法一定要加this使用.
</script>
</body>
</html>