关于javascript面向对象的一点思考
借这篇文章理清一下自己的思路,同时也希望能给和我同样一知半解的同学理清一下思路。
引发思考来自于我犯的一个错误,错误代码是这样的:
var o = {
...
}
var obj = new o();
...
}
var obj = new o();
结果不用说,当然是报错的。遗憾的是我以前一直以为var o = { }是定义了一个叫做o的类。然后自己理了一下。得出一下结论:
var o = {};
等价于
var o = new Object();
但不等价于
var o = function(){};
第一二种形式 o是一个对象,Object类的对象
第三种形式 o是一个function,更重要的是o是一个类
var o = {};
o.oField = "oField";
等价于
var o = {
oField : "oField"
}
那问题是:对象上怎么可以直接定义属性呢?
由于o是Object类的对象,所以o.prototype是undefined 所以不能这样 o.prototype.oField = ...
另外,在思考过程中,我写了两段测试代码,一并贴上。可以算是个笔记吧。

//定义类
var Engin = function(){};
//实例属性
Engin.prototype.objectField = "objectField";
//类属性(静态域)
Engin.classField = "classField";
//实例方法
Engin.prototype.objectMethod = function(){
document.write("objectMethod is called<br/>");
}
//类方法(静态方法)
Engin.classMethod = function(){
document.write("classMethod is called<br/>");
}
//调用实例方法
new Engin().objectMethod();
//调用类方法
Engin.classMethod();
document.write(new Engin().objectField + "<br/>");
document.write(Engin.classField + "<br/>");
//只能遍历出类属性和类方法
//怎么遍历出实例属性和实例方法呢?
document.write("使用for in 遍历Engin对象===============================<br/>");
for(var o in Engin){
document.write(o+"<br/>");
}
document.write("=======================================================<br/>");
var Engin = function(){};
//实例属性
Engin.prototype.objectField = "objectField";
//类属性(静态域)
Engin.classField = "classField";
//实例方法
Engin.prototype.objectMethod = function(){
document.write("objectMethod is called<br/>");
}
//类方法(静态方法)
Engin.classMethod = function(){
document.write("classMethod is called<br/>");
}
//调用实例方法
new Engin().objectMethod();
//调用类方法
Engin.classMethod();
document.write(new Engin().objectField + "<br/>");
document.write(Engin.classField + "<br/>");
//只能遍历出类属性和类方法
//怎么遍历出实例属性和实例方法呢?
document.write("使用for in 遍历Engin对象===============================<br/>");
for(var o in Engin){
document.write(o+"<br/>");
}
document.write("=======================================================<br/>");

//定义父类Parent,并在父类里定义了一个属性pField和一个方法pMethod
var Parent = function(){
this.pField = "pField";
this.pMethod = function(){
document.write("pMethod is called<br/>");
}
};
//定义父类静态属性
Parent.staticPField = "staticPField";
//定义父类静态方法
Parent.staticPMethod = function(){
document.write("staticPMethod is called<br/>");
}
//定义子类Child,并在子类里定义了一个属性cField和一个方法cMethod
var Child = function(){
this.cField = "cField";//实例属性
this.cMethod = function(){//实例方法
document.write("cMethod is called<br/>");
}
};
//定义子类静态属性
Child.staticCField = "staticCField";
//定义子类静态方法
Child.staticCMethod = function(){
document.write("staticCMethod is called<br/>");
}
//指定Child继承自Parent
Child.prototype = new Parent();
//创建子类对象
var childObj = new Child();
document.write(childObj.pField+"<br/>");//子类对象访问父类实例属性
//document.write(childObj.staticPField+"<br/>");//子类对象不能访问父类静态属性
childObj.pMethod();//子类对象调用父类实例方法
//childObj.staticPMethod();//子类对象不能调用父类静态方法
document.write(childObj.cField+"<br/>");//子类对象访问自己的实例属性
document.write(Child.staticCField+"<br/>");//必须使用类名访问自己的静态属性
childObj.cMethod();//子类对象调用自己的实例方法
Child.staticCMethod();//必须使用类名来调用自己的静态方法
var Parent = function(){
this.pField = "pField";
this.pMethod = function(){
document.write("pMethod is called<br/>");
}
};
//定义父类静态属性
Parent.staticPField = "staticPField";
//定义父类静态方法
Parent.staticPMethod = function(){
document.write("staticPMethod is called<br/>");
}
//定义子类Child,并在子类里定义了一个属性cField和一个方法cMethod
var Child = function(){
this.cField = "cField";//实例属性
this.cMethod = function(){//实例方法
document.write("cMethod is called<br/>");
}
};
//定义子类静态属性
Child.staticCField = "staticCField";
//定义子类静态方法
Child.staticCMethod = function(){
document.write("staticCMethod is called<br/>");
}
//指定Child继承自Parent
Child.prototype = new Parent();
//创建子类对象
var childObj = new Child();
document.write(childObj.pField+"<br/>");//子类对象访问父类实例属性
//document.write(childObj.staticPField+"<br/>");//子类对象不能访问父类静态属性
childObj.pMethod();//子类对象调用父类实例方法
//childObj.staticPMethod();//子类对象不能调用父类静态方法
document.write(childObj.cField+"<br/>");//子类对象访问自己的实例属性
document.write(Child.staticCField+"<br/>");//必须使用类名访问自己的静态属性
childObj.cMethod();//子类对象调用自己的实例方法
Child.staticCMethod();//必须使用类名来调用自己的静态方法
分类:
web前端开发
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?