面向对象,即 OO(Object Oriented)
理解面向对象
面向对象有如下的概念
- Class 类
定义对象的特征,它是对象的属性和方法的模板定义 - Object 对象
类的一个实例 - Property 属性
对象的特征,比如颜色 - Method 方法
对象的能力,比如行走 - Constructor 构造函数
函数初始化瞬间被调用,通常它的名字与包含它的类名相同 - Inheritance 继承
一个类可以继承另一个类的特征 - Encapsulation 封装
一种把数据和方法绑定在一起使用的方式 - Abstraction 抽象
结合复杂的继承、方法、属性的对象能够模拟现实的模型 - Polymophsim 多态
‘许多形态’, 表示不同的类可以定义相同的方法和属性
命名空间
如下代码var MYAPP = MYAPP || {};
这段代码是什么意思,为何一个变量的定义要用它自身来与上一个对象?这里就牵扯到 JS 的 5 个 ‘falsy’ 值,即
- NaN、0
- ‘’(空字符串)
- false
- null
- undefined
在 JS 中,&&
与 ||
符号是这样使用的
对于
&&
来说,它会从左往右一直寻找一个 ‘falsy’ 值,找到之后直接返回这个 ‘falsy’ 值,剩下的就不管它1 && 0 // 0
1 && 0 && 2 && 3 // 0
1 && console.log(3) // undefined, 因为 console.log() 的返回值就是 undefined对于
||
来说,它会从左往右一直寻找一个非 ‘falsy’ 值,找到之后直接返回这个 ‘falsy’ 值,剩下的就不管它0 || 1 // 1
1 || 0 || 2 || 3 // 1
0 || undefined || null || 1 // 1
这其实很好理解,对于 &&
,只要其中条件有一个不成立(falsy)就全不成立; 而对于 ||
,只要其中条件有一个成立(trusy)就全成立。于是浏览器就根据符号找到相应的值就返回。
上面说到的代码就相当于if (MYAPP) {
; // 不做
} else {
MYAPP = {}; // 等于一个对象
}
再来谈下 this
有如下代码button.onclick = function() {
console.log(this);
}
button.addEventListener('click', function() {
console.log(this);
});
// jQuery
$('ul').on('click', 'li', function() {
console.log(this);
})
代码中的 this
是什么,前两个中的 this
在 MDN 的文档中表示是 “触发事件的元素”,亦即 button
,后一个在 jQuery 的文档中表示是 “与 Selector 相匹配的元素” ,亦即 li
但是,有一种特殊情况如下button.onclick = function() {
console.log(this);
}
button.onclick.call({name: 'frank'});
那么这个时候 this
是什么,就是 call 后面传的第一个参数,亦即 {name: 'frank'}
这个对象
还有一个例子function X() {
return object = {
name: 'object',
options: null,
f1(x) {
this.options = x;
this.f2();
},
f2() {
this.options.f2.call(this); // 这里的 this 都是指向 object
}
}
}
var options = {
name: 'options',
f1() {},
f2() {
console.log(this);
}
};
var x = X();
x.f1(options);
以上最终代码打印的是 object
这个对象
new 这个关键字
假设有一个 person 对象,它的实现是这样function person(options) {
this.name = options.name;
this.age = options.age;
}
person.prototype = {
getAge: function() {
return this.age;
},
}
我们知道,我们在 new 一个对象的时候,时常会这么做let frank = new person({
name: 'frank',
age: 18
});
然后调用它的函数frank.getAge(); // 18
但是你有没有想过,如果我不用 new 和 this 呢? 我该怎么做?
不用 new 以及 this 的情况下,你可以这样写代码function person(options) {
let temp = {};
temp.name = options.name;
temp.age = options.age;
// 这句话很重要,如果不指向就调用不到 getAge
temp.__proto__ = person.prototype;
return temp;
}
person.prototype = {
getAge: function() {
return this.age;
},
}
然后你才可以这样使用let frank = person({
name: 'frank',
age: 18
});
frank.getAge(); // 18
由以上我们可以看到,我们是不是省略了一些代码?我们省略的是哪些代码呢?
用了 new 之后
- 我们不用分配一个临时对象了, JS 帮我们创建了这个临时对象
- 我们不用 return 这个临时对象了,JS 帮我们 return
- 我们不用指向自己定义的对象的原型(prototype)了, JS 帮我们自己指向
- 因为指向原型的关系,所以我们用 this 就可以访问到这个临时变量
换言之, 我们终于可以不用那么费劲心思的去定义一个对象,new 都帮我们弄好了
以下是使用 new 的时候的一些注意点
var object = new Object() |