Skip to content

Commit d9c51c9

Browse files
committed
面向对象
1 parent 824b9a1 commit d9c51c9

4 files changed

Lines changed: 278 additions & 0 deletions

File tree

es5实现类的继承.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
function Animal(){
2+
this.type = "animal";
3+
4+
//实现抽象类
5+
if(new.target === Animal){
6+
throw new Error("animal不可被实例化");
7+
}
8+
}
9+
10+
// let animal = new Animal();//报错
11+
12+
Animal.prototype.say = function(){
13+
console.log("say..");
14+
}
15+
16+
//实现父类与子类的继承
17+
function Tiger(){
18+
Animal.call(this);//继承了父类的实例属性和方法
19+
}
20+
21+
//继承父类原型上的属性和方法
22+
//(1) Tiger.prototype = Animal.prototype;//指向了同一个原型对象,子类原型的修改会影响到父类原型
23+
24+
/*
25+
(2)修改子类的__proto__指向父类的prototype
26+
1)因为Tiger与Animal是两个不同的类,且之间没有new的关系,而且在原型上没有__proto__的指向关系,因此需要手动修改Animal类__proto__指向Animal.prototype
27+
2)低版本浏览器中可能不识别__proto__
28+
*/
29+
30+
//Es5中的方法,利用了原型链,将Tiger的原型的原型指向Animal.prototype
31+
// Tiger.prototype.__proto__ = Animal.prototype;
32+
33+
//ES6中提供的方法
34+
// Object.setPrototypeOf(Tiger.prototype,Animal.prototype);
35+
36+
/*
37+
(1)使用Object.create()改变子类的prototype
38+
(2)这种方式会导致子类指向一个实例对象,而实例对象自身无constructor属性,向上找到父类prototype上的constructor属性,因此需要手动修改子类prototype上constructor的指向
39+
*/
40+
41+
// Tiger.prototype = Object.create(Animal.prototype);
42+
43+
//增加constructor指向的参数
44+
// Tiger.prototype = Object.create(Animal.prototype,{"constructor":{value:Tiger}});
45+
46+
//模拟实现Object.create()
47+
function create(parentPrototype){
48+
let Fn = function(){};
49+
//构建一个中间类指向父类,Tiger自身的prototype的属性和方法都写在中间类Fn的prototype上
50+
Fn.prototype = parentPrototype;
51+
// return new Fn();
52+
53+
//改进:给实例添加一个constructor的属性,修正constructor的指向
54+
let fn = new Fn();
55+
fn.constructor = Tiger;
56+
return fn;
57+
}
58+
59+
Tiger.prototype = create(Animal.prototype);
60+
61+
let tiger = new Tiger;
62+
63+
console.log(tiger.type);//animal
64+
tiger.say();//say..
65+
console.log(tiger.constructor)//[Function:Animal],修正指向前;[Function:Tiger],修正指向后
66+
67+
//类的静态属性
68+
Tiger.a = 10;
69+
console.log(Tiger.a);//10
70+
71+
//类的静态方法
72+
Tiger.eat = function(){
73+
console.log('eat..');
74+
}
75+
Tiger.eat();//eat..

es5实现面向对象继承.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
function Animal(){
2+
//成员属性
3+
this.type = "animal";
4+
//成员方法
5+
this.say = function(){
6+
console.log('say');
7+
}
8+
console.log('c');
9+
};
10+
11+
let animal = new Animal();
12+
13+
//prototype上的方法(公共方法)
14+
//每一个类上都有一个原型->对象
15+
Animal.prototype.cat = function(){
16+
console.log('a');
17+
}
18+
19+
//prototype上的属性(公共属性)
20+
Animal.prototype.num1 = 1;
21+
console.log(animal.type);
22+
console.log(animal.hasOwnProperty('type'));
23+
24+
//每一个对象都有一个__proto__属性,指向父类的prototype
25+
console.log(animal.__proto__ === Animal.prototype);//true
26+
27+
//每个类的prototype都有一个constructor属性,指向该类
28+
console.log(animal.constructor);//[Function:Animal]
29+
console.log(animal.__proto__.constructor === animal.constructor );//true
30+
31+
console.log(animal.__proto__.__proto__.__proto__ === null);//true
32+
console.log(animal.__proto__.__proto__ === Object.prototype);//true
33+
console.log(Animal.prototype.__proto__ === Object.prototype);//true
34+
console.log(Object.prototype.__proto__);//null
35+
36+
animal.cat();//a
37+
animal.say();//say
38+
39+
animal.cat = function(){
40+
console.log('cat..');
41+
}
42+
animal.cat();//cat..
43+
44+
let animal2 = new Animal();
45+
animal2.cat();//a
46+
47+
console.log(animal.num1);//1
48+
49+
Animal();//构造函数作为普通函数调用
50+
51+
/*
52+
53+
1.类
54+
静态属性和静态方法
55+
(1)静态属性和静态方法能够被实例对象继承,但不能被修改
56+
57+
2.原型(prototype)
58+
(1)类中的prototype属性指向自己的原型对象(独立空间)
59+
(2)类的实例对象通过__proto__属性指向类的原型对象,可以通过原型链向上访问原型上的属性和方法,但不能修改原型上的属性和方法
60+
61+
3.实例
62+
成员属性和成员方法
63+
64+
*/

