详细分析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三个关闭弹出层的小示例
Nov 05 Javascript
jQuery常用操作方法及常用函数总结
Jun 19 Javascript
兼容IE、firefox以及chrome的js获取时间(getFullYear)
Jul 04 Javascript
BootStrap.css 在手机端滑动时右侧出现空白的原因及解决办法
Jun 07 Javascript
微信小程序商品详情页规格属性选择示例代码
Oct 30 Javascript
详解微信小程序开发用户授权登陆
Apr 24 Javascript
8个有意思的JavaScript面试题
Jul 30 Javascript
如何对react hooks进行单元测试的方法
Aug 14 Javascript
Node.js HTTP服务器中的文件、图片上传的方法
Sep 23 Javascript
解决vue做详情页跳转的时候使用created方法 数据不会更新问题
Jul 24 Javascript
使用js获取身份证年龄的示例代码
Dec 11 Javascript
Nest.js环境变量配置与序列化详解
Feb 21 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中数据的批量导入(csv文件)
2006/10/09 PHP
动态生成gif格式的图像要注意?
2006/10/09 PHP
php设计模式 Delegation(委托模式)
2011/06/26 PHP
win7计划任务定时执行PHP脚本设置图解
2014/05/09 PHP
laravel安装zend opcache加速器教程
2015/03/02 PHP
php中header跳转使用include包含解决参数丢失问题
2015/05/08 PHP
php similar_text()函数的定义和用法
2016/05/12 PHP
PHP chunk_split()函数讲解
2019/02/12 PHP
使用documentElement正确取得当前可见区域的大小
2014/07/25 Javascript
Bootstrap精简教程
2015/11/27 Javascript
jQuery动画效果图片轮播特效
2016/01/12 Javascript
jquery html动态添加的元素绑定事件详解
2016/05/24 Javascript
JS对HTML表格进行增删改操作
2016/08/22 Javascript
js创建对象几种方式的优缺点对比
2016/09/28 Javascript
JS常用倒计时代码实例总结
2017/02/07 Javascript
React Native中TabBarIOS的简单使用方法示例
2017/10/13 Javascript
解决vuex改变了state的值,但是页面没有更新的问题
2020/11/12 Javascript
对pycharm代码整体左移和右移缩进快捷键的介绍
2018/07/16 Python
python安装twisted的问题解析
2018/08/21 Python
python字符串Intern机制详解
2019/07/01 Python
Python字符串的修改方法实例
2019/12/19 Python
Python实现加密的RAR文件解压的方法(密码已知)
2020/09/11 Python
使用Python判断一个文件是否被占用的方法教程
2020/12/16 Python
Python基于mediainfo批量重命名图片文件
2020/12/29 Python
使用jquery实现HTML5响应式导航菜单教程
2014/04/02 HTML / CSS
h5使用canvas画布实现手势解锁
2019/01/04 HTML / CSS
香港太阳眼镜网上商店:SmartBuyGlasses香港
2016/07/22 全球购物
Fossil美国官网:Fossil手表、手袋、珠宝及配件
2017/02/01 全球购物
Bed Bath & Beyond加拿大官网:购买床上用品、浴巾、厨房电器等
2019/10/04 全球购物
内勤主管岗位职责
2014/04/03 职场文书
《海底世界》教学反思
2014/04/16 职场文书
新员工入职欢迎词
2015/01/23 职场文书
求职意向书范本
2015/05/11 职场文书
MySQL中你可能忽略的COLLATION实例详解
2021/05/12 MySQL
基于Redis延迟队列的实现代码
2021/05/13 Redis
前端canvas中物体边框和控制点的实现示例
2022/08/05 Javascript