详细分析Javascript中创建对象的四种方式

 更新时间:2016年08月17日 09:30:12   投稿:daisy  
这篇文章详细介绍了Javascript中创建对象的几种方式与每种方式的优缺点,其中包括工厂模式、构造函数模式、原型模式和组合使用构造函数模式和原型模式,有需要的小伙伴们一起来学习学习吧。

前言

使用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能有所帮助。

相关文章

  • React Native中TabBarIOS的简单使用方法示例

    React Native中TabBarIOS的简单使用方法示例

    最近在学习过程中遇到了很多问题,TabBarIOS的使用就是一个,所以下面这篇文章主要给大家介绍了关于React Native中TabBarIOS简单使用的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-10-10
  • layui监听select变化,以及设置radio选中的方法

    layui监听select变化,以及设置radio选中的方法

    今天小编就为大家分享一篇layui监听select变化,以及设置radio选中的方法,具有好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • JavaScript“尽快失败”的原则实例详解

    JavaScript“尽快失败”的原则实例详解

    我第一次听说编码原则中有“尽快失败”这一条时,觉得很奇怪,为什么代码要失败?应该成功才对呀。下面小编通过实例代码给大家介绍js 尽快失败的原则,一起看看吧
    2016-10-10
  • 解决webpack -p压缩打包react报语法错误的方法

    解决webpack -p压缩打包react报语法错误的方法

    这篇文章主要给大家介绍了关于解决webpack -p压缩打包react报语法错误的方法,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-07-07
  • JavaScript动态改变HTML页面元素例如添加或删除

    JavaScript动态改变HTML页面元素例如添加或删除

    HTML页面元素可以通过js动态改变,比如可以向HTML中添加元素或删除某个元素,下面为示例代码,感兴趣的朋友不要错过
    2014-08-08
  • layui实现鼠标移动到单元格上显示数据的方法

    layui实现鼠标移动到单元格上显示数据的方法

    今天小编就为大家分享一篇layui实现鼠标移动到单元格上显示数据的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • 浅谈JavaScript中运算符的优先级

    浅谈JavaScript中运算符的优先级

    这篇文章主要给大家简单介绍了JavaScript中运算符的优先级的相关问题,十分的实用,有需要的小伙伴可以参考下。
    2015-07-07
  • 微信小程序实现页面分享onShareAppMessage

    微信小程序实现页面分享onShareAppMessage

    这篇文章主要介绍了微信小程序实现页面分享onShareAppMessage,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • 微信小程序入口场景的问题集合与相关解决方法

    微信小程序入口场景的问题集合与相关解决方法

    这篇文章主要介绍了微信小程序入口场景的问题集合与相关解决方法,从零开始开发一个小程序,大多数坑点都是在微信小程序的各个入口场景处。所以这里整理一下微信小程序的各个入口场景会面临的问题以及解决方案,需要的朋友可以参考下
    2019-06-06
  • 让浏览器非阻塞加载javascript的几种方法小结

    让浏览器非阻塞加载javascript的几种方法小结

    通常大多数浏览器是并行下载资源的,但由于外部脚本的特殊性例如通过脚本改变文档的DOM结构、脚本之间的存在依赖关系、使用document.write 向页面输出HTML等。
    2011-04-04

最新评论