在JavaScript中,可以通过原型链来实现继承和通过闭包来实现封装。
原型链继承是通过让子类的原型对象指向父类的实例来实现的。这样子类就可以继承父类的属性和方法。
function Parent() {
this.name = 'parent';
}
Parent.prototype.sayHello = function() {
console.log('Hello, I am ' + this.name);
};
function Child() {}
Child.prototype = new Parent();
var child = new Child();
child.sayHello(); // 输出:Hello, I am parent
构造函数继承是通过在子类中调用父类构造函数来实现的。这样子类就可以继承父类的属性。
function Parent(name) {
this.name = name;
}
function Child(name) {
Parent.call(this, name);
}
var child = new Child('child');
console.log(child.name); // 输出:child
组合继承是通过将原型链继承和构造函数继承结合起来来实现的。这样子类就既可以继承父类的属性,也可以继承父类的方法。
function Parent(name) {
this.name = name;
}
Parent.prototype.sayHello = function() {
console.log('Hello, I am ' + this.name);
};
function Child(name) {
Parent.call(this, name);
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
var child = new Child('child');
child.sayHello(); // 输出:Hello, I am child
通过闭包,可以将一些私有变量和方法封装起来,只暴露出一些公共的接口。
function Person(name) {
var age = 18; // 私有变量
function sayHello() { // 私有方法
console.log('Hello, I am ' + name);
}
this.getName = function() { // 公共方法
return name;
};
this.getAge = function() { // 公共方法
return age;
};
}
var person = new Person('person');
console.log(person.getName()); // 输出:person
console.log(person.getAge()); // 输出:18
ES6中,可以使用class和Symbol来实现封装。通过将一些私有属性和方法定义在class的constructor中,使用Symbol定义私有属性的属性名,再通过在class中定义公共方法来访问私有属性和方法。
const _name = Symbol('name'); // 私有属性名
class Person {
constructor(name) {
this[_name] = name; // 私有属性
}
getName() { // 公共方法
return this[_name];
}
}
let person = new Person('person');
console.log(person.getName()); // 输出:person
console.log(person[_name]); // 输出:undefined,无法访问私有属性
以上是JavaScript中实现继承和封装的两种常见方式。