1 、OOP的基础问题html
1.1什么是面向过程和面向对象?面试
面向过程:专一于如何去解决一个问题的过程步骤。编程特色是由一个个的函数去实现每一步的过程步骤,没有类和对象的概念。编程
面向对象:专一于由哪个对象来解决这个问题。编程特色是出现了一个个的类,从类中拿到这个对象,由这个对象去解决具体的问题。数组
对于调用者来讲,面向过程须要调用者本身去实现各类函数。而面向对象,只须要告诉调用者对象中具体方法的功能,而不须要调用者了解方法中的实现细节。函数
1.2面向对象的三大特征this
继承、封装、多态url
1.3类和对象的关系spa
① 类:一类具备相同特征(属性)和行为(方法)的集合。.net
好比:人类-->属性:身高、体重、性别 方法:吃饭、说话、走路code
② 对象:从类中,拿出具备肯定属性值和方法的个体。
好比:张三-->属性:身高180、体重180 方法:说话-->我叫张三,身高180
③ 类和对象的关系
类是抽象的,对象是具体的(类是对象的抽象化,对象是类的具体化)
解释一下:
类是一个抽象的概念,只能说类有属性和方法,可是不能给属性赋具体的值。好比说人类有姓名,可是不能说人类的姓名叫啥。。。
对象是一个具体的个例,是将类中的属性进行具体赋值而来的个体。好比说张三是人类的一个个体,能够说张三的姓名叫张三。也就是张三对人类的每个属性进行了具体的赋值,那么张三就是由人类产生的一个对象。
二、 JavaScript中的面向对象
2.1建立类和对象的步骤
①建立一个类(构造函数):类名必须使用大驼峰法则,即每一个单词的首字母必须大写。
1
2
3
4
5
6
|
function 类名(属性1){
this.属性1 = 属性1;
this.方法 = function(){
//方法中要调用自身属性,必需要使用this.属性
}
}
|
②经过类,实例化(new)出一个对象。
var obj = new 类名(属性1的具体值);
obj.属性; 调用属性
obj.方法(); 调用方法
③注意事项
>>>经过类名,new出一个对象的过程,叫作“类的实例化”
>>>类中的this,会在实例化的时候,指向新new出的对象。因此,this.属性 this.方法,其实是将属性和方法绑定在即将new出的对象上面。
>>>在类中,要调用自身属性,必须使用this.属性名、若是直接使用变量名,则没法访问对应的属性。
>>>类名必须使用大驼峰法则,注意与普通函数的区别。
2.2两个重要属性constructor和instanceof
①constructor:返回当前对象的构造函数
>>>zhangsan.constructor = Person; √
②instanceof:检测一个对象,是否是一个类的实例;
>>>lisi instanceof Person √ lisi是经过Person类new出的
>>>lisi instanceof Object √ 全部对象都是Object的实例
>>>Person instanceof Object √ 函数自己也是对象
三、 JavaScript中的this指向问题
在上一部分中,咱们建立了一个类,并经过这个类new出了一个对象。 可是,这里面出现了大量的this。 不少同窗就要懵逼了,this不是“这个”的意思吗?为何我在函数里面写的this定义的属性,最后到了函数new出的对象呢??
3.1谁最终调用函数,this就指向谁!
① this指向谁,不该该考虑函数在哪声明,而应该考虑函数在哪调用!!
② this指向的,永远只多是对象,不多是函数!!
③ this指向的对象,叫作函数的上下文context,也叫函数的调用者。
3.2this指向的规律(与函数的调用方式息息相关!)
① 经过函数名()调用的,this永远指向window
1
2
|
func(); // this--->window
//【解释】 咱们直接用一个函数名()调用,函数里面的this,永远指向window。
|
② 经过对象.方法调用的,this指向这个对象
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 狭义对象
var obj = {
name:"obj",
func1 :func
};
obj.func1(); // this--->obj
//【解释】咱们将func函数名,当作了obj这个对象的一个方法,而后使用对象名.方法名, 这时候函数里面的this指向这个obj对象。
// 广义对象
document.getElementById("div").onclick = function(){
this.style.backgroundColor = "red";
}; // this--->div
//【解释】对象打点调用还有一个状况,咱们使用getElementById取到一个div控件,也是一种广义的对象,用它打点调用函数,则函数中的this指向这个div对象。
|
③ 函数做为数组的一个元素,用数组下标调用,this指向这个数组
1
2
3
|
var arr = [func,1,2,3];
arr[0](); // this--->arr
//【解释】这个,咱们把函数名,当作数组中的一个元素。使用数组下标调用,则函数中的this将指向这个数组arr。
|
④ 函数做为window内置函数的回调函数使用,this指向window。好比setTimeout、setInterval等
1
2
3
|
setTimeout(func,1000);// this--->window
//setInterval(func,1000);
//【解释】使用setTimeout、setInterval等window内置函数调用函数,则函数中的this指向window。
|
⑤ 函数做为构造函数,使用new关键字调用,this指向新new出的对象
1
2
|
var obj = new func(); //this--->new出的新obj
//【解释】这个就是第二部分咱们使用构造函数new对象的语句,将函数用new关键字调用,则函数中的this指向新new出的对象。
|
3.3关于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
|
var fullname = 'John Doe';
var obj = {
fullname: 'Colin Ihrig',
prop: {
fullname: 'Aurelio De Rosa',
getFullname: function() {
return this.fullname;
}
}
};
console.log(obj.prop.getFullname());
// 函数的最终调用者 obj.prop
var test = obj.prop.getFullname;
console.log(test());
// 函数的最终调用者 test() this-> window
obj.func = obj.prop.getFullname;
console.log(obj.func());
// 函数最终调用者是obj
var arr = [obj.prop.getFullname,1,2];
arr.fullname = "JiangHao";
console.log(arr[0]());
// 函数最终调用者数组
|