JS面向对象高级
对象创建模式 Object构造函数模式
方法:先创建空的Object对象,再动态添加属性方法
适用:起始时候不确定对象内部数据
缺点:语句太多
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 var p = new Object ()p = {} p.name = '小明' p.age = 18 p.setName = function (name ) { this .name = name } p.setName ('小红' ) console .log (p)console .log (p.name )console .log (p.age )
对象字面量模式
方法:使用{}创建对象,同时指定方法属性
适用:起始时候对象内部数据是确定的
缺点:如果创建多个对象,有重复代码
1 2 3 4 5 6 7 8 9 10 11 12 var p = { name : '小明' , age : 18 , setName : function (name ) { this .name = name } } console .log (p.name ,p.age )p.setName ('小红' ) console .log (p.name ,p.age )
工厂模式
方法:通过工厂函数动态创建对象并且返回
适用:需要创建多个对象
缺点:对象没有一个具体的类型,都是Object类型
1 2 3 4 5 6 7 8 9 10 11 12 function createPerson (name, age ) { var p = { name : name, age : age, setName : function (name ) { this .name = name } } return p } var p1 = createPerson ('小明' , 18 )var p2 = createPerson ('小红' , 20 )
自定义函数构造
方法: 自定义构造函数, 通过new创建对象
适用: 需要创建多个类型确定的对象,与上方工厂模式有所对比
缺点: 每个对象都有相同的数据, 浪费内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function Person (name, age ) { this .name = name this .age = age this .setName = function (name ) { this .name = name } } var p1 = new Person ('Tom' , 12 )p1.setName ('Jack' ) console .log (p1.name , p1.age )console .log (p1 instanceof Person )function Student (name, price) { this .name = name this .price = price } var s = new Student ('Bob' , 13000 )console .log (s instanceof Student )var p2 = new Person ('JACK' , 23 )console .log (p1, p2)
构造函数+原型的组合模式
方法: 自定义构造函数, 属性在函数中初始化, 方法添加到原型上
适用: 需要创建多个类型确定的对象
放在原型上可以节省空间(只需要加载一遍方法)
1 2 3 4 5 6 7 8 9 10 11 12 function Person (name, age ) { this .name = name this .age = age } Person .prototype .setName = function (name ) { this .name = name } var p1 = new Person ('Tom' , 23 )var p2 = new Person ('Jack' , 24 )console .log (p1, p2)
继承模式 原型链继承 方法:
定义父函数构造函数
给父类型的原型添加方法
定义子类型的构造函数
创建父类型的实例对象赋值给子类型的原型(通过访问父类型的实例对象找到父类型原型中的函数)
创建子类型的对象:可以通过访问[子类型的原型]->[父类型的实例]->[父类型的原型]调用父类型的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function Father ( ){ this .fatherProp = '父类属性' } Father .prototype .fatherMethod = function ( ){ console .log ('父类方法' ) } function Child ( ){ this .childProp = '子类属性' } Child .prototype = new Father ()Child .prototype .constructor = Child Child .prototype .childMethod = function ( ){ console .log ('子类方法' ) } var child = new Child ()child.fatherMethod ()
借用构造函数继承(假的)
方法:
定义父类型构造函数
定义子类型构造函数
在子类型构造函数中调用父类型构造
关键:
在子类型构造函数中通用call()调用父类型构造函数
作用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function Person (name, age ) { this .name = name this .age = age } function Student (name, age, price ) { Person .call (this , name, age) this .price = price } var s = new Student ('Tom' , 20 , 14000 )console .log (s.name , s.age , s.price )
[Person]中的this是动态变化的,在[Student]中利用[Person.call(this, name, age)]改变了其this指向,所以可以实现此效果
组合继承(原型链+构造函数)
利用原型链实现对父类型对象的方法继承
利用super()借用父类型构建函数初始化相同属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function Person (name, age ) { this .name = name this .age = age } Person .prototype .setName = function (name ) { this .name = name } function Student (name, age, price ) { Person .call (this , name, age) this .price = price } Student .prototype = new Person () Student .prototype .constructor = Student Student .prototype .setPrice = function (price ) { this .price = price } var s = new Student ('Tom' , 24 , 15000 )s.setName ('Bob' ) s.setPrice (16000 ) console .log (s.name , s.age , s.price )