[[Prototype]]
,可以通过 Object.getPrototypeOf()
或 __proto__
来访问。一个对象可以通过其原型访问另一个对象的属性和方法。prototype
属性:函数对象(尤其是构造函数)有一个 prototype
属性,指向一个对象,这个对象的所有实例共享该对象的属性和方法。function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a noise.`);
}
const dog = new Animal('Dog');
dog.speak(); // "Dog makes a noise."
[[Prototype]]
隐式属性(也可以通过 __proto__
访问),它指向另一个对象(即该对象的原型)。通过原型链,一个对象可以访问其原型对象以及更高层次原型链上的属性和方法。null
,通常是 Object.prototype
的原型为 null
),仍然找不到该属性或方法,返回 undefined
。function Animal(name) {
this.name = name;
this.num = [1,2,3]
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a noise.`);
};
function Dog(name) {
this.name = name;
}
Dog.prototype = new Animal(); // 原型链继承
Dog.prototype.constructor = Dog;
const dog1 = new Dog('Dog1');
const dog2 = new Dog('Dog1');
dog1.num.push(4);
console.log(dog1.num)
console.log(dog2.num)
dog.speak(); // "Dog makes a noise."
在这个例子中,Dog.prototype
指向一个 Animal
实例,因此 dog
可以访问 Animal.prototype
上的 speak
方法。这就是原型链继承的典型示例。
function Dog() {
Animal.call(this); // 确保每个实例都有自己的 colors 属性
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Parent.prototype.getname = function () {
return this.name;
}
function Parent() {
this.name = 'parent';
this.age = 10;
this.arr = [1, 2, 3]
}
function Child() {
//借用构造函数继承
Parent.call(this);
this.type = 'children';
}
//原型链继承
Child.prototype = new Parent();
//手动将 Child 类的原型对象的 constructor 属性重新设置为 Child 函数本身
Child.prototype.constructor = Child;
let s1 = new Child();
let s2 = new Child();
s1.arr.push(4);
console.log(s1.arr);
console.log(s2.arr);
console.log(s1.getname());
ES6类继承的底层原理就是寄生组合式继承,是通过封装寄生组合式继承而来的。
// Shape——父类
function Shape() {
this.x = 0;
this.y = 0;
}
// 父类方法
Shape.prototype.move = function (x, y) {
this.x += x;
this.y += y;
console.info("Shape moved.");
};
// Rectangle——子类
function Rectangle() {
Shape.call(this); // 调用父类构造函数。
}
// 子类继承父类
Rectangle.prototype = Object.create(Shape.prototype, {
// 如果不将 Rectangle.prototype.constructor 设置为 Rectangle,
// 它将采用 Shape(父类)的 prototype.constructor。
// 为避免这种情况,我们将 prototype.constructor 设置为 Rectangle(子类)。
constructor: {
value: Rectangle,
enumerable: false,
writable: true,
configurable: true,
},
});
const rect = new Rectangle();
console.log("rect 是 Rectangle 类的实例吗?", rect instanceof Rectangle); // true
console.log("rect 是 Shape 类的实例吗?", rect instanceof Shape); // true
rect.move(1, 1); // 打印 'Shape moved.'
class
语法:ES6 引入了 class
关键字,它提供了更清晰和结构化的语法来实现继承,背后依然是基于原型链。extends
和 super
关键字:使用 extends
关键字可以创建子类,super()
用于调用父类的构造函数或方法。class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
age
constructor(name) {
super(name);// 调用父类的构造上函数
this.age = age
}
//同名方法,就近原则,优先使用自己的方法,无则使用父类方法
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog('Dog');
dog.speak();
// 输出:
// "Dog makes a noise."
// "Dog barks."
因篇幅问题不能全部显示,请点此查看更多更全内容