ES6面向对象
js中的面向对象
function User(name, age) {
this.name = name; // 定义属性
this.age = age;
}
// 通过原型添加方法
User.prototype.showName = function() {
console.log(this.name);
};
let user = new User('rose', 20); // 实例化
user.showName(); // 调用方法
可以看到js的类和构造函数是没什么区别
ES6有了个关键字:Class,来定义类,和java差不多
class User {
constructor(name, age) { // 构造器
this.name = name;
this.age = age;
}
// 定义类方法
showName() {
console.log(this.name);
}
}
let user = new User('rose', 21);
user.showName();
这个用了ES6写法的class 和 上面用构造函数定义的类,输出结果都一样。
ES6的class 有了专门的构造器 constructor,构造器和类分开了,定义方法:不需要原型来定义了,直接再类里面定义方法。
ES6定义类的写法
// 匿名类
let Example1 = class {
constructor(a) {
this.a = a;
console.log(a);
}
}
let ex1 = new Example1(1);
// 命名类
let Example2 = class Example2 {
constructor(a) {
this.a = a;
console.log(a);
}
}
let ex2 = new Example2(2);
// 类声明
class Example {
// class主体内容
constructor(a, b) {
this.a = a;
this.b = b;
}
}
注意点:
1、不可重复声明
2、类定义不会被提升,这意味着,必须在访问前对类进行定义,否则就会报错。类中方法不需要 function 关键字。
3、方法间不能加分号。
4、class 的实例化必须通过 new 关键字。
面向对象的三大特点:封装、继承、多态。ES6有了class可以封装了方法,也有继承。
js的继承
function User(name, age) {
this.name = name;
this.age = age;
}
User.prototype.showName = function() {
console.log(this.name);
}
let user = new User('rose', 21);
//user.showName();
function VipUser(name, age, level) {
User.call(this, name, age); // 通过call调用User类
this.level = level; // vipUser对象的属性
}
VipUser.prototype = new User(); // 通过原型实现继承
VipUser.prototype.constructor = VipUser;
VipUser.prototype.showLevel = function() {
console.log(this.level);
}
let vip = new VipUser('rose', 20 , 10);
vip.showName(); // 使用父类的方法
vip.showLevel(); // 使用自己的方法
ES6的继承:关键字:extends 继承、super 超级
class User {
constructor(name, age) { // 构造函数
this.name = name;
this.age = age;
}
// 定义类方法
showName() {
console.log(this.name);
}
}
class VipUser extends User {
constructor(name, age, level) {
super(name, age); // 父类
this.level = level; // 自己的属性
}
showLevel() {
console.log(this.level);
}
}
let vip = new VipUser('rose', 22, 2); // 实例化vipUser类
vip.showName();
vip.showLevel(); // 调用方法
Class 中的this指向
class User {
constructor(name, age) {
//constructor 里面的this
this.name = name;
this.age = age;
}
showName() {
// 方法里面的this
console.log(this.name);
}
}
let user = new User('rose', 10);
1、constructor 构造器里面的this是指向创建的实例对象
let that;
class User {
constructor(name, age) {
//constructor 里面的this
this.name = name;
this.age = age;
that = this;
console.log(this);
}
showName() {
// 方法里面的this
console.log(this.name);
}
}
// 每次实例化都会调用constructor构造器里面的代码
let user = new User('rose', 10); // User {name: "rose", age: 10}
console.log(that === user); // 构造器的this和实例的对象对比:true
2、方法里面的this
let that;
class User {
constructor(name, age) {
//constructor 里面的this
this.name = name;
this.age = age;
}
showName() {
// 方法里面的this
console.log(this.name);
}
showThis() {
console.log(this); // 方法里面的this
// 一般方法里面的this都是指向 谁 调用这个方法就指向 谁
that = this;
}
}
let user = new User('rose', 10);
user.showThis();
console.log(that === user); // true
<button id='bottom'>点我</button>
<script>
let that;
class User {
constructor(name, age) {
//constructor 里面的this
this.name = name;
this.age = age;
this.btn = document.getElementById('bottom');
this.btn.onclick = this.userAge;
}
showName() {
// 方法里面的this
console.log(this.name);
}
showThis() {
console.log(this); // 方法里面的this
// 一般方法里面的this都是指向 谁 调用这个方法就指向 谁
that = this;
}
userAge() {
// 这个函数里面的this:指向了btn按钮,因为是按钮调用了这个函数,
console.log(this.age);
}
}
let user = new User('rose', 10);
// 点击页面按钮输出 undefined ,因为按钮对象没有定义age属性
</script>
要点击按钮输出我实例的User的age
<button id='bottom'>点我</button>
<script>
let that;
class User {
constructor(name, age) {
//constructor 里面的this
this.name = name;
this.age = age;
this.btn = document.getElementById('bottom');
this.btn.onclick = this.userAge;
that = this;
}
showName() {
// 方法里面的this
console.log(this.name);
}
showThis() {
console.log(this); // 方法里面的this
// 一般方法里面的this都是指向 谁 调用这个方法就指向 谁
}
userAge() {
// that 存储了构造器里面的this
console.log(that.age);
}
}
let user = new User('rose', 10);
// 点击页面按钮输出 10
</script>
通过全局变量that,that === 实例化的对象。