es6中的面向对象.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
class Animal{//es6提供了类,只能new
2+
//实现抽象类
3+
constructor(){
4+
5+
// if(new.target === Animal){
6+
// throw new Error("not new Animal");
7+
// }
8+
9+
//实例上的属性和方法
10+
this._type = "animal";
11+
this.age = 20;
12+
}
13+
14+
//更改实例属性
15+
get type(){
16+
//这里的this指向调用者,即实例对象
17+
return this._type;
18+
}
19+
20+
set type(newType){
21+
this._type = newType;
22+
}
23+
24+
//报错
25+
// get age(){
26+
// return this.age;
27+
// }
28+
29+
//类的原型prototype对象上的方法
30+
eat(){
31+
console.log('eat..');
32+
}
33+
34+
//类的原型prototype对象上的属性
35+
get a(){
36+
return 100;
37+
}
38+
39+
//es6中不支持静态属性
40+
// static a = 10;//报错
41+
42+
//静态属性
43+
static get num(){
44+
return "num";
45+
}
46+
47+
//静态方法
48+
static jump(){
49+
return "jump.."
50+
}
51+
52+
// a = 1;//实例上的属性,es7中的语法,node环境还无法使用
53+
}
54+
55+
let animal = new Animal();
56+
57+
//调用原型上的方法
58+
animal.eat();//eat..
59+
60+
//调用原型上的属性
61+
console.log(animal.a);//100
62+
63+
//调用类的静态属性和静态方法
64+
console.log(Animal.num);//num
65+
console.log(Animal.jump());//jump
66+
67+
//使用get和set修改后的实例属性
68+
animal.type = "dog";
69+
console.log(animal.type);//dog
70+
71+
console.log(animal.age);
72+
73+
// Animal();//直接调用报错
74+
75+
//实现class只能new的类似功能
76+
function Person(){
77+
78+
if(!(this instanceof Person)){
79+
throw new Error("not new");
80+
}
81+
82+
};
83+
// Person();//报错

es6中类的继承.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
class Animal{//es6提供了类,只能new
2+
//实现抽象类
3+
constructor(){
4+
5+
// if(new.target === Animal){
6+
// throw new Error("not new Animal");
7+
// }
8+
9+
//实例上的属性和方法
10+
this._type = "animal";
11+
this.age = 20;
12+
}
13+
14+
//类的原型prototype对象上的方法
15+
eat(){
16+
console.log('eat..');
17+
}
18+
19+
//静态属性
20+
static get num(){
21+
return "num";
22+
}
23+
24+
}
25+
26+
/*
27+
(1)父类静态属性和静态方法的继承
28+
Tiger.__proto__ = Animal;//改变Tiger的__proto__指向,修改其父类的原型指向,实现静态属性和静态方法的继承
29+
(2)父类原型上的属性和实例方法的继承
30+
Tiger.prototype = Object.create(Animal.prototype);
31+
(3)父类实例属性和实例方法的继承
32+
Animal.call(this);
33+
*/
34+
class Tiger extends Animal{
35+
constructor(){//使用this之前必须调用super
36+
//实例属性和实例方法
37+
super();//Animal.call(this)
38+
};
39+
40+
static parentNum(){
41+
return super.num;//super指向父类自身
42+
};
43+
44+
eat(){
45+
super.eat();//super指向父类的原型
46+
}
47+
}
48+
49+
let tiger = new Tiger('tiger1');
50+
51+
//调用实例属性
52+
console.log(tiger.age);//20
53+
//调用原型方法
54+
tiger.eat();//eat..
55+
//调用静态方法
56+
console.log(Tiger.parentNum());//num

0 commit comments

Comments
 (0)