笔记一个包含:认识面向对象、构造函数的封装、继承、多态、ECMA6中新代替语法class
下:包括构造函数的继承、多态、ECMA6中新代替语法class
构造函数的继承
从父一级延续下来的属性和功能(方法)叫做继承
(既得到另一个对象的属性和方法)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <script> 7 function Person(name, sex){ 8 this.name = name; 9 this.sex = sex; 10 } 11 Person.prototype.showName = function(){ 12 alert(this.name); 13 } 14 Person.prototype.showSex = function(){ 15 alert(this.sex); 16 } 17 /* 18 继承:从父一级延续下来的属性和功能叫做继承。 19 20 */ 21 /* 22 创建白领(演示用的,有个体面的工作)构造函数 23 */ 24 //Worker要继承Person的属性和方法 25 function Worker(name, sex, job){ 26 //继承父一级所有的属性 27 //1、构造函数的伪装 28 Person.call(this, name, sex); 29 this.job = job; 30 } 31 32 33 //继承方法 34 Worker.prototype = Person.prototype;//方法不可行,会对父一级造成印象(引用数据类型) 35 36 Worker.prototype.showJob = function(){ 37 alert('我的工作是' + this.job); 38 } 39 40 var xiaoming = new Worker("小明", "男", "程序员"); 41 xiaoming.showName(); 42 xiaoming.showSex(); 43 xiaoming.showJob(); 44 45 var p1 = new Person('blue', '男'); 46 alert(p1.showJob); 47 </script> 48 </head> 49 <body> 50 51 </body> 52 </html>
继承对象方法的时候不能
Worker.prototype = Person.prototype; 直接赋值的方式,因为对象时引用数据类型,这样相当于存的地址,修改其中一个时都会发生改变。
来看一下小例子
1 <script> 2 var obj = { 3 name: "小明", 4 age: 18, 5 sex: "男" 6 } 7 var obj2 = {}; 8 /*var obj2 = obj; //直接通过赋值的方式,后期更改obj2,obj也会受影响 9 obj2.xxx = "yyy"; 10 console.log(obj);//Object { name: "小明", age: 18, sex: "男", xxx: "yyy" } 11 console.log(obj2);//Object { name: "小明", age: 18, sex: "男", xxx: "yyy" }*/ 12 13 /*-----通过for...in遍历不受影响-------------*/ 14 15 for(var key in obj){//通过for ... in.. 遍历的方式不会受影响 16 obj2[key] = obj[key]; 17 } 18 19 obj2.xxx = "yyy"; 20 21 console.log(obj);//Object { name: "小明", age: 18, sex: "男" } 22 console.log(obj2);//Object { name: "小明", age: 18, sex: "男", xxx: "yyy" } 23 //obj 24 </script>
所以我们可以用for...in 的方式继承 父一级属性。
构造函数继承的标准语法:
继承父一级所有的属性,叫做构造函数的伪装。
继承父一级所以的方法,叫做原型链。
1 <script> 2 function Person(name, sex){ 3 this.name = name; 4 this.sex = sex; 5 } 6 Person.prototype.showName = function(){ 7 alert(this.name); 8 } 9 Person.prototype.showSex = function(){ 10 alert(this.sex); 11 } 12 /* 13 继承:从父一级延续下来的属性和功能叫做继承。 14 */ 15 /* 16 创建白领构造函数 17 */ 18 19 function Worker(name, sex, job){ 20 //继承父一级所有的属性 21 //1、构造函数的伪装 22 Person.call(this, name, sex); 23 this.job = job; 24 } 25 26 27 //继承方法 28 //2、原型链 29 for(var funcName in Person.prototype){ 30 Worker.prototype[funcName] = Person.prototype[funcName]; 31 } 32 33 Worker.prototype.showJob = function(){ 34 alert('我的工作是' + this.job); 35 } 36 37 var xiaoming = new Worker("小明", "男", "程序员"); 38 xiaoming.showName();//小明 39 xiaoming.showSex();//男 40 xiaoming.showJob();//我的工作是程序员 41 42 var p1 = new Person('blue', '男'); 43 alert(p1.showJob);//undefied 说明没有影响父一级,父一级并没用showJob这个方法 44 </script>
再来看一下构造函数的多态。
(在继承完父一级的方法和属性后,添加一些自己的属性和方法,包括重写父一级的方法)
子一级可以继承父一级所有的属性和方法,这个部分叫做【继承】。
子一级再根据自己的功能拓展属性和方法,或者重写父一级继承的函数,这叫做【多态】。
面向对象的程序:特点
继承、封装、多态
1 <script> 2 3 /* 4 子一级可以继承父一级所有的属性和方法,这个部分叫做【继承】。 5 子一级再根据自己的功能拓展属性和方法,或者重写父一级继承的函数,这叫做【多态】。 6 7 8 面向对象的程序:特点 9 继承、封装、多态 10 11 */ 12 function Father(name, sex){ 13 this.name = name; 14 this.sex = sex; 15 } 16 17 Father.prototype.showName = function(){ 18 alert(this.name); 19 } 20 Father.prototype.showSex = function(){ 21 alert(this.sex); 22 } 23 //父一级的sing方法,一会要被自已继承后重写,既构造函数的多态 24 Father.prototype.sing = function(){ 25 alert("县级青歌会的冠军"); 26 } 27 28 29 function Son(name, sex, height){ 30 //1、构造函数的伪装 31 Father.call(this, name, sex); 32 this.height = height; 33 } 34 /* 35 2、原型链 36 */ 37 for(var funcName in Father.prototype){ 38 Son.prototype[funcName] = Father.prototype[funcName]; 39 } 40 //继承完父一级的方法后,重写父一级的sing方法 41 Son.prototype.sing = function(){ 42 alert('喜欢嘻哈,拿了一个全国五强'); 43 } 44 45 var laoming = new Father("老明", "男", 170); 46 laoming.sing();// 47 48 var xiaoming = new Son("小明", "男", 180); 49 xiaoming.sing(); 50 </script>
上面的构造函数,在别的语言中都称为类class,所以在ECMA6中又把这个概念加回来了,请看ECMA6中写构造函数的语法。
ECMA6 class语法
1 <script> 2 /*------------传统构造函数---------------------*/ 3 /*function Iphone(color, size){ 4 this.color = color; 5 this.size = size; 6 } 7 Iphone.prototype.show = function(){ 8 alert(`您选择了${this.color}颜色的,硬盘大小为${this.size}G的手机,已出货`); 9 } 10 11 var iphoneXMax = new Iphone("土豪金", 512); 12 iphoneXMax.show();*/ 13 14 15 /* 16 ECMA6的语法 17 */ 18 class Iphone{ 19 //属性 20 constructor(color, size){ 21 this.color = color; 22 this.size = size; 23 } 24 //方法 25 show(){ 26 alert(`您选择了${this.color}颜色的,硬盘大小为${this.size}G的手机,已出货`); 27 } 28 } 29 30 var iphoneXMax = new Iphone("黑色", 126); 31 iphoneXMax.show(); 32 33 </script>
我们再来看一下class语法的继承。
ECMA6 class语法 继承
1 <script> 2 3 /*---------传统构造函数------------------*/ 4 5 /*function Iphone(color, size){ 6 this.color = color; 7 this.size = size; 8 } 9 Iphone.prototype.show = function(){ 10 alert(`您选择了${this.color}颜色的,硬盘大小为${this.size}G的手机,已出货`); 11 } 12 13 14 //继承 15 //1、构造函数的伪装,继承函数 16 function IphoneXs(color, size, screen){ 17 Iphone.call(this, color, size); 18 this.screen = screen; 19 } 20 21 //2、继承函数,原型链 22 23 for(var funcName in Iphone.prototype){ 24 IphoneXs.prototype[funcName] = Iphone.prototype[funcName]; 25 } 26 27 IphoneXs.prototype.selectScreen = function(){ 28 alert(`你选择的是${this.screen}屏幕的手机`); 29 } 30 31 var iphoneXs1 = new IphoneXs("土豪金", 512, 6.4); 32 iphoneXs1.show(); 33 iphoneXs1.selectScreen();*/ 34 35 36 /*-------------------上下做对比--------------------*/ 37 /* 38 ECMA6的语法 39 */ 40 class Iphone{ 41 //属性 42 constructor(color, size){ 43 this.color = color; 44 this.size = size; 45 } 46 //方法 47 show(){ 48 alert(`您选择了${this.color}颜色的,硬盘大小为${this.size}G的手机,已出货`); 49 } 50 } 51 52 class IphoneXs extends Iphone{ 53 constructor(color, size, screen){ 54 //先去继承父一级的属性 55 super(color, size); //调用父级的constructor函数,继承父级的属性 56 this.screen = screen; 57 } 58 selectScreen(){ 59 alert(`你选择的是${this.screen}屏幕的手机`); 60 } 61 } 62 63 var iphoneXs1 = new IphoneXs("土豪金", 512, 6.4); 64 iphoneXs1.show(); 65 iphoneXs1.selectScreen(); 66 </script>