javascript 之 面向对象【创建对象】
创建对象
(1) 工厂模式
1 2 3 4 5 6 7 8 9 10 11 12 | function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert( this .name); }; return o; } var person1 = createPerson( "Nicholas" , 29, "Software Engineer" ); var person2 = createPerson( "Greg" , 27, "Doctor" );<br>存在的问题:没有解决对象时别问题(怎么知道一个对象的类型) |
(2)构造函数模式
注意点:构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头
1 2 3 4 5 6 7 8 | function Person(name, age, job){ this .name = name; this .age = age; this .job = job; this .sayName = function(){ alert( this .name); }; }与上面进行比较<br>1/没有显示的创建对象<br>2/直接将属性和方法赋给了 this 对象<br>3/没有 return 语句 var person1 = new Person( "Nicholas" , 29, "Software Engineer" ); <br> var person2 = new Person( "Greg" , 27, "Doctor" );<br>创建Person新实例必须使用 new 操作符,对应着四个步骤<br>1/创建新的对象<br>2/将构造函数的作用域给新对象<br>3/执行构造函数中的代码<br>4/返回新对象<br><br> //作为普通函数调用<br>Person(Greg,27,Doctor)//添加到window<br>window.sayName();<br>//在另一个对象的作用域中调用<br>var o=new Object();<br>Person.call(o,Kristen,25,Nurser)<br>o.sayName()<br><br>存在的问题:每个方法都要在每个实例上重新创建一遍,person1和person2都有一个sayName()方法,但实际这两个方法不知一样的 |
(3)原型模式
1 2 3 4 5 6 7 8 9 10 11 12 13 | 每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象<br>好处:可以让所有对象实例共享它所包含的属性和方法<br>function Person(){ } Person.prototype.name = "Nicholas" ; Person.prototype.age = 29; Person.prototype.job = "Software Engineer" ; Person.prototype.sayName = function(){ alert( this .name); }; var person1 = new Person(); person1.sayName(); //"Nicholas" var person2 = new Person(); person2.sayName(); //"Nicholas" alert(person1.sayName == person2.sayName); //true<br><br>//说明:在ECMAScript新增方法Object.getPrototypeOf() |
alert(Object.getPrototypeOf(person1) == Person.prototype); //true
alert(Object.getPrototypeOf(person1).name); //"Nicholas"
在这里,解析器实际执行了两次搜索,第一次:person1有name属性吗,答:没有 ;第二次:person1的原型有这个属性吗,答:有。
//若实例存在和实例原型中一样的属性同名,那么实例中的属性会屏蔽原型中的属性
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
person1.name = "Greg";
alert(person1.name); //"Greg"——来自实例
alert(person2.name); //"Nicholas"——来自原型
delete person1.name;
alert(person1.name); //"Nicholas" ——来自原型
//原型与in操作符
in操作符会在通过对象访问给定属性时返回true,无论该属性存在于实例还是原型中
alert(person1.hasOwnProperty("name")); //false
alert(person1.hasPrototypeProperty("name")) // true
alert("name" in person1); //true
person1.name = "Greg";
alert(person1.name); //"Greg" ——来自实例
alert(person1.hasOwnProperty("name")); //true
//hasOwnProperty判断是来自于原型属性时 返回false;
//hasPrototypeProperty判断是来自于原型属性时,返回true;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现