一、创建对象

1.1 工厂模式

工厂模式抽象了创建具体对象的过程,用函数来封装以特定接口创建对象的细节。代码如下:

function createPerson(name, age, job) {var o = new Object();o.name = name;o.age = age;o.job = job;o.sayName = function() {console.log(this.name);};return o;
}var person1 = createPerson('sy', 25, 'Software Engineer')
var person2 = createPerson('sansa', 25, 'Doctor')

工厂模式的优点:解决创建多个相似对象的问题

缺点:无法解决对象识别的问题,即怎样知道一个对象的类型

1.2 构造函数模式

构造函数可以创建特定类型的对象,如果是Object和Array这样的原生构造函数,在运行时会出现在执行环境中,此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。

function Person(name, age, job) {this.name = name;this.age = age;this.job = job;this.sayName = function() {console.log(this.name)}
}var person1 = new Person('sy',  25, 'Software Engineer')
var person2 = new Person('sansa', 25, 'Doctor')

与构造函数不同之处:

没有显式地创建对象;直接将属性和方法赋给了this对象;没有return语句。

创建Person的新实例,必须使用new操作符。会经过以下步骤:

(1)创建一个新对象;

(2)将构造函数的作用域赋给新对象(因此this就指向了这个新对象);

(3)执行构造函数中的代码(为这个新对象添加属性);

(4)返回新对象。

person1和person2都有一个constructor(构造函数)属性,该属性指向Person。

person1.constructor == Person; // true

构造函数的优点:可以清楚的知道一个对象的类型

缺点:构造函数中存在方法的话,每个Person实例都包含一个不同的Function实例。ECMAScript中的函数是对象,因此每定义一个函数,就是实例化了一个对象。如果将方法移到全局作用域的话,会导致这个函数只能被某个对象调用,这让全局作用域名不副实。而且如果对象需要定义很多方法,那就要定义很多全局函数,这样对自定义的引用类型没有了封装性。

1.3 原型模式(*)

使用原型对象的好处是:可以让所有对象实例共享它所包含的属性和方法。创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,prototype就是通过调用构造函数而创建的那个对象实例的原型对象。

function Person() {
}Person.prototype.name = 'sy';
Person.prototype.age = 25;
Person.prototype.job = 'Software Engineer';
Person.prototype.sayName = function() {console.log(this.name)
};var person1 = new Person()
person1.sayName() // 'sy'var person2 = new Person()
person2.sayName() // 'sy'person1.sayName === person2.sayName // true

__proto__存在于实例与构造函数的原型对象之间。

Person.prototype.isPrototypeOf(person1) // true

Object.getPrototypeOf(person1) == Person.prototype // true

注:使用for-in循环时,返回的是通过对象访问的、可枚举的属性,包括实例中的属性,也包括存在于原型中的属性。要取得对象上所有可枚举的实例属性,使用ES5的Object.keys()方法,这个方法接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组。

如果要得到所有实例属性,无论是否可枚举,可以使用Object.getOwnPropertyNames(Person.prototype); // ["constructor", "name"] 显示了不可枚举的constructor属性

简单的原型语法:

function Person(){
}Person.prototype = {name: 'sy',age: '25',job: 'Software Engineer',sayName: function() {console.log(name)}
}

constructor属性不再指向Person了。每创建一个函数,就会同时创建它的prototype对象,这个对象也会自动获得constructor属性,而这个语法,本质上完全重写了默认的prototype对象,因此constructor属性也就变成了新对象的constructor属性(指向Object构造函数),不再指向Person函数。通过constructor无法确定对象的类型了。可以强制将constructor: Person,但是会导致它的[[Enumerable]]特性设置为true。实例中的指针仅指向原型,而不指向构造函数。

原型模式的优点:可以共享属性和方法

缺点:对于包含引用类型的属性,会导致所有的对象都发生变化

1.4 组合使用构造函数模式和原型模式

构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。最大限度地节省了内存,而且这种模式支持向构造函数传递参数。

function Person(name, age, job) {this.name = name;this.age = age;this.job = job;this.friends = ['111', '222']
}Person.prototype = {constructor: Person,sayName: function() {console.log(this.name)}
}var person1 = new Person('sy', 25, 'Software Engineer')
var person2 = new Person('sansa', 25, 'Doctor')person1.friends.push('333')console.log(person1.friends === person2.friends) // false

1.5 动态原型模式

为了将构造函数和原型封装,动态原型模式把所有信息都封装在了构造函数中。可以通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型。

