面向对象
1了解面向对象
面向对象是利用对象进行编程的一种思想(Object-oriented programming,缩写:OOP)。
1.1 JavaScript两种模式
1.面向过程;
2.面向对象。
1.2面向对象与面向过程的区别
例如:小狗觅食(闻一闻smell、舔一舔lick、咬一咬bite)。对这个案例分别采用面向过程和面向对象来分析。
1.面向过程(主角是小狗) :
先闻一闻, 然后再舔一舔, 最后再咬一咬。
2.面向对象(主角是我):
我首先要有一只小狗, 它可以闻一闻食物, 可以舔一舔食物, 可以咬一咬食物;
然后我对小狗说:旺财去闻一闻,旺财去舔一舔,旺财去咬一口 (指挥小狗)。
1.3对象的组成
1.属性(变量):
对象有什么。
2.方法(函数):
对象能做什么。
2如何创建对象
2.1字面量
var student = {id:10,name:'小明',age:18};
2.2构造函数
var student = new Object()
student.id = 10;
student.name = '王铁锤';
student.age = 18;
以上两种方式的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。
2.3封装工厂函数
为了减少重复代码,对上述代码进行封装。
function createStudent(name,age,gender){
var res = {}
res.name = name;
res.age = age;
res.gender = gender;
return res;
}
需要创建对象时,可直接var s1 = createStudent('xxx',22,'女');
工厂函数的缺点是,无法识别对象是由谁生成的,如果不知道对象是由谁生成的,会有很多不便,如无法添加原型方法。
3自定义构造函数
案例:
function Student(name, age){
this.name = name;
this.age = age;
this.sayName = function(){alert(this.name);};
}
var s1 = new Student("王铁锤", 18);
new调用构造函数时经历以下4步(重要):
1. 创建一个Object对象;
2. 将构造函数的this指向这个对象;
3. 执行构造函数中的代码;
4. 返回Object对象。
3.1 内置构造函数
如String,Number,Boolean,Array,Object,RegExp等。
为什么字面量生成的字符串能像对象一样使用方法,如var username =’nihao’; username.slice(); ?
系统会默认执行以下操作:
1. 创建一个临时对对象 var temp = new String(username);
2. 利用临时对象调用方法并返回值:return temp.trim();
3. 删除临时对象。
3.2实例
· 用new关键字生成的对象称为实例。
· 实例包含一个内部属性[[prototype]],指向原型对象。
3.3构造函数与普通函数的区别
唯一区别:调用方式不同。
· 任何函数,只要通过new操作符来调用,它就可以作为构造函数;
· 而任何构造函数,如果不通过new 操作符来调用,那它跟普通函数无区别。
约定:构造函数名首字母大写。
3.4 this
函数中的this作为JS的关键字,有特殊的含义,代表了当前对象,而当前对象是谁,由函数执行时所处的环境来决定。
· 用new关键字调用:this指向生成的实例对象。
· 普通函数调用:this指向调用函数的对象。
3.5原型对象
· constructor:指向构造函数。
· 原型对象中的属性和方法可以让所有对象实例共享。
3.5.1如何获取原型对象
通过构造函数:prototype。
通过实例:FF,Chrome:__proto__;ES5方式:Object.getPrototypeOf(实例)。
3.6判断
判断原型和实例的关系(返回布尔值)
constructor: 一般用于判断该实例是否由某一构造函数生成:实例.constructor == Student //true。
instanceof: 检测某个对象是不是某一构造函数的实例
实例 instanceof Student //true
实例 instanceof Object //true
isPrototypeOf: 判断当前对象是否为实例的原型:原型对象.isPrototypeOf(实例) //true
3.7实际应用
3.7.1属性访问规则
1.先从当前对象本身查找,找到则使用;
2.如果找不到,则往它的原型对象中查找;
3.如果找不到,则往它的原型对象的原型对象查找,直到Object的原型对象;
4.如果都找不到,则返回undefined
3.7.2实际应用
构造函数方法很好用,但是单独使用存在一个浪费内存的问题(所有的属性/方法都写入实例中)。这样既不环保,也缺乏效率。
解决方案:构造函数+原型对象:
· 构造函数中添加属性;
· 原型对象中添加方法。
实例中的属性减少了,原型对象中的方法又能被所有的实例共享,最大限度的节省了内存。
4总结:面向对象只做两件事
1.创建并描述对象
添加属性;
添加方法;添加方法遵循单一原则:一个方法只做一件事情。
2.操作对象
指挥对象实现某种效果。
5匿名函数
5.1匿名函数与具名函数的区别
匿名函数在声明时不需要带上函数名。
5.2匿名函数自动执行
(function(){
alert("abc");
})();
所有的一元运算符号都可触发匿名函数的执行,如
(function(){
console.log(777)
}());
!function(){
console.log(888)
}();
-function(){
console.log(999)
}();