详细分析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 相关文章推荐
extjs 学习笔记(二) Ext.Element类
Oct 13 Javascript
Javascript跨域请求的4种解决方式
Mar 17 Javascript
jquery的总体架构分析及实现示例详解
Nov 08 Javascript
javascript中使用new与不使用实例化对象的区别
Jun 22 Javascript
jQuery实现瀑布流布局详解(PC和移动端)
Sep 01 Javascript
浅析jQuery 3.0中的Data
Jun 14 Javascript
详解bootstrap用dropdown-menu实现上下文菜单
Sep 22 Javascript
Vue中render方法的使用详解
Jan 26 Javascript
零基础之Node.js搭建API服务器的详解
Mar 08 Javascript
JS计算两个数组的交集、差集、并集、补集(多种实现方式)
May 21 Javascript
微信小程序自定义tabBar的踩坑实践记录
Nov 06 Javascript
JavaScript实现点击自制菜单效果
Feb 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与XML、XSLT、Mysql的结合运用实现代码
2009/11/19 PHP
php生成二维码的几种方式整理及使用实例
2013/06/03 PHP
php缓冲 output_buffering和ob_start使用介绍
2014/01/30 PHP
PHP中的socket_read和socket_recv区别详解
2015/02/09 PHP
PHP实现全角字符转为半角方法汇总
2015/07/09 PHP
Laravel实现autoload方法详解
2017/05/07 PHP
JavaScript中实现块作用域的方法
2010/04/01 Javascript
js改变Iframe中Src的方法
2015/05/05 Javascript
JavaScript让Textarea支持tab按键的方法
2015/06/26 Javascript
浅谈Node.js:Buffer模块
2016/12/05 Javascript
Vue实例简单方法介绍
2017/01/20 Javascript
javascript中的面向对象
2017/03/30 Javascript
解决Vue页面固定滚动位置的处理办法
2017/07/13 Javascript
JS沙箱模式实例分析
2017/09/04 Javascript
vue双花括号的使用方法 附练习题
2017/11/07 Javascript
Vue.set()实现数据动态响应的方法
2018/02/07 Javascript
vue.js的vue-cli脚手架中使用百度地图API的实例
2019/01/21 Javascript
JS左右无缝轮播功能完整实例
2019/05/16 Javascript
[01:06:54]DOTA2-DPC中国联赛 正赛 SAG vs DLG BO3 第二场 2月28日
2021/03/11 DOTA
详解Python3中的Sequence type的使用
2015/08/01 Python
python 用正则表达式筛选文本信息的实例
2018/06/05 Python
xadmin使用formfield_for_dbfield函数过滤下拉表单实例
2020/04/07 Python
keras在构建LSTM模型时对变长序列的处理操作
2020/06/29 Python
红色康乃馨酒店:Red Carnation Hotels
2017/06/22 全球购物
新西兰最大的连锁超市:Countdown
2020/06/04 全球购物
命名空间(namespace)和程序集(Assembly)有什么区别
2015/09/25 面试题
关于赌博的检讨书
2014/01/08 职场文书
童装店创业计划书
2014/01/09 职场文书
剪彩仪式主持词
2014/03/19 职场文书
啤酒节策划方案
2014/05/28 职场文书
水污染治理工程专业自荐信
2014/06/21 职场文书
促销活动总结怎么写
2014/06/25 职场文书
归途列车观后感
2015/06/17 职场文书
2019年度开业庆典祝福语大全!
2019/07/05 职场文书
2019年描写人生经典诗句大全
2019/07/08 职场文书
能用CSS实现的就不要麻烦JavaScript了
2021/10/05 HTML / CSS