详细分析Javascript中创建对象的四种方式


Posted in Javascript onAugust 17, 2016

前言

使用Javascript创建对象的方式有很多,现在就来列举一下其中的四种方式,并且罗列出了每种方式的优缺点,可以让大家进行选择使用,下面来看看。

工厂模式

function createPerson(name, age){
 var obj = new Object();
 obj.name = name;
 obj.age = age;
 return obj; //一定要返回,否则打印undefined:undefined
 }
 var person1 = new createPerson('Young',18);
 console.log(person1.name + ':' + person1.age);

优点:工厂模式可以解决创建多个相似对象

缺点:没有解决对象识别问题(怎样确定一个对象的类型)

构造函数模式

function Person(name,age){
 this.name = name;
 this.age = age;
 }
 var person1 = new Person('Young',18);
 console.log(person1.name + ':' + person1.age);

在说优缺点之前,先来说说她本身的一点小故事吧

将构造函数当做函数使用

function Person(name,age){
 this.name=name;
 this.age=age;
 this.sayName=function(){
 return this.name;
 }
 }
 
 //当做构造函数使用
 var person1 = new Person('Young', 18);
 person1.sayName();
 console.log(person1.name + ':' + person1.age);
 
 //当做普通函数调用
 Person('Wind', 18);
 console.log(window.sayName());
 
 //在另一个作用域中调用
 var obj = new Object();
 Person.call(obj, 'bird', 100);
 console.log(obj.sayName());

构造函数优缺点

优点:可以将它的实例标识为一种特定类型

缺点:每个方法都要在每个实例上重新创建一遍。当然你也可以这样改:

function Person(name, age){
 this.name = name;
 this.age = age;
 this.sayName = sayName;
 }
 function sayName(){
 return this.name;
 }

改为调用全局函数,这样一来毫无封装性可言。。。接下来的原型模式可以弥补这个的不足

原型模式

function Person(){
 
 }
 Person.prototype.name = 'Young';
 Person.prototype.age = 18;
 Person.prototype.sayName = function(){
 return this.name;
 }
 
 var person1 = new Person();
 console.log(person1.sayName());
 var person2 = new Person();
 console.log(person1.sayName());
 alert(person1.sayName === person2.sayName);
 //person1和person2访问的是同一组属性的同一个sayName()函数

虽然可以通过对象实例访问保存在原型中的值,但却不能通过实例对象重写原型中的值

function Person(){
 
 }
 Person.prototype.name='Young';
 Person.prototype.age=18;
 Person.prototype.sayName=function(){
 return this.name;
 }
 
 var person1=new Person();
 var person2=new Person();
 person1.name='Wind';
 
 console.log(person1.sayName());//Wind
 console.log(person2.sayName());//Young
 alert(person1.sayName==person2.sayName);//true

在我们调用person1.sayName的时候,会先后执行两次搜索,解析器先确定实例person1是否有sayName的属性,有则调用自己的属性,没有则搜索原型中的属性。

function Person(){
 
 }
 Person.prototype.name='Young';
 Person.prototype.age=18;
 Person.prototype.sayName=function(){
 return this.name;
 }
 
 var person1=new Person();
 var person2=new Person();
 
 person1.name='Wind';
 console.log(person1.sayName());//Wind
 console.log(person2.sayName());//Young
 
 delete person1.name;
 console.log(person1.sayName());//Young
 console.log(person2.sayName());//Young

使用hasOwnPropertyType方法可以检测一个属性是存在与原型中还是存在于实例中,该方法是从Object继承来的,实例中为true,原型中为false。

枚举对象上的实例属性用Object.keys()方法

function Person(){
 
 }
 Person.prototype.name='Young';
 Person.prototype.age=18;
 Person.prototype.sayName=function(){
 return this.name;
 }
 
 var keys=Object.keys(Person.prototype);
 console.log(keys);//["name", "age", "sayName"]

原型模式优缺点

优点:不用每个方法都要在每个实例上重申一遍

缺点:很少有人单独使用原型模式地。。问题详列

function Person(){
 
 }
 Person.prototype={
 constructor:Person,
 name:'Young',
 age:18,
 friends:['Big','Pig'],
 sayName:function(){
 return this.name;
 }
 };
 var p1=new Person();
 var p2=new Person();
 p1.friends.push('Mon');
 console.log(p1.friends);//["Big", "Pig", "Mon"]
 console.log(p2.friends);//["Big", "Pig", "Mon"]

正是因为实例一般都要有自己的属性,而我们这里将他放在了Person.prototype中,所以随着p1的修改,整个实例包括原型都修改了。那么,我们可以组合使用构造函数模式和原型模式。

组合使用构造函数模式和原型模式

