详细分析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 call 函数的用法说明
Apr 09 Javascript
JS的get和set使用示例
Feb 20 Javascript
JavaScript设计模式之策略模式实例
Oct 10 Javascript
Bootstrap modal 多弹窗之叠加显示不出弹窗问题的解决方案
Feb 23 Javascript
bootstrap模态框远程示例代码分享
May 22 Javascript
angular框架实现全选与单选chekbox的自定义
Jul 06 Javascript
通过jquery.cookie.js实现记住用户名、密码登录功能
Jun 20 jQuery
微信小程序如何使用云开发
May 17 Javascript
vue实现搜索功能
May 28 Javascript
ES10的13个新特性示例(小结)
Sep 23 Javascript
jquery轻量级数字动画插件countUp.js使用详解
Oct 17 jQuery
js中Function引用类型常见有用的方法和属性详解
Dec 11 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 函数语法介绍一
2009/06/14 PHP
基于PHP array数组的教程详解
2013/06/05 PHP
解析php时间戳与日期的转换
2013/06/06 PHP
CI(CodeIgniter)框架介绍
2014/06/09 PHP
PHP使用mysql与mysqli连接Mysql数据库用法示例
2016/07/07 PHP
PHP使用mysqli操作MySQL数据库的简单方法
2017/02/04 PHP
详解PHP5.6.30与Apache2.4.x配置
2017/06/02 PHP
PHP crypt()函数的用法讲解
2019/02/15 PHP
thinkPHP框架乐观锁和悲观锁实例分析
2019/10/30 PHP
PHP队列场景以及实现代码实例详解
2021/02/26 PHP
javaScript对象和属性的创建方法
2007/01/15 Javascript
jQuery .tmpl(), .template()学习资料小结
2011/07/18 Javascript
将光标定位于输入框最右侧实现代码
2012/12/04 Javascript
如何学习Javascript入门指导
2013/11/01 Javascript
用jquery写的一个万年历(自写)
2014/01/20 Javascript
JQuery实现展开关闭层的方法
2015/02/17 Javascript
jQuery基本选择器(实例及表单域value的获取方法)
2016/05/20 Javascript
JS中静态页面实现微信分享功能
2017/02/06 Javascript
vue跨域解决方法
2017/10/15 Javascript
jQuery图片查看插件Magnify开发详解
2017/12/25 jQuery
vue中v-model的应用及使用详解
2018/06/27 Javascript
Webpack按需加载打包chunk命名的方法
2019/09/22 Javascript
vue-cli 为项目设置别名的方法
2019/10/15 Javascript
Python使用dis模块把Python反编译为字节码的用法详解
2016/06/14 Python
Python入门之三角函数sin()函数实例详解
2017/11/08 Python
Django Form and ModelForm的区别与使用
2019/12/06 Python
如何配置关联Python 解释器 Anaconda的教程(图解)
2020/04/30 Python
Python 私有属性和私有方法应用场景分析
2020/06/19 Python
Python利用socket模块开发简单的端口扫描工具的实现
2021/01/27 Python
详解利用css3的var()实现运行时改变scss的变量值
2021/03/02 HTML / CSS
StubHub澳大利亚:购买或出售您的门票
2019/08/01 全球购物
某IT外企面试题-二分法求方程!看看大家的C++功底
2015/07/04 面试题
应征英语教师求职信
2013/11/27 职场文书
前台文员我鉴定
2014/01/12 职场文书
喜之郎果冻广告词
2014/03/20 职场文书
vue如何在data中引入图片的正确路径
2022/06/05 Vue.js