面向对象 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引用的数组对象是一样的
最新文章
- 如何快速清除ZBrush画布中多余图像
- hosts 文件妙用
- JS-确认框
- 天气api
- 异步加载js
- *nix高手站点
- CGI初识
- Catch That Cow(BFS)
- PHP 1:在Windows上安装和配置PHP,Apache和My SQL
- WP 开发中.xaml 与.xaml.cs
- linux虚拟机正常安装完成后获取不到IP的解决办法
- MIT 计算机科学及编程导论 Python 笔记 1
- pc端,移动端css重置样式
- px2rem
- Android 开发笔记
- 涂抹mysql笔记-mysql复制特性
- 书法字帖 PDF转化为可打印PDF
- 开发JAVA9以上的项目时,出现ClassNotFoundException: javax.xml.bind.JAXBException的解决方法
- 2018/03/09 每日一学PHP 之 require_once require include include_once 包含文件的区别
- ZOJ 3869 Ace of Aces
热门文章
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-qrcode
- C# Stream篇(四) -- FileStream
- VM虚拟机安装 常用Linux命令 网卡配置 (第二天)
- CCCC L3-015. 球队“食物链”(dfs+剪枝)
- POJ 1584:A Round Peg in a Ground Hole
- Spark-大数据计算引擎
- 原子类型字段更新器AtomicXxxxFieldUpdater
- python 奇淫技巧之自动登录 哔哩哔哩
- LICEcap--一款录屏生成Gif的软件
- 【转】modelBuilder.Configurations.AddFromAssembly in EF Core