摘自《JavaScript的对象继承方式,有几种写法》,做者:peakedness
连接:http://www.javashuo.com/article/p-zmgddvlv-hz.html数组
原理:构造函数使用this关键字给全部属性和方法赋值(即采用类声明的构造函数方式)。由于构造函数只是一个函数,因此可以使Parent构造函数称为Children的方法,而后调用它。Children会收到Parent的构造函数中定义的属性和方法。
***app
//父类构造函数 var Parent = function(name){ this.name = name; this.sayHi = function(){ console.log("Hi" + this.name + "."); } } var Children = function(name){ this.method = Parent; this.method(name); //实现继承 delete this.method; this.getName = function(){ console.log(this.name); } } var P = new Parent("john"); var C = new Children("joe"); P.sayHi(); //Hi john C.sayHi(); //Hi joe C.getName(); //joe
原理:JS是一门基于原型的语言。在JS中prototype对象的任何属性和方法都被传递给那个类的全部实例。函数
//父类构造函数 var Parent = function(name){ this.name = name; this.sayHi = function(){ console.log("Hi" + this.name + "."); } } //子类构造函数 var Children = function(){}; Children.prototype = new Parent(); var P = new Parent(); var C = new Children(); P.sayHi(); C.sayHi();
注意:
调用Parent的构造函数,没有给它传递参数。这是原型链中的标准作法,要确保构造函数没有任何参数。this
原理:经过改变this指向实现继承。apply第二个参数必须是数组,call依次传入。.net
//父类构造函数 var Parent = function(name){ this.name = name; this.sayHi = function(){ console.log("Hi" + this.name + "."); } }; //子类构造函数 var Children = function(name){ Parent.call(this,name); this.getName = function(){ console.log(this.name); } }; var C = new Children("Joe"); C.sayHi(); //Hi john C.getName(); //Joe
使用原型链就没法使用带参数的构造函数了
所以,在JS中建立类,最好使用构造函数定义属性,使用原型链定义方法。prototype
//父类构造函数 var Parent = function(name){ this.name = name; } Parent.prototype.sayHi = function(){ console.log("Hi ! " + this.name + "!!!"); } var P = new Parent("John"); P.sayHi(); //Hi John !!!
Object.create方法会使用指定的原型对象及其属性去建立一个新的对象code
//父类构造函数 var Parent = function(name){ this.name = name; } Parent.prototype.sayHi = function(){ console.log("Hi " + this.name + "."); } //子类构造函数 var Children = function(name,age){ this.age = age; Parent.call(this,name); //属性不在prototype上 }; Children.prototype = Object.create(Parent.prototype); Children.prototype.constructor = Children; Children.prototype.getAge = function(){ console.log(this.age); }; var P = new Parent("John"); var C = new Children("Joe",30); P.sayHi(); //Hi John C.sayHi(); //Hi Joe C.getAge(); //30
注意:
当执行Children.prototype = Object.create(Parent.prototype)这个语句后,Children的constructor就被变为Parent,所以须要将Children.protype.constructor从新指定为Children自己。对象
constructor指向建立此对象的函数的引用。blog
class Paren{ constructor(name,age){ this.name = name; this.age = age; } } class Children extends Parent{ constructor(name,age,job){ super(name,age); //super必须在前,不然代码报错 this.job = job; } }
注意:
子类的constructor方法没有调用super以前,就使用this关键字会报错。缘由是:子类Children的构造函数之中的super(),表明调用父类Parent的构造函数。继承
super虽然表明了父类Parent的构造函数,可是返回的是子类Children的实例,即super内部的this指的是Children,所以super()在这里至关于Parent.prototype.constructor.call(this);