面向对象的特征就是封装性,继承性和多态性
| 封装:就是将复杂包裹,隐藏起来,让简单的东西预留在外面| 继承:拿来主义,自己没用,把别人的拿过来,让其成为自己的东西
1. 拷贝继承
拷贝继承:分为继承属性和继承方法两个部分
function Person(name,sex){//父类 this.name = name; this.sex = sex; } Person.prototype.showName = function (){ console.log(this.name); } Person.prototype.num = [1,2,3] var p1 = new Person('小明','男'); function Child(name,sex,job){//子类 Person.call(this,name,sex); //call则是改变Person函数内部this指向 this.job = job } Child.prototype = Person.prototype //可以实现原型方法继承,但是引用类型不能用这种形式,方法(function)不会改变只会增加或者删减 var p2 = new Child('小黄','男','学生') //* 在此改变p1的showName,p2的showName并不会改变,因为showName是方法,并不是引用类型 p2.showName = function (){ console.log('小黄'); } p1.showName(); //小明 p2.showName(); //小黄 //* 在次改变p1的num的值,此处num为引用类型,引用类型值一旦改变,p1.num和p2.num都会改变 p1.num.push(4); console.log(p1.num); //[1,2,3,4] console.log(p2.num); //[1,2,3,4]
2. 原型继承
如果需要让一个对象有某一个行为(属性,方法),那么可以把这个行为加到原型对象中,那么这个对象就继承自原型对象,获得该行为
1)利用对象的多态性添加成员
function Person(){}; Person.prototype.sayHello = function (){}; //直接在Person构造函数的原型属性上添加成员,即多态性的展现 var obj = new Person(); //在obj的原型对象中包含sayHello方法
2) 利用覆盖原型对象
function Person(){}; var obj = new Person(); console.log(obj.constructor) //Person obj属于Person类 Person.prototype = { sayHello : function (){}, sayGoodBye : function (){}, constructor : 'Person' //若此处不声明constructor属性,obj属于Object类,因为obj原型对象被覆盖,constructor属性从原型对象的原型对象上获得,所以为Object }; var obj = new Person(); console.log(obj.constructor) //Person
3) 利用组合式继承添加原型成员
function Person(){}; Person.prototype.extend(obj) //此处obj代表需要被继承的对象
3. 组合式继承
组合是继承就是将其他对象中的成员加到自己身上
var obj1 = {name:'wuxiaosui',age:18,sex:'nan'}; var obj2 = {score:{ math:90, english:120 }}; // for(var k in obj1){ // obj2[k] = obj1[k]; // } Object.prototype.extent = function (obj){ for(var k in obj){ this[k] = obj[k]; } } obj2.extent(obj1); //将extend方法放置在Object构造函数原型上,调用的函数可以继承任意来自于其他对象的属性方法
4.原型链结构
var o1 = new Object(); //o1原型链结构:o1 -> Object.prototype -> null
o1原型结构图如下:
function Person(){}; var o2 = new Person(); //o2原型链结构:o2 -> Person.prototype -> Object.prototype -> null
o2原型链结构图如下: