JS 基础 - 面向对象编程

参考阅读:

  1. 程序员也不知道什么是面向对象

  2. MDN 给了我们一堆术语

请尝试理解面向对象,并背诵 MDN 里的以下内容

Class 类

​ 定义对象的特征。它是对象的属性和方法的模板定义.

Object 对象

​ 类的一个实例。

Property 属性

​ 对象的特征,比如颜色。

Method 方法

​ 对象的能力,比如行走。

Constructor 构造函数

​ 对象初始化的瞬间, 被调用的方法. 通常它的名字与包含它的类一致.

Inheritance 继承

​ 一个类可以继承另一个类的特征。

Encapsulation 封装

​ 一种把数据和相关的方法绑定在一起使用的方法.

Abstraction 抽象

​ 结合复杂的继承,方法,属性的对象能够模拟现实的模型。

Polymorphism 多态

​ 多意为‘许多’,态意为‘形态’。不同类可以定义相同的方法或属性。

封装 Model View Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* 
Controller({
init:(){
this.view
this.model
this.xxx()
this.yyy()
},
xxx(){}
yyy(){}
})
*/
window.Controller = function(options){
var init = options.init // B

let object = {
view: null,
model: null,
init: function(view, model){ // A
this.view = view
this.model = model
this.model.init()
init.call(this, view, model) // 这是哪个 init
this.bindEvents.call(this)
},
}
for(let key in options){
if(key !== 'init'){
object[key] = options[key]
}
}
return object
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
var model = Model({
resourceName: '表名'
})
*/
window.Model = function(options){
let resourceName = options.resourceName
return {
init: function(){
var APP_ID = 'TsDnap9SEXjSvGSowP7gXXJC-gzGzoHsz'
var APP_KEY = 'rGye31p12mM3wFpNRn9RADu9'
AV.init({ appId: APP_ID, appKey: APP_KEY })
},
fetch: function(){
var query = new AV.Query(resourceName);
return query.find() // Promise 对象
},
save: function(object){
var X = AV.Object.extend(resourceName);
var x = new X();
return x.save(object)
}
}
}
1
2
3
4
5
6
/*
var view = View('.xxx')
*/
window.View = function(selector){
return document.querySelector(selector)
}
  1. controller === object

  2. controller.init(view, model)
    controller.init.call(controller, view, model)
    那么 controller.init 里面的 this 当然 TM 是 controller
    也就是这个1里面的object
    controller.init 里面的 this 就是 object
    object.init 里面的 this 就是 object

  3. initB.call(this)

    initB 里面的 this === call 后面的this
    call 后面 this === 第二条里的 this
    第二条里面的 this === object
    => initB 里面的 this 就是 object

this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
button.onclick = function f1(){
console.log(this) // 触发事件的元素。 button
}

button.onclick.call({name: 'frank'})


button.addEventListener('click', function(){
console.log(this) // 该元素的引用 button
}


2 结果

$('ul').on('click', 'li' /*selector*/, function(){
console.log(this) //this 则代表了与 selector 相匹配的元素。
// li 元素
})


3 结果
去看 on 的源码呀 -> 做不到
jQuery 的开发者知道 onclick 的源码,f1.call(???)
jQuery 的开发者写了文档
看文档呀

function X(){
return object = {
name: 'object',
options: null,
f1(x){
this.options = x
this.f2()
},
f2(){
this.options.f2.call(this)
}
}
}


var options = {
name: 'options',
f1(){},
f2(){
console.log(this) // this 是啥 ?
}
}

var x = X()

x.f1(options)

new 的作用

  1. 不用创建临时对象,因为 new 会帮你做(你使用「this」就可以访问到临时对象);
  2. 不用绑定原型,因为 new 会帮你做(new 为了知道原型在哪,所以指定原型的名字为 prototype);
  3. 不用 return 临时对象,因为 new 会帮你做;
  4. 不要给原型想名字了,因为 new 指定名字为 prototype。

https://zhuanlan.zhihu.com/p/23987456

var object = new Object()

自有属性 空
object.*proto* === Object.prototype

var array = new Array(‘a’,’b’,’c’)

自有属性 0:’a’ 1:’b’ 2:’c’,length:3
array.*proto* === Array.prototype
Array.prototype.*proto* === Object.prototype

var fn = new Function(‘x’, ‘y’, ‘return x+y’)
自有属性 length:2, 不可见的函数体: ‘return x+y’
fn.*proto* === Function.prototype

Array is a function
Array = function(){…}
Array.*proto* === Function.prototype

编辑