面向对象

85 阅读7分钟

概念

面向:关注 - 重视

面向过程:重视一件事情的整个过程

面向对象:重视一件事的参与对象

面向对象不是一种新的语法,是一种高级的编程思想

学习面向对象的终极目标:为了分工合作

定义对象

var obj = {} // 字面量方式

var pbj = new Object() // 构造函数方式

console.log(obj, pbj);

学习面向对象:主要工作 - 如何定义对象才是最好的;如何给对象添加属性是最棒的;如何给对象添加方法最好的方式

工厂函数创建对象

定义一个函数,每次调用都能得到一个对象


function createObj(name,age,sex){
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.sex = sex;
    return obj;
}
var obj1 = createObj("张三",12,"男");
var obj2 = createObj("李四",13,"女");
var obj3 = createObj("王五",11,"女");

这种调用就能创建对象的函数,叫做工厂函数。创建出来的每个对象的结构一致,如:电商网站中的商品对象

优点:可以同时创建多个对象

缺点:创建出来的没有具体的类型(比如是Array和Number),都是object类型的,但我们看到自己的对象只是object,不知道具体是什么类型。

es6的语法 - 对象的简写形式

当对象的键和值使用的变量同名了,就可以简写

 var obj = {
     name: name,
     age: age
 }

构造函数

new出来的数据,可以一目了然看到具体是什么逻辑上的数据类型

function Person() {
    // 1.var obj = {}
    // 2.this = obj
    // 3.执行构造函数中的代码
    // 构造函数中的this:new出来的那个对象
    this.name = '张三' // 给this对象添加属性
    console.log(111, this); // this就是new出来的那个对象
    console.log(this.name);
     // 4.return obj
}
var p = new Person() // 虽然在new,但是函数也是在调用
新的函数调用方式,通过new来调用
console.log(p);

new操作符的作用:

1.会在构造函数中创建一个空对象 - 隐形的
2.会给构造函数中的this复制这个空对象 - 隐形
3.执行构造函数中的代码
4.会将this返回 - 隐形

总结:

1.new 构造函数 其实也是在调用函数
2.构造函数中的this代表new出来的对象
3.new到底干了什么?
    1.隐形创建了一个空对象
    2.将空对象赋值给this
    3.执行构造函数中的代码
    4.返回这个空对象

原型

任何函数在创建好的时候,浏览器会分配一个对象给这个函数,通过函数的prototype可以访问到这个对象。这个对象叫做原型对象,简称原型。通过new构造函数实例化出来的对象默认可以访问到这个对象的属性和方法。

任何对象天生都自带一个属性:proto - 对应的值,也是一个对象 - 原型/原型对象

原型的作用:对象就天生就能使用自带的原型中的属性和方法。当对象使用一个属性或方法的时候,先在自己对象上只要这个属性或方法,如果自己有,就使用自己的属性或方法,如果自己没有,才会去原型上找属性和方法

只要是对象,天生自带原型 - 对象.proto 原型上的属性和方法天生就能被对象使用,先在自己上找,自己没有就找原型

构造函数的原型 === new出来的对象的原型
被一个构造函数new出来的所有对象的原型都是同一个
一个构造函数可以new出来无数个对象,他们的原型都是同一个
构造函数理解为母亲,将原型理解为父,将new出来的对象理解为子

构造器

每一个原型对象天生带有一个属性叫做constructor,这个属性指的是这个原型对象所属的构造函数。


function Person(){
    
}
var obj1 = new Person();
console.log(obj1.__proto__.constructor === Person); // true  
console.log(obj1.constructor === Person); // true  obj1对象中没有constructor属性,所以去原型对象上找

原型链

对象访问属性的时候,如果自己么有,就去原型对象上找,找到了访问。那如果找不到怎么办?

对象天生就有一个属性叫做__proto__,那么,原型对象也是对象,他也有这个属性,也就是说,原型对象也有原型自己的构造函数和原型对象。


function Person(){
    
}
var obj = new Person(); // 通过构造函数创建了对象obj
var proto = obj.__proto__; // 通过实例对象访问到原型对象
console.log(proto);

访问结果:

构造器

每一个原型对象天生带有一个属性叫做constructor,这个属性指的是这个原型对象所属的构造函数。


function Person(){
    
}
var obj1 = new Person();
console.log(obj1.__proto__.constructor === Person); // true  
console.log(obj1.constructor === Person); // true  obj1对象中没有constructor属性,所以去原型对象上找

原型链

对象访问属性的时候,如果自己么有,就去原型对象上找,找到了访问。那如果找不到怎么办?

对象天生就有一个属性叫做__proto__,那么,原型对象也是对象,他也有这个属性,也就是说,原型对象也有原型自己的构造函数和原型对象。


function Person(){
    
}
var obj = new Person(); // 通过构造函数创建了对象obj
var proto = obj.__proto__; // 通过实例对象访问到原型对象
console.log(proto);

访问结果:

原型对象

继续访问原型对象的原型:


function Person(){
    
}
var obj = new Person(); // 通过构造函数创建了对象obj
var proto = obj.__proto__; // 通过实例对象访问到原型对象
var proto1 = proto.__proto__; // 访问原型对象的元素
console.log(proto1);

其实这个对象,就是Object构造函数的原型对象。

这也是个对象,他的原型是什么?


function Person(){
    
}
var obj = new Person(); // 通过构造函数创建了对象obj
var proto = obj.__proto__; // 通过实例对象访问到原型对象
var proto1 = proto.__proto__; // 访问原型对象的元素
var proto2 = proto1.__proto__; // 访问Object的原型对象的原型
console.log(proto2); // null

最后访问到null,也就是说到头了,这是最顶级的对象。

通过一张图来将上面几个对象的关系画出来:

构造器

每一个原型对象天生带有一个属性叫做constructor,这个属性指的是这个原型对象所属的构造函数。


function Person(){
    
}
var obj1 = new Person();
console.log(obj1.__proto__.constructor === Person); // true  
console.log(obj1.constructor === Person); // true  obj1对象中没有constructor属性,所以去原型对象上找

原型链

对象访问属性的时候,如果自己么有,就去原型对象上找,找到了访问。那如果找不到怎么办?

对象天生就有一个属性叫做__proto__,那么,原型对象也是对象,他也有这个属性,也就是说,原型对象也有原型自己的构造函数和原型对象。


function Person(){
    
}
var obj = new Person(); // 通过构造函数创建了对象obj
var proto = obj.__proto__; // 通过实例对象访问到原型对象
console.log(proto);

继续访问原型对象的原型:

function Person(){
    
}
var obj = new Person(); // 通过构造函数创建了对象obj
var proto = obj.__proto__; // 通过实例对象访问到原型对象
var proto1 = proto.__proto__; // 访问原型对象的元素
console.log(proto1);

其实这个对象,就是Object构造函数的原型对象。

这也是个对象,他的原型是什么?

function Person(){
    
}
var obj = new Person(); // 通过构造函数创建了对象obj
var proto = obj.__proto__; // 通过实例对象访问到原型对象
var proto1 = proto.__proto__; // 访问原型对象的元素
var proto2 = proto1.__proto__; // 访问Object的原型对象的原型
console.log(proto2); // null

最后访问到null,也就是说到头了,这是最顶级的对象。

样向上的一条链式结构,我们称之为原型链。

对象查找属性的规则:

​ 先在自己身上找,如果有,直接使用,如果没有,顺着原型链往上找,找到了就使用,找不到就继续往上找,如果找到了null,都没有的话,就返回undefined;

但是对象属性赋值和原型没关系,有就修改,没有就增加。