听说面向对象很难很复杂的样子?其实并不难,慢慢由浅入深理解就好了。下面我来说说我对面向对象的认识吧!
比如说我们要做一道菜,那么步骤应该是:
1. 买菜(去哪买?买多少?买什么?)
2. 洗菜切菜(怎么切?片?条?块?)
3. ……
面向过程:关注的是具体实现的过程
面向对象:关注的是特征(具有的特性),注意:面向对象不是没有过程,而是不关注过程,就跟个领导一样,我不管你菜哪里买,怎么切,怎么做,我只要你把一道菜放我面前就是。
两者的本质上都是函数的一个封装。所以说封装思想很重要!
在JS中对象是一种复合的数据类型。
对象的创建有两种方式
1. new Object()
var obj1 = new Object();
2. {}
var obj2 = {};
通过上述的两种方式,都可以创建一个空的对象
先来看看对象的创建
function People(name, gender, age) { // var obj = new Object(); this.name = name; this.gender = gender; this.age = age; // return obj; }
//基于书写规范,一般都以大写字母开头,用来区分普通的函数封装。 当我们通过new的方式去调用执行一个函数的时候 * 1. 在函数内部自动创建一个空的对象 * 2. 把该函数的this指向该对象 * 3. 函数执行完成自动返回该对象 所以如同上面一样,创建一个对象本质上我们是自动省略了那两行注释的。
得到一个people对象,我们可以调用它。
var xm = new People('小明', '男', 18);//我们创建了一个叫小明的人的对象,并且给他取了名字,定了性别,年龄。
People被称为构造函数,基于它我们创造了小明这个对象实例。
构造函数的注意事项:
function eat() { console.log('狼吞虎咽'); } function People(name, gender, age) { this.name = name; this.gender = gender; this.age = age; this.say = function() { console.log(this.name + '是个吃货'); } this.eat = eat; }
构造函数 <-> 类
* 类:类型,对具有相同特征的对象的抽象描述
* 对象:由类创建出来的具体对象(实例),也称为实例化对象
* 构造函数:类中用来创建对象的具体函数,类创建对象的时候调用的初始化函数
对象的一些特征所拥有的值其实也是一样,那么如果每个对象对这样的相同值的特征也是独立保存一份的话,就会照成资源浪费(内存占用)
所以把相同特征都写在构造函数的原型上,每个实例对象都能继承到它。
People.prototype.eat = function () {
console.log('狼吞虎咽');
}
xm.eat()执行的时候,会去查找xm这个对象本身的__proto__属性上有没有eat方法,没有的话就去找它的构造函数People的原型上有没有这个方法,找到了就执行。
所以执行结果就能打印出:狼吞虎咽。
当我们去调用一个对象下的属性或方法的时候,对象首先会在自身上查找是否该属性或方法,如果有则调用,如果没有,则会查找自己的__proto__属性上是否有给属性或方法
为了使对象共有的特征方法维护和管理,所以有一种专门来管理和维护这些共同特征的方法(手段)
* 当一个函数被创建的时候,该函数下自动会有一些属性(函数也是对象),其中有一个属性,名称:prototype,他的值是一个对象,我们通常就把构造函数创建的对象所拥有的共同特征保存在这些对象的构造函数的prototype属性下
*
* 当一个对象被创建的时候,对象自动会创建一个属性,名称:__proto__,该属性也是一个对象,其实该属性就是该对象的构造函数的prototype
*
* 当我们去调用一个对象下的属性或方法的时候,对象首先会在自身上查找是否该属性或方法,如果有则调用,如果没有,则会查找自己的__proto__属性上是否有给属性或方法
刚接触面向对象,最重要或者说最难理解的是它的原型链。这个问题,下一节会详细去说的。