[关闭]
@hotjp 2017-03-10T09:26:54.000000Z 字数 2323 阅读 1257

JavaScript面向对象编程

培训


之前有简单介绍过立即执行函数函数的闭包,简单的对象封装和js中面向对象的实现方式

这次集中横向介绍一下书写环节中对于以上内容的整合

工厂模式

工厂模式是面向对象编程的常见实现模式,用于生产对象和对象实例完成工作需要,减少对外部变量的依赖
之前说过,JavaScript中没有类可以用来实例化对象,所以采用函数返回对象的方式进行对象构建

  1. function createNinjia(name, weapon) {
  2. var o = {};
  3. o.name = name;
  4. o.weapon = weapon;
  5. o.sayHello = function() {
  6. console.log(name + '向你发射了一把' + weapon);
  7. }
  8. return o;
  9. }

等价于

  1. function createNinjia(name, weapon) {
  2. return {
  3. name: name,
  4. weapon: weapon,
  5. sayHello: function() {
  6. console.log(name + '向你发射了一把' + weapon);
  7. }
  8. }
  9. }

调用方式

  1. var ninjia = createNinjia('Mike', 'ak47')

但是

工厂模式生产的对象无法识别类型,不能判断生成的源

  1. ninjia // Object {}

构造函数

  1. function Ninjia(name, weapon) {
  2. this.name = name;
  3. this.weapon = weapon;
  4. this.sayHello = function() {
  5. console.log(this.name + '向你发射了一把' + this.weapon);
  6. }
  7. }

调用方式

  1. var ninjia = new Ninjia('Mike','AK48')

查看一下生成对象

  1. ninjia // Ninjia {}
  2. ninjia.constructor // 返回构造函数

构造函数的特性

函数名首写字母为大写
没有显式的创建对象
直接将属性和方法赋值给了this
没有return语句
使用new创建对象
能够识别对象(构造函数模式优于工厂模式的要点)

但是痛点也随之而来,每次构建的对象中有一个重复函数 sayHello
之前认真听原型部分的内容应该已经有完美的解决方案了,但是不要急,我们慢慢过渡

  1. function Ninjia(name, weapon) {
  2. this.name = name;
  3. this.weapon = weapon;
  4. this.sayHello = sayHello;
  5. }
  6. // ‘萃取’通用部分外置
  7. function sayHello() {
  8. console.log(this.name + '向你发射了一把' + this.weapon);
  9. }

缺点是?

原型

  1. function Ninjia() {
  2. }
  3. Ninjia.prototype.name = 'Mike';
  4. Ninjia.prototype.weapon = 'tutuGun';
  5. Ninjia.prototype.sayHello = function() {
  6. console.log(this.name + '向你发射了一把' + this.weapon);
  7. }

一个纯粹的原型函数进行声明之后,每次对原型的修改都会影响其他函数

  1. var ninjia = new Ninjia()

做一下优化

  1. function Ninjia(name,weapon) {
  2. }
  3. Ninjia.prototype.name = this.name;
  4. Ninjia.prototype.weapon = this.weapon;
  5. Ninjia.prototype.sayHello = function() {
  6. console.log(this.name + '向你发射了一把' + this.weapon);
  7. }

酱紫可以用么?

  1. var ninjia = new Ninjia('Mike','machine gun')

由此开始进入实际开发环节的书写推荐

混合模式(原型 + 构造函数)

  1. function Ninjia(name, size, weapon) {
  2. this.name = name;
  3. this.weapon = weapon;
  4. this.size = size;
  5. }
  6. Ninjia.prototype.sayHello = function() {
  7. console.log(this.name + '拿起了他' + this.size + '厘米的' + this.weapon + '冲你来了一发');
  8. }
  9. var ninjia1 = new Ninjia('Mike', '18','烧火棍'),
  10. ninjia2 = new Ninjia('Lilei', '5', '小手枪');

混合模式是适用最普遍最广泛的构建方式
具有构造函数的清晰对象结构
具有原型函数的优秀性能

你以为就到这了?

动态原型

  1. function Ninjia(name, size, weapon) {
  2. this.name = name;
  3. this.weapon = weapon;
  4. this.size = size;
  5. if(typeof this.sayHello != 'function'){
  6. console.log('动态初始化原型函数');
  7. Ninjia.prototype.sayHello = function() {
  8. //this.prototype.sayHello = function() {
  9. console.log(this.name + '拿起了他帅气的' + this.size + '厘米的' + this.weapon + '冲你来了一发');
  10. }
  11. }
  12. }
  1. var ninjia1 = new Ninjia('Mike', '18','烧火棍'),
  2. ninjia2 = new Ninjia('Lilei', '5', '小手枪');

问题:
声明原型的时候为什么不能用this?
这样写的优势在哪?

随堂附送 《JavaScript高级程序设计》电子版,
也是本文的参考资料,喜欢看纸质书的也可以找我借阅

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注