Open
Description
Javascript 原型链继承
图片无法在issue中提交,原文在这里:onvno博客
简单实现继承
var a = {
x: 10,
calculate: function (z) {
return this.x + this.y + z
}
};
var b = {
y: 20,
__proto__: a
};
var c = {
y: 30,
__proto__: a
};
// call the inherited method
b.calculate(30); // 60
c.calculate(40); // 80
他们之间的继承关系:
以上图,观察a
可得到:
如果没有明确为一个对象指定原型,那么它将会使用proto的默认值-Object.prototype。Object.prototype对象自身也有一个proto属性,这是原型链的终点并且值为null。
以上代码,ES5实现方法:
var b = Object.create(a, {y: {value: 20}});
var c = Object.create(a, {y: {value: 30}});
如浏览器不支持,可用以下Polyfill
if(!Object.create){
Object.create = function(obj){
function F(){};
F.prototype = obj;
return new F();
}
}
构造函数继承
// a constructor function
function Foo(y) {
// which may create objects
// by specified pattern: they have after
// creation own "y" property
this.y = y;
}
// also "Foo.prototype" stores reference
// to the prototype of newly created objects,
// so we may use it to define shared/inherited
// properties or methods, so the same as in
// previous example we have:
// inherited property "x"
Foo.prototype.x = 10;
// and inherited method "calculate"
Foo.prototype.calculate = function (z) {
return this.x + this.y + z;
};
// now create our "b" and "c"
// objects using "pattern" Foo
var b = new Foo(20);
var c = new Foo(30);
// call the inherited method
b.calculate(30); // 60
c.calculate(40); // 80
// let's show that we reference
// properties we expect
console.log(
b.__proto__ === Foo.prototype, // true
c.__proto__ === Foo.prototype, // true
// also "Foo.prototype" automatically creates
// a special property "constructor", which is a
// reference to the constructor function itself;
// instances "b" and "c" may found it via
// delegation and use to check their constructor
b.constructor === Foo, // true
c.constructor === Foo, // true
Foo.prototype.constructor === Foo // true
b.calculate === b.__proto__.calculate, // true
b.__proto__.calculate === Foo.prototype.calculate // true
);
注意:可得出constructor
都指向构造函数本身,创建的实例b,c都指向构造函数的'prototype对象'
ES6的继承-类-extends
class Person {
constructor(name,age){
this.name = name;
this.age = age;
}
sayHello(){
console.log(`My name is ${this.name},i'm ${this.age} years old`)
}
toString(){
...
}
}
class Student extends Person{
constructor(name,age,cla){
super(name,age); // 调用父类的constructor(name, age)
this.class = cla;
}
study(){
console.log(`I'm study in class ${this.class}`)
}
toString() {
return this.class + ' ' + super.toString(); // 调用父类的toString()
}
}
constructor
方法是类的默认方法,通过new
命令生成对象实例时,自动调用该方法。一个类必须有constructor
方法,如果没有显式定义,一个空的constructor
方法会被默认添加。
注意,子类中必须在constructor
先使用super()
来调用父类。
原因是子类通过super
获取父类this
实现继承,否则后边的this.class
因获取不到this
会报错。
super
这个关键字,有两种用法,含义不同。(1)作为函数调用时(即
super(...args)
),super
代表父类的构造函数。(2)作为对象调用时(即
super.prop
或super.method()
),super
代表父类。注意,此时super
即可以引用父类实例的属性和方法,也可以引用父类的静态方法。
ES6可实现原生构造函数的继承。
参考链接
Metadata
Metadata
Assignees
Labels
No labels