1,对象冒充方式
原理:构造函数使用this关键字给所有属性和方法赋值。因为构造函数只是一个函数,所有可是基类的构造函数成为子类的方法,然后调用它。子类就会收到基类的构造函数中定义的属性和方法。
function ClassA(sColor) {
this.color = sColor;
this.showColor = function() {
alert(this.color);
};
}
function ClassB(sColor,sName) {
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod; //删除对ClassA的引用,以后就不能在调用它。
this.name = sName; //所有新的属性和方法必须在删除了新方法(newMethod)的代码后定义.否则,可能会覆盖基类的相关属性和方法
this.showName = function() {
alert(this.name);
};
}
var objA = new ClassA("red");
var objB = new ClassB("blue","Nicholas");
objA.showColor(); //outputs "red"
objB.showColor(); //outputs "blue"
objB.showName(); //outputs "Nicholas"
this.color = sColor;
this.showColor = function() {
alert(this.color);
};
}
function ClassB(sColor,sName) {
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod; //删除对ClassA的引用,以后就不能在调用它。
this.name = sName; //所有新的属性和方法必须在删除了新方法(newMethod)的代码后定义.否则,可能会覆盖基类的相关属性和方法
this.showName = function() {
alert(this.name);
};
}
var objA = new ClassA("red");
var objB = new ClassB("blue","Nicholas");
objA.showColor(); //outputs "red"
objB.showColor(); //outputs "blue"
objB.showName(); //outputs "Nicholas"
并且对象冒充可以支持多重继承。
例如
function ClassZ(){
//继承ClassX
this.newMethod = ClassX;
this.newMethod();
delete this.newMethod;
//继承ClassY
this.newMethod = ClassY;
this.newMethod();
delete this.newMethod;
}
//继承ClassX
this.newMethod = ClassX;
this.newMethod();
delete this.newMethod;
//继承ClassY
this.newMethod = ClassY;
this.newMethod();
delete this.newMethod;
}
但是,如果ClassX和ClassY居右相同名的属性和方法时,ClassY则具有高优先级,因为它从后面的类继承。
2,call()方法
基本用法:
function showColor(sPrefix, sSuffix) {
alert(sPrefix + this.color + sSuffix);
};
var obj = new Object();
obj.color = "red";
showColor.call(obj, "The color is ", ", a very nice color indeed."); //outputs "The color is red, a very nice color indeed."
alert(sPrefix + this.color + sSuffix);
};
var obj = new Object();
obj.color = "red";
showColor.call(obj, "The color is ", ", a very nice color indeed."); //outputs "The color is red, a very nice color indeed."
与对象冒充方法一起使用
function ClassB(sColor,sName){
//this.newMethod = ClassA;
//this.newMethod(sColor);
//delete this.newMethod;
ClassA.call(this,sColor);
this.name = sName;
this.showName = function(){
alert(this.name);
};
}
//this.newMethod = ClassA;
//this.newMethod(sColor);
//delete this.newMethod;
ClassA.call(this,sColor);
this.name = sName;
this.showName = function(){
alert(this.name);
};
}
3,apply()方法
基本用法
function display(sPrefix, sSuffix) {
alert(sPrefix + this.color + sSuffix);
}
var obj = new Object();
obj.color = "blue";
display.apply(obj, new Array("111", "222"));
alert(sPrefix + this.color + sSuffix);
}
var obj = new Object();
obj.color = "blue";
display.apply(obj, new Array("111", "222"));
同上
function ClassB(sColor, sName) {
ClassA.apply(this, [sColor]);
this.name = sName;
this.showName = function() {
alert(this.name);
};
}
ClassA.apply(this, [sColor]);
this.name = sName;
this.showName = function() {
alert(this.name);
};
}
4,原型链
function ClassA() {
}
ClassA.prototype.color = "red";
ClassA.prototype.showColor = function(){
alert(this.color);
};
function ClassB(){
}
ClassB.prototype = new ClassA();
ClassB.prototype.name = "asdf"; //添加新属性和方法必须出现在对ClassB.prototype赋值完成后。
ClassB.prototype.showName = function(){
alert(this.name);
};
var objA = new ClassA();
var objB = new ClassB();
objA.color = "red";
objB.color = "blue";
objB.name = "adf";
objA.showColor();
objB.showColor();
objB.showName();
}
ClassA.prototype.color = "red";
ClassA.prototype.showColor = function(){
alert(this.color);
};
function ClassB(){
}
ClassB.prototype = new ClassA();
ClassB.prototype.name = "asdf"; //添加新属性和方法必须出现在对ClassB.prototype赋值完成后。
ClassB.prototype.showName = function(){
alert(this.name);
};
var objA = new ClassA();
var objB = new ClassB();
objA.color = "red";
objB.color = "blue";
objB.name = "adf";
objA.showColor();
objB.showColor();
objB.showName();
注意:调用ClassA的构造函数时,没有给它传递参数。这在原型链中是标准做法。要确保构造函数没有任何参数。
原型链不支持多重继承。
5,混合方式
就是将对象冒充与原型链方式进行组合。
function ClassA(sColor) {
this.color = sColor;
}
ClassA.prototype.showColor = function() {
alert(this.color);
};
function ClassB(sColor, sName) {
ClassA.call(this, sColor);
this.name = sName;
}
ClassB.prototype = new ClassA();
ClassB.prototype.showName = function() {
alert(this.name);
};
var objA = new ClassA("red");
var objB = new ClassB("blue", "name");
objA.showColor();
objB.showColor();
objB.showName();
this.color = sColor;
}
ClassA.prototype.showColor = function() {
alert(this.color);
};
function ClassB(sColor, sName) {
ClassA.call(this, sColor);
this.name = sName;
}
ClassB.prototype = new ClassA();
ClassB.prototype.showName = function() {
alert(this.name);
};
var objA = new ClassA("red");
var objB = new ClassB("blue", "name");
objA.showColor();
objB.showColor();
objB.showName();
附:动态原型方法不能实现继承机制。
分类:
02 - JavaScript
, 12 - 技巧总结
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构