87,993
社区成员
发帖
与我相关
我的任务
分享
function Person(username) {
this.username = username;
}
Person.prototype.setUsername = function(name) {
this.username = name;
}
// 继承Person
function Employee(username, company) {
Person.call(this, username);
this.company = company;
}
// 设置原型
Employee.prototype = new Person()
Employee.prototype.constructor=Employee
// 测试代码
var yiifaa = new Employee('yiifaa', '360')
你这个是一个比较常见继承方法,它是通过把子类的原型对象(prototype)设置成父类的一个实例来进行继承的。
但是只简单的这样设置继承有四个缺点:
缺点一:执行上面代码会发现父类的构造函数不是像JAVA中那样在给子类进行实例化时执行的,而是在设置继承的时候执行的,并且只执行一次。这往往不是我们希望的,特别是父类的构造函数中有一些特殊操作的情况下。
缺点二:由于父类的构造函数不是在子类进行实例化时执行,在父类的构造函数中设置的成员变量到了子类中就成了所有实例对象公有的公共变量。由于JavaScript中继承只发生在“获取”属性的值时,对于属性的值是String,Number和Boolean这些数据本身不能被修改的类型时没有什么影响。但是Array和Object类型就会有问题。就如你的代码那样
缺点三:如果父类的构造函数需要参数,我们就没有办法了。
缺点四:子类原本的原型对象被替换了,子类本身的constructor属性就没有了。在类的实例取它的constructor属性时,取得的是从父类中继承的constructor属性,从而constructor的值是父类而不是子类。
为了解决这四个缺点,正确的继承方法如下:
function SuperClass(){
this.books=["js","html","css"];
this.age=1;
}
function SubClass(){
SuperClass.call(this);//主动调用父类的构造函数
}
//SubClass.prototype=new SuperClass();
SubClass.prototype = Object.create(SuperClass.prototype);//ie9+
/* ie9以下用下面代码
var Bs = function(){};
Bs.prototype = SuperClass.prototype;
SubClass.prototype = new Bs();
*/
SubClass.prototype.constructor = SubClass;
var a1=new SubClass();
var a2= new SubClass();
console.log(a2.age);
a1.age=22;
console.log(a2.age);
console.log(a2.books);
a1.books.push('jquery');
console.log(a2.books);