一、es5的类与继承
1. prototype原型对象
每个函数(普通函数、构造函数)都有一个prototype原型对象,每个prototype都有constructor属性,constructor指向函数本身
每个实例都有一个proto,指向构造函数的原型对象
function getSum(a,b){
console.log(a+b)
}
function People(name,age){
this.name = name;
this.age = age;
}
getSum(1,2);
console.log(People.prototype.constructor)// People
console.log(getSum.prototype.constructor)// getSum
2. 静态方法和实例方法
① 在构造函数体中,this指向实例对象,通过this创建的属性属于实例属性
② 在构造函数原型对象上创建方法,方法内部this指向实例对象,属于实例方法
③ 直接挂在构造函数上的属性为静态属性、方法为静态方法,静态方法内的this指向构造函数本身
④ 直接调用构造函数,函数体内this指向调用时所处的作用域,即window
// 声明构造函数People
function People(name,age){
console.log(this);// this指向实例对象
this.name = name; //① 实例属性
this.age = age; //① 实例属性
People.count++;
}
// ② 实例方法,构造函数原型对象上的方法属于实例方法
People.prototype.showName = function(){
console.log('我的名字是',this.name)
}
// ③ 静态属性,构造函数上的属性属于静态属性
People.count = 0;
// ③ 静态方法,构造函数上的方法属于静态方法
People.getCount = function(){
console.log(this);// this指向构造函数本身
console.log(this.count === People.count)//true ,此处等同于People
console.log('目前共有',People.count,'个人')
}
let p1 = new People('xiaoyue1')
console.log(p1);
p1.showName();// 每个实例都能访问到原型对象上的方法和属性
let p2 = new People('xiaoyue2')
console.log(p2);
p2.showName();// 每个实例都能访问到原型对象上的方法和属性
console.log(People.count) //访问静态属性
People.getCount(); //调用静态方法
People('lily',18); // ④ 直接调用构造函数,函数题内部this指向当前作用域window
// 常见静态方法和属性
Math.max(1,2)
Math.PI
console.log(Math)// 查看Math上有哪些静态睡醒和静态方法
// 常见实例方法和属性
let arr = [1,2,3];
console.log(arr.slice(1))// slice为实例方法,slice、push、pop等这些方法都是挂在Array的构造函数上的
3. 类的继承,组合式继承
① 继承父类的属性:通过调用父类函数,call改变函数内this指向。People.call(this,name)
② 继承父类的方法:实例化一个父类的对象赋值给子类的原型对象,让子类实例通过自身的原型对象访问到父类的原型对象的方法。Student.prototype = new People();
③ 原型对象的constructor指回子类。Student.prototype.constructor = Student;
function Student(name,hobby){
People.call(this,name);//① 继承属性:执行People函数,改变this指向为当前Student实例
this.hobby = hobby; //实例自身属性
}
// ②实例化一个People对象peo,peo赋值给Student原型对象,实例对象peo能访问到People原型对象上所有的方法, 因此Student原型对象也能访问到People原型对象上的所有方法。
const peo = new People(); //实例化一个People对象peo
Student.prototype = peo; //赋值给Student原型对象
// Student.prototype = new People(); 或直接这样写
// ③赋值前,Student的prototype的constructor指向Student。
// ③赋值后,实例对象peo本身没有constructor,就会去new出它的构造函数People的原型对象上去找,但People的原型对象的constructor属性是指向People本身的。因此Student.prototype.constructor就会是People,得改回来,让它指回Student,如下。
Student.prototype.constructor = Student; //③
// 除了能访问到People的所有方法,还可以给Student原型对象添加属于自己的方法dance
Student.prototype.dance = function(){
console.log('dance')
}
let s1 = new Student('yoyo','跳舞');
// console.log(Student.count) //undefined,继承不到静态属性和方法
// console.log(Student.getCount()) //报错, 继承不到静态属性和方法
console.log(s1)
s1.showName()
s1.dance()
练习题
console.log(s1.constructor === Student); //true
console.log(s1.constructor === People); //false
console.log(p1.constructor === People); //true
console.log(p1.__proto__ === People.prototype); //true
console.log(s1.__proto__ === Student.prototype); //true
console.log(s1.__proto__.constructor === Student); //true
二、es6的类与继承
1. 类
① class 声明类
② constructor 函数体
③ static 声明静态方法,不能声明静态属性
④ set和get 实例属性声明的另一种方式,可用于属性的读与写时的拦截处理
class People{ //①
constructor(name){ //②函数体
this.name = name; //实例属性
this._sex = 0;
}
showName(){ //实例方法
console.log(this.name)
}
// static count = 0; //会报错,es6还不支持这种static声明静态属性的写法!
static getCount(){ //③静态方法
// console.log(this) //静态方法this指向People,就是调用getCount时的.前面的那个对象
console.log(this.count) //0
console.log(this.count === People.count) //true
}
get sex(){ //④getter获取
if(this._sex === 0){
return 'female'
}else if(this._sex === 1){
return 'male'
}else{
return 'error'
}
}
set sex(val){ //④setter设置,只声明了set没声明get方法,设置时会报错
if(val ===0 || val === 1){
this._sex = val;
}
}
}
People.count = 0; //静态属性,目前只能这声明
let p1 = new People('yoyo');
console.log(p1);
console.log(p1.sex)
p1.sex = 1;
console.log(p1.sex)
2. 继承
extends继承内容:实例属性、实例方法、静态属性、静态方法、get/set属性
class Student extends People{
constructor(name,hobby){
super(name)
this.hobby = hobby
}
study(){
console.log('study')
}
}
let s1 = new Student('yoyo','dance');
console.log(s1)
console.log(s1.sex) //0 继承了get 和set声明的属性
s1.showName(); //继承了实例方法
console.log(Student.count) //0 继承了静态属性
console.log(Student.getCount()) //true 继承了静态方法
网友评论