详细分析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实现checkbox全选全不选的简单实例
Dec 31 Javascript
jquery 获取dom固定元素 添加样式的简单实例
Feb 04 Javascript
jquery操作HTML5 的data-*的用法实例分享
Aug 17 Javascript
使用JavaScript进行进制转换将字符串转换为十进制
Sep 21 Javascript
JS实现网页背景颜色与select框中颜色同时变化的方法
Feb 27 Javascript
jQuery使用CSS()方法给指定元素同时设置多个样式
Mar 26 Javascript
Javascrip实现文字跳动特效
Nov 27 Javascript
浅谈regExp的test方法取得的值变化的原因及处理方法
Mar 01 Javascript
原生JS实现图片无缝滚动方法(附带封装的运动框架)
Oct 01 Javascript
vuejs 切换导航条高亮(路由菜单高亮)的方法示例
May 29 Javascript
vue 引用自定义ttf、otf、在线字体的方法
May 09 Javascript
vue缓存之keep-alive的理解和应用详解
Nov 02 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中的时间处理
2006/10/09 PHP
PHP strstr 函数判断字符串是否否存在的实例代码
2013/09/28 PHP
初识通用数据库操作类――前端easyui-datagrid,form(php)
2015/07/31 PHP
详解PHP的Yii框架中自带的前端资源包的使用
2016/03/31 PHP
PHP基于PDO调用sqlserver存储过程通用方法【基于Yii框架】
2017/10/07 PHP
Javascript 变量作用域 两个可能会被忽略的小特性
2010/03/23 Javascript
基于jQuery的实现简单的分页控件
2010/10/10 Javascript
图片动画横条广告带上下滚动可自定义图片、链接等等
2013/10/20 Javascript
jQuery+ajax实现鼠标单击修改内容的思路
2014/06/29 Javascript
Javascript验证方法大全
2015/09/21 Javascript
node.js 中国天气预报 简单实现
2016/06/06 Javascript
移动端 一个简单易懂的弹出框
2016/07/06 Javascript
js仿腾讯QQ的web登陆界面
2016/08/19 Javascript
解决node.js安装包失败的几种方法
2016/09/02 Javascript
Vue 2中ref属性的使用方法及注意事项
2017/06/12 Javascript
shiro授权的实现原理
2017/09/21 Javascript
记一次vue-webpack项目优化实践详解
2019/02/17 Javascript
深入理解Puppeteer的入门教程和实践
2019/03/05 Javascript
JavaScript中arguments的使用方法详解
2020/12/20 Javascript
python打包压缩、读取指定目录下的指定类型文件
2018/04/12 Python
python 用lambda函数替换for循环的方法
2018/06/09 Python
Python不同目录间进行模块调用的实现方法
2019/01/29 Python
python学习--使用QQ邮箱发送邮件代码实例
2019/04/16 Python
PowerBI和Python关于数据分析的对比
2019/07/11 Python
Python字典常见操作实例小结【定义、添加、删除、遍历】
2019/10/25 Python
Python web如何在IIS发布应用过程解析
2020/05/27 Python
CSS3中的@keyframes关键帧动画的选择器绑定
2016/06/13 HTML / CSS
1688平价精选商城:阿里集团旗下,工厂出厂价格直销
2017/04/24 全球购物
德国汽车零件和汽车配件网上商店:kfzteile24
2018/11/14 全球购物
英国设计师泳装、沙滩装和比基尼在线精品店:Beach Cafe
2019/08/28 全球购物
个人融资协议书范本两则
2014/10/15 职场文书
2014年除四害工作总结
2014/12/06 职场文书
村干部任职承诺书
2015/01/21 职场文书
导游词之海南天涯海角
2019/12/05 职场文书
详解Redis主从复制实践
2021/05/19 Redis
python图像处理基本操作总结(PIL库、Matplotlib及Numpy)
2021/06/08 Python