详细分析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 相关文章推荐
jquery利用ajax调用后台方法实例
Aug 23 Javascript
Javascript基础教程之数据类型转换
Jan 18 Javascript
js实现获取两个日期之间所有日期的方法
Jun 17 Javascript
H5移动端图片压缩上传开发流程
Nov 09 Javascript
Node.js读取文件内容示例
Mar 07 Javascript
对vue里函数的调用顺序介绍
Mar 17 Javascript
vue项目动态设置页面title及是否缓存页面的问题
Nov 08 Javascript
详解javascript 变量提升(Hoisting)
Mar 12 Javascript
微信小程序实现收货地址左滑删除
Nov 18 Javascript
简单了解微信小程序 e.target与e.currentTarget的不同
Sep 27 Javascript
微信小程序 textarea 层级过高问题简单解决方案
Oct 14 Javascript
vue全屏事件开发详解
Jun 17 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中的正则表达式
2014/08/17 PHP
PHP遍历目录函数opendir()、readdir()、closedir()、rewinddir()总结
2014/11/18 PHP
php利用scws实现mysql全文搜索功能的方法
2014/12/25 PHP
详解js异步文件加载器
2016/01/24 PHP
PHP中大括号'{}'用法实例总结
2017/02/08 PHP
PHP封装返回Ajax字符串和JSON数组的方法
2017/02/17 PHP
php校验公钥是否可用的实例方法
2019/09/17 PHP
srcElement表格样式
2006/09/03 Javascript
jQuery 拖动层(在可视区域范围内)
2012/05/24 Javascript
JS动态添加与删除select中的Option对象(示例代码)
2013/12/20 Javascript
javascript + jquery实现定时修改文章标题
2014/03/19 Javascript
JavaScript生成的动态下雨背景效果实现方法
2015/02/25 Javascript
javascript版2048小游戏
2015/03/18 Javascript
浅谈js里面的InttoStr和StrtoInt
2016/06/14 Javascript
javascript self对象使用详解
2016/10/18 Javascript
如何用js判断dom是否有存在某class的值
2017/02/13 Javascript
AngularJS执行流程详解
2017/02/17 Javascript
浅谈js for循环输出i为同一值的问题
2017/03/01 Javascript
AngularJS之页面跳转Route实例代码
2017/03/10 Javascript
详解JavaScript中return的用法
2017/05/08 Javascript
JavaScript中Hoisting详解 (变量提升与函数声明提升)
2017/08/18 Javascript
详解React 在服务端渲染的实现
2017/11/16 Javascript
深入理解webpack process.env.NODE_ENV配置
2020/02/23 Javascript
Vue 3.0中jsx语法的使用
2020/11/13 Javascript
原生JS实现音乐播放器
2021/01/26 Javascript
Python中如何导入类示例详解
2019/04/17 Python
如何将tensorflow训练好的模型移植到Android (MNIST手写数字识别)
2020/04/22 Python
Python unittest单元测试框架实现参数化
2020/04/29 Python
matplotlib 生成的图像中无法显示中文字符的解决方法
2020/06/10 Python
python实现猜数游戏(保存游戏记录)
2020/06/22 Python
对Python 字典元素进行删除的方法
2020/07/31 Python
用HTML5的canvas实现一个炫酷时钟效果
2016/05/20 HTML / CSS
总经理助理岗位职责范本
2014/07/20 职场文书
学位证书委托书
2014/09/30 职场文书
医学专业大学生职业生涯规划书
2014/10/25 职场文书
幼儿园班级管理心得体会
2016/01/07 职场文书