1.原型链

2.ES5继承实现
//Person类 构造方法
function Person(name,age){
this.name = name;
this.age = age;
}
//Person类 原型的hi方法
Person.prototype.hi = function(){
console.log('Hi,my name is '+this.name+' and I am '+this.age+'years old now.');
}
//Person类 原型的属性
Person.prototype.LEGS_NUM = 2;
Person.prototype.ARMS_NUM = 2;
Person.prototype.walk = function(){
console.log(this.name+' is walking...');
}
var p = new Person("li","18");
p.walk();//li is walking...
//Student 类
function Student(name,age,className){
Person.call(this,name,age);//调用Person构造方法,参考Object.prototype.toString.call({}) 某个方法使用在某个对象上,这里Person构造方法使用在this(当new时的bosn对象)
this.className = className;
}
//Student 类继承Person
Student.prototype = Object.create(Person.prototype);//Object.create(要继承的对象)
Student.prototype.constructor = Student;//将Student构造方法置为Student 否则则是Person的构造方法
//重写hi方法
Student.prototype.hi = function(){
console.log('Hi,my name is '+this.name+' and I am '+this.age+'years old now,and from '+this.className);
}
//学生类新有方法lear
Student.prototype.learn = function(subject){
console.log(this.name +' is learning '+subject+' at '+this.className);
}
var bosn = new Student("bosn",27,'Class 3,Grade 2');
bosn.hi();//Hi,my name isbosn,I am 27 years old now,and from Class 3,Grade 2.
bosn.LEGS_NUM;//2
bosn.walk();//bosn is walking...
bosn.learn("Math");//bosn is learning Math at Class 3,Grade 2
//prototype
Student.prototype.x = 101//修改student原型的属性,会影响到bosn对象
101
bosn.x
101
Student.prototype = {x:1} //但是如果把Student的原型替换成其他对象,则不会改变以创建的对象,但是通过Student新new的对象则会替换
bosn的 __proto__是Person
var newBosn = new Student()
newBosn
newBosn的__proto__是{x:1}
继承可以分为三个步骤:
- 父类和子类的创建
- 子类Child.prototype指向父类Parent.prototype
- 将子类Child.prototype.constructor重新指向Child,同时如果需要继承父类的属性需要在constructor执行Person.call(this)
注意
其中核心在于第二步,那么直接用Child.prototype==Parent.prototype不就行了?
这样是有问题的,因为一旦给Child添加方法比如Chld.prototype.cry 那么就会直接影响到Parent
那么,可不可以Child.prototype = new Parent() 呢,这样看起来没有问题呀new Child可以获取Parent的方法和属性。然而这样方式有个弊端,就是Child.prototype会携带父类创造的属性值,比如Child.prototype.name是在存在的,这样会污染原型链。
==Object.create()==
首先了解下Object.create()方法的简单实现
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();//f
};
A.prototype = Object.create(B.prototype)意味着 A.prototype.proto = F.prototype = B.prototype;既A的原型并不直接等于B的原型,而是等于中间量new F();
这样的话既避免了污染原型链,同时将父类方法继承过了,然后在Child的constructor中执行 Person.call(this,name,age);实现对父类构造函数的继承。
Object.create使用
var o = Object.create(Object.prototype, {
// foo会成为所创建对象的数据属性
foo: {
writable:true,
configurable:true,
value: "hello"
},
// bar会成为所创建对象的访问器属性
bar: {
configurable: false,
get: function() { return 10 },
set: function(value) {
console.log("Setting `o.bar` to", value);
}
}
});