继承有什么好处?很简单,继承了你爸的财产,本身就能够少奋斗点嘛。开玩笑,言归正传,继承使子类拥有超类的做用域、属性与方法,能够节省程序设计的时间。ECMAScript实现继承主要方式是依靠原型链。javascript
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){ } //利用原型链继承 SubType.prototype = new SuperType(); var instance1 = new SubType(); console.log(instance1.colors) //["red", "blue", "green"]
上例中,经过SubType.prototype = new SuperType()
使SubType的原型链上增长了SuperType()这一环。从而使SubType 经过原型链继承了SuperType的color
属性。java
存在的问题:git
实例共享
在上面的例子中加入如下代码,发现SubType()的实例1对color
属性作出改变后,实例2获取到的color
属性是改变后的值。这是由于:github
每一个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。app
instance1.colors.push("black"); console.log(instance1.colors); //["red", "blue", "green", "black", "black"] var instance2 = new SubType(); console.log(instance2.colors);//["red", "blue", "green", "black", "black"]
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){ //继承了SuperType SuperType.call(this); } var instance1 = new SubType(); console.log(instance1.color)//["red", "blue", "green"]
基本思想即在子类型构造函数的内部调用超类型构造函数。函数
call和apply
全局函数apply和call能够用来改变函数中this的指向。this
存在的问题:prototype
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ console.log(this.name); }; function SubType(name, age){ //继承属性 SuperType.call(this, name); //第二次调用SuperType() this.age = age; } //继承方法 SubType.prototype = new SuperType(); //第一次调用SuperType() SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ console.log(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.colors.push("black"); console.log(instance1.colors); //"red,blue,green,black" instance1.sayName(); //"Nicholas"; instance1.sayAge(); //29 var instance2 = new SubType("Greg", 27); console.log(instance2.colors); //"red,blue,green" instance2.sayName(); //"Greg"; instance2.sayAge();
基本思想:设计
为何能够实现属性私有化?指针
存在的问题:
不管什么状况下,都会调用两次超类型构造函数::一次是在建立子类型原型的时候,另外一次是在子类型构造函数内部
function object(o){ function F(){} F.prototype = o; return new F(); } var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = Object.create(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); console.log(person.friends); //["Shelby", "Court", "Van", "Rob", "Barbie"]
ECMAScript 5 经过新增Object.create()方法规范化了原型式继承。这个方法接收两个参数:一个用做新对象原型的对象和(可选的)一个为新对象定义额外属性的对象
存在同原型链方式同样的问题
function object(o){ function F(){} F.prototype = o; return new F(); } function createAnother(original){ var clone = object(original); //经过调用函数建立一个新对象 clone.sayHi = function(){ //以某种方式来加强这个对象 console.log("hi"); }; return clone; //返回这个对象 } var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = createAnother(person); anotherPerson.sayHi(); //"hi"
function object(o){ function F(){} F.prototype = o; return new F(); } function inheritPrototype(subType, superType){ var prototype = object(superType.prototype); //建立对象 prototype.constructor = subType; //加强对象 subType.prototype = prototype; //指定对象 } function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ console.log(this.name); }; function SubType(name, age){ SuperType.call(this, name); //调用一次SuperType() this.age = age; } inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function(){ console.log(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.sayName(); console.log(instance1.colors);
参考书籍:《javascript高级程序设计》
个人博客:http://bigdots.github.io、http://www.cnblogs.com/yzg1/
若是以为本文不错的话,帮忙点击下面的推荐哦,谢谢!