function Person(name, age, job){// 属性this.name = name;this.age = age;this.job = job;// 方法if(typeof this.sayName != 'function'){Person.prototype.sayName = function() {console.log(this.name)}}}var friend = new Person('sy', 25, 'Software Engineer')
friend.sayName(); // sy

使用动态原型模式时,不能使用对象字面量重写原型。如果在已经创建了实例的情况下重写原型,那么就会切断现有实例与新原型之间的联系。

1.6 寄生构造函数模式

思想:创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象。

function Person(name, age, job){var o = new Object();o.name = name;o.age = age;o.job = job;o.sayName = function(){console.log(this.name);};return o;
}
var friend = new Person("Nicholas", 29, "Software Engineer");
friend.sayName();  //"Nicholas"    

1.7 稳妥构造函数模式

稳妥对象:指的是没有公共属性,而且其方法也不引用this的对象。

function Person(name, age, job){// 创建要返回的对象var o = new Object();// 可以在这里定义私有变量和函数// 添加方法o.sayName = function() {console.log(name)}// 返回对象return o;
}
var friend = new Person("Nicholas", 29, "Software Engineer");
friend.sayName();  //"Nicholas"    

转载于:https://www.cnblogs.com/songya/p/11488887.html

JS创建对象学习笔记相关推荐

  1. js/jquery学习笔记

    javascript简介 JavaScript是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言. 不同于服务器端脚本语言,例如PHP与ASP,JavaScript是客户端脚本语言,也就是说Ja ...

  2. 【带着canvas去流浪(11)】Three.js入门学习笔记

    [摘要] three.js 入门学习笔记 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 资料推荐及建议 1.官方文档 很详细,但是API部分单独 ...

  3. JS逆向学习笔记 - 持续更新中

    JS逆向学习笔记 寻找深圳爬虫工作,微信:cjh-18888 文章目录 JS逆向学习笔记 一. JS Hook 1. JS HOOK 原理和作用 原理:替换原来的方法. (好像写了句废话) 作用: 可 ...

  4. Node.js+mongodb 学习笔记(三)swagger注释+用户管理

    Node.js+mongodb 学习笔记(三)swagger注释+用户管理 Node.js+mongodb 学习笔记(三)swagger注释+用户管理 用户注册 用户登录 修改密码 swagger注释 ...

  5. 数据可视化清新版【chart.js】学习笔记8.0—极地图(Polar Area)

    Polar Area--(极地图) 极地面积图类似于饼图,但每个线段具有相同的角度 - 线段的半径因值而异.当我们想要显示类似于饼图的比较数据,同时也要显示上下文的值的范围时通常使用这种类型的图表. ...

  6. JS BOM 学习笔记

    2022年7月26日 周二学习笔记  学习时长:4h  学习进度:复习+ JS中的 BOM 目录 BOM 1.概述 1.1 什么是BOM 2. window对象的常见事件 2.1 窗口加载事件 2.2 ...

  7. Three.js入门学习笔记05:外部模型导入-C4D转成json文件供网页使用

    参考学习: https://www.jianshu.com/p/906072e60197 https://blog.csdn.net/qq_30100043/article/details/79606 ...

  8. JS高级学习笔记(6)- 事件循环

    参考文章:深入理解JS引擎的执行机制        JavaScript 异步.栈.事件循环.任务队列 我的笔记:ES系列之Promise async 和 await Event Loop 前提 js ...

  9. Three.js入门学习笔记12:模型沿着任意轨迹线运动

    参考学习 http://www.yanhuangxueyuan.com/doc/Three.js/curveRun.html http://www.yanhuangxueyuan.com/doc/th ...

最新文章

  1. python 条形图-python使用Plotly绘图工具绘制水平条形图
  2. JAVA抽象类为什么可以有构造_抽象类为什么可以有构造函数?- Constructor of an abstract class in C#(转载)...
  3. docker pull 下载一半_Docker 从入门到掉坑
  4. 【数据结构总结】第六章 图(非线性结构)
  5. [转]c++类的构造函数详解
  6. php下拉列表框 是隐藏变色的代码,jQuery设置下拉框显示与隐藏效果的方法分析...
  7. 谈谈运维监控那些事儿
  8. 进入第一个Android应用界面
  9. 深度学习笔记(三):激活函数和损失函数
  10. iconfont采坑
  11. 高校就业管理系统数据库设计
  12. 大数据处理技术,主要包括哪些基本技术?
  13. html制作钢铁侠心脏,钢铁侠的“心脏”并不是特效,得知如何制成的,网友:难以置信...
  14. 藤子不二雄博物馆之行
  15. 拉勾网职位数据爬取与分析(一)
  16. Android项目 生成签名证书指纹
  17. DeepSpectra: An end-to-end deep learning approach for quantitative spectral analysis翻译
  18. JVM中类装载的执行过程
  19. 数据降维(data dimension reduction)
  20. HTTP的通信过程及请求报文和响应报文(详解)

热门文章

  1. ASP.NET 2.0 – 善用DataSourceMode属性
  2. C语言 将字符串中数字字符全部删除
  3. MySQL数据库优化总结
  4. VS之设置文件编码格式
  5. Google Chrome调试js入门
  6. python学习笔记--easy_install和pip
  7. html5 canvas画进度条
  8. KVM 介绍(7):使用 libvirt 做 QEMU/KVM 快照和 Nova 实例的快照 (Nova Instances Snapshot Libvirt)...
  9. 【转】MySQL分库分表环境下全局ID生成方案
  10. devi into python 笔记(一)字典 列表的简单操作