面向对象

面向对象的初心

  1. 改善可读性
  2. 提升重用性

原则:开放封闭原则

  1. 对于扩展是开放的(Open for extension)。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。
  2. 对于修改是关闭的(Closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。

目的

三要素:封装、继承、多态

类:上帝创造万物

面向对象可以解释任何事物(哲学?)

生命

p: body

m: born

m: die

动物

m: run

植物

m: 光合作用

m: 上树

m: say

狐狸

m: 成仙

m: say

m: say

编程的时候你就是上帝

Object

p: __proto__

m: toString

m: valueOf

Array

p: length

Function

p: length

m: push

m: call

对象:将类实例化

var object = new Object()

类是图纸

将图纸实现(实例化、放入内存)就是对象

var image = new Image()

var cat = new Cat()

想象上帝创造猫这个类,然后创造一个猫的实例。

小结

  • 类可以继承类(父类与子类)
  • 将类实例化,就有了对象
  • 对象拥有类的属性和方法、父类的属性和方法、父类的父类……
  • 将一些属性和方法封装为类
  • 多态:不同对象的同一个方法,可以有不同的表现

JavaScript 使用原型链实现继承

Java 使用  实现继承

JavaScript 可以模拟 Java 的继承(部分)

class 以前是 JavaScript 的保留字,现在已经是关键字了

预备知识 - new 操作

var object = new Object() 时,发生了什么?

  1. 创建一个空对象作为 this
  2. this.__proto__ 指向构造函数的 prototype
  3. 运行构造函数
  4. 返回 this(如果构造函数没有 return)

预备知识 - this

this 的值到底是什么?

  1. 默认情况下,this === window(node 里另说,strict mode 另说)
  2. 使用 func.call(context, param1) 的第一个参数指定 this
  3. object.method(param1) 可以指定 method 的 this 为 object
    1. 相当于 object.method.call(object, param1)

this 的值在函数执行时才能确定

注意区别:变量在定义时就确定

P.S.

  1. func.call 和 func.apply 的区别
  2. func.bind(context) 的作用

如何确定 this 的值:

如何手动指定对象的原型

1. object.__proto__ = { ... }

ECMAScript 6 之前没有涉及过 __proto__,只是由于浏览器都实现了 __proto__,ECMAScript 才将 __proto__ 加入到 Specs

2. 借用 new

var myProto = {
    name: 'foo'
}

var obj = {}

var Temp = function(){}
Temp.prototype = myProto
obj = new Temp()

3. 使用 Object.create(proto)  MDN

JS实现一个构造函数

对应 Java 里面的『类』

var Animal = function(){
    this.种类 = '动物'
}

Animal.prototype.say = function(){
    console.log(this.种类 + '叫')
}

实例化,得到一个对象

var animal = new Animal()

animal.say()

JS继承一个类

var Cat = function(){
    Animal.apply(this, arguments)
    this.tail = '一条尾巴'
}

// 下面三句话只是为了实现 Cat.prototype.__proto__ = Animal.prototype
var F = function(){};
F.prototype = Animal.prototype;
Cat.prototype = new F();

// 纠正一下 constructor
Cat.prototype.constructor = Cat;

Cat.prototype.run = function(){
    console.log('猫儿在跑')
}

Cat.prototype.say = function(){
    console.log('喵喵喵')
}
var cat = new Cat()

cat.say()

不用类也能实现继承

var animal =  {
    '种类':'动物',
    say: function(){
        console.log('动物叫')
    }
}



var cat = Object.create(animal) // 使用任意手段让 cat.__proto__ === animal

cat.tail = '' 
cat.say= function(){
        console.log('喵喵喵')
    }

JS 里面没有事件

区别于 DOM 事件

JS里的事件有什么用?

举例:不同代码块间的通信

数据已更新!

Text

保存

Text

保存

Text

保存

Text

保存

RSS 订阅

用一个例子说明发布订阅模式(观察者模式)

  1. 读者可以订阅一个博客的 RSS
  2. 读者可以取消订阅
  3. 一旦 RSS 更新,读者就会收到提示
  4. 博客作者可以触发 RSS 更新

一个事件系统长什么样子

  1. eventSystem.on('xxx', fooFunction)
  2. eventSystem.trigger('xxx', data)
  3. eventSystem.off('xxx', fooFunction)
// 用户提交数据完毕后提示用户
// main.js
!(function(){
    var notify = function(message){
        alert(message)
    }

    eventSystem.on('submitSuccess', function(message){
        notify(message)
    })

})()

// a.js
$.post(urlA, function(){
    eventSystem.trigger('submitSuccess', '数据A已更新')
})

// b.js
$.post(urlB, function(){
    eventSystem.trigger('submitSuccess', '数据B已更新')
})

// c.js
$.post(urlC, function(){
    eventSystem.trigger('submitSuccess', '数据C已更新')
})

// foo.js
!(function(){

    eventSystem.on('submitSuccess', function(message){
        // 做其他事情
    })

})()

世上最小的发布订阅系统

(function($) {

  var o = $({});

  $.on = function() {
    o.on.apply(o, arguments);
  };

  $.off = function() {
    o.off.apply(o, arguments);
  };

  $.trigger = function() {
    o.trigger.apply(o, arguments);
  };

}(jQuery));

这样的设计用于模块间通信非常方便,所以程序员给它起来一个名字:

发布/订阅模式

被起了名字的常用设计,就叫做设计模式

下一课:一些框架的介绍

下下课:写简历与面试的技巧

找工作的同学可以找老师模拟面试(多次)

1. 给我简历

2. 告诉我你的目标职位

3. 约时间模拟面试

面向对象

By 方方

面向对象

  • 1,907