详细分析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 最简单易用的表单验证插件
Feb 27 Javascript
多选列表框动态添加,移动,删除,全选等操作的简单实例
Jan 13 Javascript
jQuery插件datepicker 日期连续选择
Jun 12 Javascript
使用requestAnimationFrame实现js动画性能好
Aug 06 Javascript
jquery 实现输入邮箱时自动补全下拉提示功能
Oct 04 Javascript
轻松实现js弹框显示选项
Sep 13 Javascript
原生JS实现几个常用DOM操作API实例
Jan 19 Javascript
AngularJS的脏检查深入分析
Apr 22 Javascript
关于JavaScript中高阶函数的魅力详解
Sep 07 Javascript
如何使用VuePress搭建一个类型element ui文档
Feb 14 Javascript
抖音上用记事本编写爱心小程序教程
Apr 17 Javascript
vue实现简单数据双向绑定
Apr 28 Vue.js
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 set_time_limit(0)长连接的实现分析
2010/03/02 PHP
PHP 自定义错误处理函数trigger_error()
2013/03/26 PHP
PHP中使用SimpleXML检查XML文件结构实例
2015/01/07 PHP
PHP 5.3和PHP 5.4出现FastCGI Error解决方法
2015/02/12 PHP
PHP使用strrev翻转中文乱码问题的解决方法
2017/01/13 PHP
PHP基于递归算法解决兔子生兔子问题
2018/05/11 PHP
laravel按天、按小时,查询数据的实例
2019/10/09 PHP
锋利的jQuery 要点归纳(三) jQuery中的事件和动画(上:事件篇)
2010/03/24 Javascript
jQuery实现公告文字左右滚动的实例代码
2013/10/29 Javascript
扩展IE中一些不兼容的方法如contains、startWith等等
2014/01/09 Javascript
Javascript玩转继承(三)
2014/05/08 Javascript
JS获取Table中td值的方法
2015/03/19 Javascript
JavaScript实现点击文字切换登录窗口的方法
2015/05/11 Javascript
javascript实现框架高度随内容改变的方法
2015/07/23 Javascript
AngularJS基础 ng-open 指令简单实例
2016/08/02 Javascript
Javascript将JSON日期格式化
2016/08/23 Javascript
three.js实现3D视野缩放效果
2017/11/16 Javascript
详解Vue文档中几个易忽视部分的剖析
2018/03/24 Javascript
Angular使用过滤器uppercase/lowercase实现字母大小写转换功能示例
2018/03/27 Javascript
element-ui的回调函数Events的用法详解
2018/10/16 Javascript
Vue模板语法中数据绑定的实例代码
2019/05/17 Javascript
js实现经典贪吃蛇小游戏
2020/03/19 Javascript
JS使用正则表达式实现常用的表单验证功能分析
2020/04/30 Javascript
python使用any判断一个对象是否为空的方法
2014/11/19 Python
Python 实现使用dict 创建二维数据、DataFrame
2018/04/13 Python
pandas多级分组实现排序的方法
2018/04/20 Python
解决Jupyter因卸载重装导致的问题修复
2020/04/10 Python
VSCode中autopep8无法运行问题解决方案(提示Error: Command failed,usage)
2021/03/02 Python
详解CSS3 Media Queries中媒体属性的使用
2016/02/29 HTML / CSS
法国时尚童装网站:Melijoe
2016/08/10 全球购物
英国最大的电子产品和家电零售企业:Currys PC World
2016/09/24 全球购物
Auguste The Label官网:澳大利亚一家精品女装时尚品牌
2020/06/14 全球购物
经济管理毕业生求职信
2014/03/15 职场文书
小学元宵节活动总结
2015/02/06 职场文书
2016年寒假见闻
2015/10/10 职场文书
服务器SVN搭建图文安装过程
2022/06/21 Servers