一.es5
//1.把属性和方法都放在构造函数中(不建议使用,每次创建实例都会创建公共的方法)
function Person(name){
this.name = name;
this.getName = function(){
return this.name;
}
this.setName = function(name){
this.name = name;
}
this.action = function(){
console.log('我是'+this.name)
}
}
Person.info = function(){
//静态方法,实例化对象不能调用,只能通过 Person.info()来调用
console.log('info')
}
Person.age = '20';//静态属性
let teacher = new Person('张三');
console.log(teacher)
console.log(teacher.getName())//张三
teacher.action()//我是张三
teacher.setName('李四');
console.log(teacher)
//2.公共的属性和方法放在原型上
function Person(name) {
this.name = name;
}
Person.prototype.getName = function (name) {
return this.name;
}
Person.prototype.setName = function (name) {
this.name = name;
}
Person.prototype.action = function (name) {
console.log('我是' + this.name)
}
Person.info = function(){
//静态方法,实例化对象不能调用,只能通过 Person.info()来调用
console.log('info')
}
Person.age = '20';//静态属性
let teacher = new Person('张三');
console.log(teacher)
console.log(teacher.getName())//张三
teacher.action()//我是张三
teacher.setName('李四');
console.log(teacher)
//3.继承
//3.1 对象冒充继承,只能继承构造函数中的属性和方法,不能继承原型链上的属性和方法
function Person(name) {
this.name = name;
}
Person.prototype.getName = function (name) {
return this.name;
}
Person.prototype.setName = function (name) {
this.name = name;
}
Person.prototype.action = function (name) {
console.log('我是' + this.name)
}
Person.info = function(){
//静态方法,实例化对象不能调用,只能通过 Person.info()来调用
console.log('info')
}
Person.age = '20';//静态属性
function Teacher(name){
Person.call(this,name)
}
let teacher = new Teacher('王五');
console.log(teacher)
console.log(teacher.getName())// Uncaught TypeError: teacher.getName is not a function
//3.2原型链继承,能继承父类原型链的属性和方法,不能给父类的构造函数传参
function Person() {
this.name = '王五';
}
Person.prototype.getName = function (name) {
return this.name;
}
Person.prototype.setName = function (name) {
this.name = name;
}
Person.prototype.action = function (name) {
console.log('我是' + this.name)
}
Person.info = function(){
//静态方法,实例化对象不能调用,只能通过 Person.info()来调用
console.log('info')
}
Person.age = '20';//静态属性,只能通过 Person.age来使用
function Teacher(){
}
Teacher.prototype = new Person();
let teacher = new Teacher();
console.log(teacher)
console.log(teacher.getName())
//3.3 组合继承:原型链继承+对象冒充继承
function Parent(name) {
this.name = name; // 实例基本属性 (该属性,强调私有,不共享)
this.arr = [1]; // (该属性,强调私有)
}
Parent.prototype.say = function() { // --- 将需要复用、共享的方法定义在父类原型上
console.log('hello')
}
function Child(name,like) {
Parent.call(this,name,like) // 核心
this.like = like;
}
Child.prototype = Object.create(Parent.prototype) // 核心 通过创建中间对象,子类原型和父类原型,就会隔离开。不是同一个啦,有效避免了方式4的缺点。
<!--这里是修复构造函数指向的代码-->
Child.prototype.constructor = Child
let boy1 = new Child('小红','apple')
let boy2 = new Child('小明','orange')
let p1 = new Parent('小爸爸')
注意:这种方法也要修复构造函数的
修复代码:Child.prototype.constructor = Child
修复之后:console.log(boy1.constructor); // Child
console.log(p1.constructor);// Parent 完美
二.es6
//1。创建类和实例化对象,还不支持私有方法和属性
class Person{
static age = '20';//静态属性
constructor(name) {
this.name = name;
}
getName(){
return this.name;
}
static action(){
//静态属性
console.log(`我是${this.name}`)//此处的name 是Person类的name属性,不是实例的属性
}
}
let person = new Person('张三');
console.log(person);
console.log(person.getName());//张三
console.log(Person.age);//20
Person.action();//我是Person
//2。继承
class Teacher extends Person{
constructor(name,age){
super(name)//super关键字调用了父类的构造函数
this.age = age;
}
getAge(){
return this.age;
}
}
let teacher = new Teacher('李四',23);
console.log(teacher);
console.log(teacher.getName());
console.log(teacher.getAge());
三.typescript
//1.类的创建及实例化
class Person{
name:string;//实例化对象属性,默认是public修饰,必须声明才能在构造函数中赋值
static name1:string = '李四';//静态属性,只能通过Person.name来访问
protected name2:string = '王五';//受保护的属性,只能在本类和子类中使用,不能在实例化对象上访问
private name3:string = '赵六';//私有属性,只能在本类中使用,不能在实例化对象上访问
constructor(na:string){
this.name = na;
}
getName(){
//实例化对象方法
return this.name;
}
static getName1(){
//静态方法,只能通过Person.getName1()来访问
return this.name1;
}
protected getName2(){
//受保护方法,只能在本类及子类中通过this.getName1()来访问
return this.name2;
}
private getName3(){
//静态方法,只能在本类中通过Person.getName1()来访问
return this.name3;
}
}
let person = new Person('张三');
console.log(person);
console.log(person.getName());
//2.继承
class Teacher extends Person{
public age:number;
constructor(na:string,ag:number){
super(na)//继承了父类的属性和方法
this.age = ag;
}
getAge(){
return this.age;
}
}
let teacher = new Teacher('呼保义',20);
console.log(teacher)
console.log(teacher.getName())
console.log(teacher.getAge())
//3.封装:通过公有方法来访问私有属性,get和set实例化对象
class Woker{
private name:any;
constructor(na:any){
this.name = na;
}
getName(){
return this.name
}
setName(name:any){
this.name = name
}
}
console.log('--------------')
let worker = new Woker('玉麒麟');
console.log(worker.getName())
worker.setName('霹雳火')
console.log(worker)