面向面试编程——javascript对象的几种创建方式
javascript对象的几种创建方式
总共有以下几个模式:
1.工厂模式
2.构造函数模式
3.原型模式
4.混合构造函数和原型模式
5.动态原型模式
6.寄生构造函数模式
7.稳妥构造函数模式
1.工厂模式:
<script type="text/javascript"> function Person(name,sex) { var obj=new Object(); obj.name=name; obj.sex=sex; obj.getSex=function(){ alert(this.sex); } return obj; } var person=new Person("张三","男") alert(person.name); person.getSex(); </script>
缺点:不能识别出对象的类型。
2.构造函数模式
<script type="text/javascript"> function Person(name,sex) { this.name=name; this.sex=sex; this.getSex=function(){ alert(this.sex); } } var person=new Person('张三','男'); alert(person.name); person.getSex(); </script>
使用构造函数模式可以有三种创造方式:
(1)当作构造函数去使用
var person=new Person();
(2) 当作普通函数去使用
var person=Person();但是这种方式默认this是windows,相当于直接在全局范围内定义name,sex属性。
(3)使用call
var person=new Object();
Person.call(person,"张三","男");
alert(person.name); //张三
缺点:由于this指针在对象实例的时候发生改变指向新的实例。这时新实例的方法也要重新创建,如果n个实例就要n次重建相同的方法
3.原型模式
<script type="text/javascript"> function Person() { } Person.prototype={ constructor:Person, //必须设置这个属性,不然就断了与构造函数的联系了。没有实例共享原型的意义了。 /* 现在这个属性是可枚举的,若不想被枚举,则可以使用如下代码 参数:重设构造器的对象,所要设置的属性,可选设置 Object.definePropery(Person.prototype,'constructor',{ enumerable:false, value:Person }) */ name:'张三', sex:'男', getSex:function(){ alert(this.sex); } } var person=new Person(); alert(person.name); person.getSex(); </script>
调用方法的过程:先看实例中有没有,有调之,无追踪到原型,有调之,无出错,调用失败。
缺点:这种纯原型的模式问题也很明显,所有的属性,方法和变量都是共享的,一旦修改一个全部都会受影响,不能让对象具体化。
4.混合构造和原型模式
<script type="text/javascript"> function Person(name,sex) { this.name=name; this.sex=sex; } Person.prototype={ constructor:Person, //必须设置这个属性,不然就断了与构造函数的联系了。没有实例共享原型的意义了。 /* 现在这个属性是可枚举的,若不想被枚举,则可以使用如下代码 参数:重设构造器的对象,所要设置的属性,可选设置 Object.definePropery(Person.prototype,'constructor',{ enumerable:false, value:Person }) */ getSex:function(){ alert(this.sex); } } var person=new Person("张三","男"); alert(person.name); person.getSex(); </script>
推荐:应用最广泛。
5.动态原型模式
<script type="text/javascript"> function Person(name,sex) { this.name=name; this.sex=sex; //动态原型方法 只会执行一次 if(typeof this.getSex!='function') { Person.prototype.getSex=function(){ alert(this.sex); } } } var person=new Person("张三","男"); alert(person.name); person.getSex(); </script>
推荐
5.寄生构造函数模式
这种模式的基本思想是创建一个函数
,该函数的作用仅仅是封闭创建对象的代码
,然后再返回新创建的对象.
假设我们想创建一个具有额外方法的特殊数组。由于不能直接修改Array构造函数,可以使用这个模式。
function SpecialArray() { //创建数组 var values = new Array(); // 添加值 values.push.apply(values, arguments); // 添加方法 values.toPipedString = function() { return this.join('|'); }; // 返回数组 return values; } var colors = new SpecialArray('red', 'blue', 'green'); alert(colors.toPipedString());//red|blue|green;
在这个例子中,我们创建了一个名叫SpecialArray的构造函数。在这个函数内部,首先创建了一个数组,然后push()方法(用构造函数接收到的所有参数)初始化了数组的值。随后,又给数组实例添加了一个toPipedString()方法,该方法返回以竖线分割的数组值。最后,将数组以函数值的形式返回。接着,我们调用了SpecialArray构造函数,向其中传入了用于初始化数组的值,此后调用了toPipedString()方法。
关于寄生构造函数模式,有一点需要说明:首先,返回的对象与构造函数或构造函数的原型属性之间没有关系;也就是说,构造函数返回的对象与在构造函数外部创建 对象没有什么不同。为此,不能依赖instranceof操作符来确定对象类型。由于存在上述问题,建议在可以使用其他模式的情况下,不要使用这种模式。
6.稳妥构造函数模式
<script type="text/javascript"> function Person(name,sex) { var object=new Object(); var name=name; var sex=sex; object.getSex=function(){ alert(sex); } return object; } var person=new Person("张三","男"); alert(person.name); //undefined person.getSex(); //男 </script>
没有公共属性,其他方法也不引用this对象,只能通过存取器获得变量的值,适合对安全性要求很高的程序。
还有不能被称为模式的方法,只能实例单个对象:
1.简单对象字面量
//创建一个简单对象字面量 var person = {}; // 加入属性和方法 person.name = 'ifcode'; person.setName = function(theName) { person.name = theName; }
非常简单,但一般情况下不推荐这种方法。JS good parts书中认为这种写法可读性不够强,作者推荐的是后面一种写法。
2.嵌套对象字面量
var person = { name: 'ifcode', setName: function(theName) { this.name = theName; } }
JS good parts中推荐这种写法:
【推荐】国内首个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如何颠覆传统软件测试?测试工程师会被淘汰吗?