函数原型+对象冒充实现继承
// 父类函数
function Person(name) {
this.name = name;
}
// 父类函数的原型属性
Person.prototype.say = function () {
console.log("Hello " + this.name);
};
// 子类函数
function Ninja(name, weapon) {
// 对象冒充,将子类函数的上下文this,传给父类构造函数,这样可以实现将父类函数的属性挂载到子类对象中
// 这样就可以使用子类函数构造器将父类函数的属性copy过来。见下图
Person.call(this, name);
this.weapon = weapon;
}
// 为了继承父类原型上的方法,我们知道每个构造函数的实例有含有一个指向原型的引用
//而js查找标识符(属性或方法)是在原型链上由近及远搜索
Ninja.prototype = new Person();
Ninja.prototype.feint = function () {
console.log("feint using " + this.weapon);
};
// 将Ninja.prototype替换为Person实例会让prototype少一个constructor属性,这里使用Object内置的方法设置constructor
// 详见Object.defineProperty说明
Object.defineProperty(Ninja.prototype, "constructor", {
enumerable: false,
value: Ninja,
writable: true
});
let ninja = new Ninja('YouShi', 'Knife');
ninja.say();
ninja.feint();
Chrome的scope视图
运行结果
原理说明