【JavaScript 学习笔记】创建对象
2019独角兽企业重金招聘Python工程师标准>>>
因为最近一直在读《JavaScript高级程序设计》,深感从前对JavaScript的了解实在过于肤浅,所以打算顺手做些摘抄笔记,总结一下,给自己做个备忘。
在JavaScript里创建对象总共有以下几种实现方式:
工厂模式 构造函数模式 原型模式 原型和构造函数的混合模式 动态原型模式 寄生构造函数模式 稳妥构造函数模式
下面对以上诸方式举例说明:
1. 工厂模式
最简单的模式,直接看例子即可:
1: function createPerson(name, age, job){
2: var o = {};
3: o.name = name;
4: o.age = age;
5: o.job = job;
6: return o;
7: }
8: var p = createPerson("Bob", 22, "spy");
缺点:该方法的缺憾是类似对象的识别问题, 无法准确判断两个object实例是否是同一类型。
2. 构造函数模式
1: function Person(name age, job){
2: this.name = name;
3: this.age = age;
4: this.job = job;
5: this.sayName = function(){
6: alert(this.name);
7: }
8: }
9: var p1 = new Person("Bob", 22, "Spy");
10: var p2 = new Person("Mike", 25, "Engineer")
在使用这种模式创建对象时,其实主要有以下几个步骤:
创建一个对象; 将构造函数的作用域绑定为这个对象,也就是说构造函数的this其实就指向新创建的这个对象; 执行构造函数,返回这个新的对象
优点:可以用 instanceof 标识对象的类型, 如上面的 p1,p2 在 instanceof Person时都可以返回true值
缺点:每个实例上都定义了sayName方法,不够环保,而且不同实例上的同名函数(这里是sayName)是不相等的。
3. 原型模式
1: function Person(){
2: }
3: Person.prototype.name = "Bob";
4: Person.prototype.age = 22;
5: Person.prototype.job = "Spy";
6: Person.prototype.sayName = function(){
7: alert(this.name)
8: };
9:
10: var p1 = new Person();
11: p1.sayName();// "Bob"
12: var p2 = new Person();
13: p2.sayName();//"Bob"
4.原型和构造函数的混合模式
1: function Person(name, age, job){
2: this.name = name;
3: this.age = age;
4: this.job = job;
5: }
6: Person.prototype.sayName = function(){
7: alert(this.name);
8: }
9:
10: var p1 = new Person("Bob", 22, "Spy");
11: var p2 = new Person("Mike", 24, "Engineer");
把实例属性定义在构造函数中,把共享的方法定义在prototype中,是ECMAScript中使用最广泛,认同度最高的一种创建自定义类型的方法。
5. 动态原型模式
习惯了其他语言面向对象的编程人员,在看到JavaScript里采用上面的模式定义对象是可能会感到困惑,为什么要在两个地方去定义一个类型呢?于是就诞生了动态原型模式,如下
1: function Person(name, age, job){
2: this.name = name;
3: this.age = age;
4: this.job = job;
5: if(typeof this.sayName != "function"){
6: Person.prototype.sayName = function(){
7: alert(this.name);
8: }
9: }
10: }
11:
12: var p1 = new Person("Bob", 22, "Spy");
所以说,动态原型模式 跟 原型和构造函数的混合模式 并没有本质上的不同,仅仅是动态原型模式会在第一次调用构造函数是才会在原型上定义共享的方法。
6. 寄生构造函数模式
1: function Person(name, age, job){
2: var o = new Object();
3: o.name = name;
4: o.age = age;
5: o.job = job;
6: o.sayName = function(){
7: alert(this.name);
8: }
9: }
10: var p = new Person("Bob", 22, "Spy");
除了使用了new操作符,这个方式跟工厂模式并无很大差别。在上面的构造函数模式里曾经说过,当采用 new Person() 时,会先创建一个新的对象实例,再去绑定调用构造函数云云,这里应该把返回值这部分补全一下,当构造函数没有返回值时,就默认返回了第一步创建的那个新对象实例,但是如果构造函数里有return语句,并且返回了一个object,那么最终的返回结果就是这个在构造函数里创建的object,而不是最初创建的那个新对象实例。(这里必须要保证构造函数内部返回值是object,如果是数字,字符串等基本型,是无法覆盖在第一步创建的对象实例的,这个是我自己试验的 )。
这里还有一点需要注意的就是由构造函数内部返回出来的这个object,它的原型和Person的prototype是没有关系的,其实在Chrome里不妨试一试,当使用构造函数模式创建了一个对象实例后,输出这个实例所得结果如下
Person {name: "Bob", age: 22, job: "Spy", … }
但是如果用寄生构造函数创建一个对象实例,输出该实例所得结果如下
Object {name: "Bob", age: 22, job: "Spy", …}
所以,使用该模式创建的实例与使用工厂模式创建的实例一样,没法使用 instanceof 来判断类型。
关于这个寄生构造函数模式使用的场合,一般是想在某种已有类型的基础上添加方法等,但是又不方便直接去修改已有类型的构造函数,这时候,寄生构造函数模式就比较适合了,下面是个例子
1: function SpecialArray(){
2: var values = new Array();
3: values.push.apply(values, argumeents);
4: values.toPipedString = function(){
5: return this.join("|");
6: }
7: return values;
8: }
9: var arr = new SpecialArray("Tiger", "Lion", "Dog");
这里就在Array的基础上定义了SpecialArray,初始化数组,并添加了新的方法toPipedString。
7. 稳妥构造函数模式
先来看看实例,再来说说这种模式有什么特点吧
1: function Person(name){
2: var o = new Object();
3: o.sayName = function(){
4: alert(name);
5: };
6: return o;
7: }
8:
9: var p = Person("Bob");
- 创建的对象实例没有公共属性
- 方法中不使用this
其实满足了以上条件的对象就叫做稳妥对象,稳妥对象适合在一些安全环境中使用,这些环境中,会禁止使用 new 和 this , 或者防止数据被其他应用改动,从示例中可以看到,除了sayName, 外界是无法访问 name 的,(这里用了一个闭包)。
哦,暂时就到这里吧,实在有些困了,如果示例代码里有小毛病,还请多包涵。
转载于:https://my.oschina.net/himerlin/blog/136889
【JavaScript 学习笔记】创建对象相关推荐
- JavaScript学习笔记(一)-Learning Advanced JavaScript
JavaScript学习笔记 (一)- Learning Advanced JavaScript Learning Advanced JavaScript #2: Goal: To be able t ...
- JavaScript学习笔记03-数组-Data对象-Math对象-包装类-字符串-正则
目录 一.数组 索引 数组的特点 1.1.数组的创建 1.1.1.使用new关键字(构造函数) 1.1.2.使用字面量形式 1.1.3.创建数组的注意事项 1.2.数组的基本使用 1.2.1.存操作( ...
- JavaScript学习笔记(第二部分)总共四部分
JavaScript学习笔记(第二部分)总共四部分 4 对象(Object) 字符串String.数值Number.布尔值Boolean.空值Null.未定义Undefined是基本的数据类型,这些数 ...
- JavaScript学习笔记(四)---闭包、递归、柯里化函数、继承、深浅拷贝、设计模式
JavaScript学习笔记(四)---闭包.递归.柯里化函数.继承.深浅拷贝.设计模式 1. 匿名函数的使用场景 2.自运行 3.闭包 3.1前提: 3.2闭包 4.函数对象的三种定义方式 5.th ...
- JavaScript学习笔记一
JavaScript学习笔记 1. 介绍 2. 基础语法 输入输出 变量 数据类型 简单数据类型 复杂数据类型 类型转换 3. 运算 算术运算符 递增递减运算符 比较运算符 逻辑运算符 赋值运算符 运 ...
- 千锋JavaScript学习笔记
千锋JavaScript学习笔记 文章目录 千锋JavaScript学习笔记 写在前面 1. JS基础 1.1 变量 1.2 数据类型 1.3 数据类型转换 1.4 运算符 1.5 条件 1.6 循环 ...
- JavaScript学习笔记之对象及继承
JavaScript学习笔记之对象及继承 对象属性 ES5中有两种属性,数据属性和访问器属性. 数据属性包括[[writable]](能否修改属性的值).[[value]]等等: 访问器属性包括[[C ...
- Java程序猿的JavaScript学习笔记(12——jQuery-扩展选择器)
计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...
- Java程序猿的JavaScript学习笔记(汇总文件夹)
最终完结了,历时半个月. 内容包含: JavaScript面向对象特性分析,JavaScript高手必经之路. jQuery源代码级解析. jQuery EasyUI源代码级解析. Java程序猿的J ...
- JavaScript学习笔记(五)
JavaScript学习笔记(五) ①Array类 本地对象 ②Date类 ①Global对象 对象的类型 内置对象 ②Math对象 宿主对象 今天继续学习JS中的对象,昨天内置对象Global对 ...
最新文章
- 数据蒋堂 | 性能优化是个手艺活
- final关键字细节
- java param request_使用@RequestParam将请求参数绑定至方法参数
- mysql password no_mysql 连接问题(using password: NO)
- idea中拉取项目时 没有文件_idea编译器中maven项目获取路径的方法
- 泉州海事学校计算机,泉州海事学校寝室图片、校园环境好吗?
- Java中对象的深复制(深克隆)和浅复制(浅克隆)介绍
- .Net Pet Shop 4 初探之一:初识PetShop4
- 《GO语言实战》笔记
- 机器学习 —— 联合概率分布
- 北大AI讲座公开课-精华
- 苹果退款_教程:在 iTunes 申请 App Store 退款
- Vue基础语法之@click、时间修饰符@click.stop与@click.prevent、按键修饰符(如@keyup.enter)
- 去银行当程序员是一种什么体验
- ks live room danmu
- 考研计算机专业课408,【21计算机考研】专业课统考408院校汇总
- pytorch dataset自定义_PyTorch 系列 | 数据加载和预处理教程
- ​川希:互联网创业赚钱就是抄抄抄,越抄越赚钱!
- 使用wordpress建立企业或博客网站新手教程
- MyBatisPlus代码生成器使用