一、传统模式 – 利用原型链
Grand.prototype.lastName = '王五';
function Grand() {
}
var grand = new Grand();
Father.prototype = grand;
function Father() {
this.name = '李四'
}
var father = new Father();
Son.prototype = father;
function Son() {
}
var son = new Son();
console.log(son.name); // 李四
console.log(son.lastName); // 王五
缺点是:继承了过多的无用属性
二、借用构造函数
function Student(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
function Person(name, age, sex, grade) {
Student.call(this, name, age, sex);
this.grade = grade;
}
var person = new Person('mary', 18, 'female', 550);
console.log(person.name); // marry
缺点:不能继承借用构造函数的原型,只能借用构造函数的方法, 每次构造函数都要多走一个函数,只是从视觉上变少了而已
三、共享原型
Student.prototype = Person.prototype; // 把两个原型的地址都引向 Person 的原型
Student.prototype.name = 'mary';
function Student() {
}
function Person() {
}
var person = new Pereson();
console.log(person.name); // mary
// Person.prototype
// Student Father
// 原型是构造函数构造出的对象的公有祖先
// 现在多个构造函数共用了一个原型
小小升级一下
Father.prototype.lastName = 'smith';
function Father() {
}
function Son() {
}
// 用一个函数传参
function inherit(Target, Origin) {
Target.prototype = Origin.prototype;
}
inherit(Son, Father);
var son = new Son();
console.log(son.lastName); // smith
// 这种方法的缺点是,每个构造函数想给自己的原型上加一个属性,其他的构造函数原型也会受到影响
// 我们需要的是,每个构造函数能单独给自己的原型设置属性,不影响其他人,但是又需要其他人原型上提供的属性
缺点:不能随便改动自己的原型
四、圣杯模式
function inherit(Target, Origin) {
function F() {}
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constructor = Target;
Target.prototype.uber = Origin.prototype;
}
Father.prototype.lastName = 'mary';
function Father() {
}
function Son() {
}
var father = new Father();
var son = new Son();
五、联想一下闭包私有化的应用
function Student(name, age) {
var str = '我供你们使用';
this.name = name;
this.age = age;
this.doing = function() {
this.age = str;
}
this.dance = function(Target) {
str = Target;
}
this.say = function() {
console.log(str);
}
}
var student = new Student('mary', 18);
六、结合闭包私有化,升级圣杯模式
var inherit = (function () {
var F = function() {};
return function (Target, Origin) {
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constructor = Target;
Target.prototype.uber = Origin.prototype;
}
}());
function Father() {
}
function Son() {
}
inherit(Son, Father);
var father = new Father();
var son = new Son();
七、空间命名问题
通过闭包实现变量私有化
var name = 'smith';
var init = (function () {
// 这里面的所有变量命名,跟外面没有关系
var name = 'mary';
function callName() {
console.log(name);
}
return function () {
callName(); // 这是一个函数的接口
}
});
像jQuery一样,实现一个方法的连续调用
var obj = {
smoke: function() {
console.log('i am smoking');
return this;
},
drink: function() {
console.log('i am drinking');
return this;
},
prem: function() {
console.log('i am preming');
return this;
}
};
obj.smoke().drink().prem(); // 模仿 jQuery 链式调用