function Person(name,age){
 this.name=name;
 this.age=age;
 this.friends=['Big','Pig'];
 }
 Person.prototype={
 sayName:function(){
 return this.name;
 }
 };
 var p1=new Person('Young',18);
 var p2=new Person('Wind',78);
 p1.friends.push('Raganya');
 console.log(p1.friends);//["Big", "Pig", "Raganya"]
 console.log(p2.friends);//["Big", "Pig"]
 console.log(p1.friends==p2.friends);//false
 console.log(p1.sayName==p2.sayName);//true

这种模式是目前使用最广泛、认同度最高的一种创建自定义类型的方法。是用来定义引用类型的一种默认模式。

总结

以上就是关于分析Javascript中创建对象方式的全部内容,通过这篇文章为大家总结的四种方式和其优缺点,希望可以对大家学习使用Javascript能有所帮助。

Javascript 相关文章推荐
JavaScript自执行闭包的小例子
Jun 29 Javascript
查看大图功能代码jquery版
Nov 05 Javascript
js 针对html DOM元素操作等经验累积
Mar 11 Javascript
jQuery支持添加事件的日历特效代码分享(3种样式)
Aug 24 Javascript
JavaScript子窗口调用父窗口变量和函数的方法
Oct 09 Javascript
jQuery元素属性操作实例(设置、获取及删除元素属性)
Sep 08 Javascript
关于Vue.js一些问题和思考学习笔记(1)
Dec 02 Javascript
微信小程序上传图片功能(附后端代码)
Jun 19 Javascript
Vue实现商品分类菜单数量提示功能
Jul 26 Javascript
教你如何用Node实现API的转发(某音乐)
Sep 20 Javascript
浅谈如何优雅处理JavaScript异步错误
Nov 12 Javascript
Nuxt的路由配置和参数传递方式
Nov 06 Javascript
AngularJS表单详解及示例代码
Aug 17 #Javascript
AngularJS模块详解及示例代码
Aug 17 #Javascript
Bootstrap 源代码分析(未完待续)
Aug 17 #Javascript
AngularJS HTML DOM详解及示例代码
Aug 17 #Javascript
AngularJS表格详解及示例代码
Aug 17 #Javascript
AngularJS过滤器详解及示例代码
Aug 16 #Javascript
AngularJS控制器详解及示例代码
Aug 16 #Javascript
You might like
php中批量修改文件后缀名的函数代码
2011/10/23 PHP
fgetcvs在linux的问题
2012/01/15 PHP
PHP读取Excel类文件
2017/05/15 PHP
php检测mysql表是否存在的方法小结
2017/07/20 PHP
特殊字符、常规符号及其代码对照表
2006/06/26 Javascript
javascript实现仿银行密码输入框效果的代码
2007/12/13 Javascript
gameboy网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点
2016/02/21 Javascript
bootstrap daterangepicker汉化以及扩展功能
2017/06/15 Javascript
ReactNative实现图片上传功能的示例代码
2017/07/11 Javascript
vue中component组件的props使用详解
2017/09/04 Javascript
详解ionic本地相册、拍照、裁剪、上传(单图完全版)
2017/10/10 Javascript
使用use注册Vue全局组件和全局指令的方法
2018/03/08 Javascript
ES6 Proxy实现Vue的变化检测问题
2019/06/11 Javascript
原生javascript单例模式的应用实例分析
2020/02/23 Javascript
Vue3不支持Filters过滤器的问题
2020/09/24 Javascript
关于小程序优化的一些建议(小结)
2020/12/10 Javascript
如何在JavaScript中正确处理变量
2020/12/25 Javascript
python 实现堆排序算法代码
2012/06/05 Python
python解析html开发库pyquery使用方法
2014/02/07 Python
Python内置函数dir详解
2015/04/14 Python
Python实现的递归神经网络简单示例
2017/08/11 Python
浅谈Scrapy框架普通反爬虫机制的应对策略
2017/12/28 Python
PyQt5每天必学之带有标签的复选框
2018/04/19 Python
对Python Class之间函数的调用关系详解
2019/01/23 Python
AUC计算方法与Python实现代码
2020/02/28 Python
python 如何调用 dubbo 接口
2020/09/24 Python
意大利宠物用品购物网站:Bauzaar
2018/09/15 全球购物
工作自荐信
2013/12/11 职场文书
五十岁生日宴会答谢词
2014/01/15 职场文书
2014工程部年度工作总结
2014/12/17 职场文书
优秀党员申报材料
2014/12/18 职场文书
捐助倡议书
2015/01/19 职场文书
2015年依法治校工作总结
2015/07/27 职场文书
运动会闭幕式致辞
2015/07/29 职场文书
python利用while求100内的整数和方式
2021/11/07 Python
Apache Linkis 中间件架构及快速安装步骤
2022/03/16 Servers