面向对象 part5
构造函数模式与原型模式结合
function Person(name) = {
this.name = name
this.friends = ["a", "b"]
} person.prototype = {
constructor: Person,
sayName: function() {
alert("this.name")
}
} var p1 = new Person("hi")
但是这很让人困惑。因为构造函数和原型模式单独书写。不符合面向对象的封装。
//因为构造函数会初始化原型,所以原型模式不能书写到构造函数中,因为这样每创建一次实例都会重新定义一下原型函数
解决方案 动态原型模式
所有的都封装在构造函数中,通过在构造函数中初始化原型(仅在必要的时候。就是可以添加一个判断)
function Person(name) = {
//属性
this.name = name
this.friends = ["a", "b"]
//方法
if (typeof this.sayName != "function") {
person.prototype.sayName =function() {
alert(this.name);
}
}
} var p1 = new Person("hi")
这段代码只会在初次调用构造函数的时候才会执行,此后原型已经完成了初始化。这里在原型中做的修改,能够立即体现在所有的实例中。
原型的动态性:我们对原型对象所做的任何修改,都能够立即从实例上反应出来
寄生构造函数(一个特殊的用法)
- 特殊的情况为对象创建构造函数。假设在不修改Array构造函数的前提下,创建一个具有额外方法的特殊数组
- 返回的对象与构造函数活着构造函数的原型没有任何关系
- 构造函数在不返回值的情况下,会默认返回新对象实例。如果又一个return,就重写构造函数的返回值
总结
function SpecialArray(){
//创建数组
var vlaues = new Array();
//添加值
vlaues.push.apply(values, arguments);
//添加方法
values.toPipedString = function(){
return this.join("|");
};
//返回数组
return values;
} var colors = new SpecialArray("red", "blue", "green");
alert(colors.toPipedString()); //"red|blue|green"
寄生构造函数模式的目的是实现在不改变原有构造函数的前提下为构造函数添加特殊的方法,这个构造函数的功能就是传入参数,生成一个数组对象,并且这个数组自带SpetialArray方法,而且返回的对象跟构造函数和构造函数的原型对象没有什么关系;
这里演示的是附带special方法, 下次附带数组不具有的方法呢?所以不必纠结join;
为什么没有使用原型方法,开篇就提到了,不改变原有构造函数的前提下,添加新方法,你修改了Array的prototype,所有Array实例都会继承这样一个方法,得不偿失;
比如遇到某个场景:你想创建一个字符串,String字符串自带某种方法可以返回一段复合要求的字符串,你不能直接在String原型上定义该方法,因为这样所有的字符串都会继承这个方法没有必要,但是你又不想每次都调用封装的函数,寄生构造函数就能派上用场了,在创建对象的时候就给这个字符串赋予了你需要调用的方法,同时有不影响String这个全局构造函数
是这样的,Array想要把argements全部push的话,必须要遍历arguments,arguments只是类似数组,但事实上是一个对象,所以push arguments返回的是一个包含单个对象的长度为1的数组,apply把数组的push方法施加到一个数组上,接收的第二个参数是一个数组,所以直接跳过遍历,一次性全部push了
寄生构造函数专门用来为js原生的构造函数定义新的方法
function SpecialArray(){
var values = new Array();
values.push.apply(values, arguments);
values.toPipedString = function(){
return this.join("|");
}
return values;
}
var a = new SpecialArray(2,6,8,9,4);
a.toPipedString();
var b = SpecialArray(2,6,8,9,4);
b.toPipedString();
寄生构造函数模式和工厂模式没有本质区别,通过new 操作符的就叫寄生构造函数模式,直接调用的就叫工厂模式
JS里的构造函数就是一个用来构造对象的普通函数,和JAVA不同
你要知道,通过new 来调用函数,会自动执行下面操作
创建一个全新的对象
这个对象会被执行[[prototype]]连接原型
函数调用中的this会绑定到新对象
如果函数没有返回其他对象,那么new 构造就会自动返回这个新对象
由于这里new调用和直接调用都返回values,所以a,b引用的数组对象是一样的
面向对象 part5的更多相关文章
- Java实例 Part5:面向对象入门
目录 Part5:面向对象入门 Example01:成员变量的初始化值 Example02:单例模式的应用 -----懒汉式 -----饿汉式 Example03:汉诺塔问题的求解 Example04 ...
- day 25 面向对象之接口、抽象类、多态、异常处理、反射、断言
复习 '''继承1.父类:在类后()中写父类们class A:passclass B:passclass C(A, B):pass2.属性查找顺序:自己 -> ()左侧的父类 -> 依 ...
- python基础——18(面向对象2+异常处理)
一.组合 自定义类的对象作为另一个类的属性. class Teacher: def __init__(self,name,age): self.name = name self.age = age t ...
- python语言(七)面向对象、异常处理
一.异常处理 python解释器检测到错误,触发异常(也允许程序员自己触发异常).程序员编写特定的代码,专门用来捕捉这个异常(这段代码与程序逻辑无关,与异常处理有关).如果捕捉成功则进入另外一个处理分 ...
- angular2系列教程(六)两种pipe:函数式编程与面向对象编程
今天,我们要讲的是angualr2的pipe这个知识点. 例子
- 一起学 Java(二)面向对象
一.方法函数 函数也称为方法,就是定义在类中的具有特定功能的一段独立代码.用于定义功能,提高代码的复用性. 函数的特点1> 定义函数可以将功能代码进行封装,便于对该功能进行复用:2> 函数 ...
- js面向对象学习 - 对象概念及创建对象
原文地址:js面向对象学习笔记 一.对象概念 对象是什么?对象是“无序属性的集合,其属性可以包括基本值,对象或者函数”.也就是一组名值对的无序集合. 对象的特性(不可直接访问),也就是属性包含两种,数 ...
- 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型
前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...
- .NET 基础 一步步 一幕幕[面向对象之对象和类]
对象和类 本篇正式进入面向对象的知识点简述: 何为对象,佛曰:一花一世界,一木一浮生,一草一天堂,一叶一如来,一砂一极乐,一方一净土,一笑一尘缘,一念一清静.可见"万物皆对象". ...
随机推荐
- Django static配置
STATIC_URL = '/static/' # HTML中使用的静态文件夹前缀 STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static&q ...
- 使用jackson转换类型时报Unrecognized field
调用 objectMapper.convertValue(obj, valueType ); 时报错 原因 obj 的属性多于 valueType 导致,添加一条语句即可 objectMapper.c ...
- softmax、交叉熵
Softmax是用于分类过程,用来实现多分类的 它把一些输出的神经元映射到(0-1)之间的实数,并且归一化保证和为1,从而使得多分类的概率之和也刚好为1. Softmax可以分为soft和max,ma ...
- 使用FragmentStatePagerAdapter时发现的内存泄露问题
这篇文章想说的并非是由于使用 FragmentStatePagerAdapter 而导致的内存泄漏,内存泄漏的真正原因和 FragmentStaePagerAdapter 并无直接关联,但是使用 Fr ...
- 线性数据结构案例1 —— 单向链表中获取倒数k个节点
一.介绍 先遍历整个链表获取链表长度length,然后通过 (length-index) 方式得到我们想要节点在链表中的位置. 二.代码 public Node findLastIndexNode( ...
- jQuery下拉框联动(JQ遍历&JQ中DOM操作)
1.下载jQuery,并导入:https://blog.csdn.net/weixin_44718300/article/details/88746796 2.代码实现: <!DOCTYPE h ...
- Python风格规范分享
今天给大家分享Python 风格规范,以下代码中 Yes 表示推荐,No 表示不推荐. 分号 不要在行尾加分号, 也不要用分号将两条命令放在同一行. 行长度 每行不超过80个字符 以下情况除外: 长的 ...
- 吴裕雄--天生自然Django框架开发笔记:Django 模型
Django 对各种数据库提供了很好的支持,包括:PostgreSQL.MySQL.SQLite.Oracle. Django 为这些数据库提供了统一的调用API. 可以根据自己业务需求选择不同的数据 ...
- 使用Spring Data Mongodb的MongoRepository类进行增删改查
Spring Data Mongodb提供一套快捷操作 mongodb的方法,创建Dao,继承MongoRepository,并指定实体类型和主键类型. public interface CmsPag ...
- Java基础之IO流整理
Java基础之IO流 Java IO流使用装饰器设计模式,因此如果不能理清其中的关系的话很容易把各种流搞混,此文将简单的几个流进行梳理,后序遇见新的流会继续更新(本文下方还附有xmind文件链接) 抽 ...