JS - 面向对象编程(原型对象篇)

207 阅读3分钟

面向对象编程

面向对象编程(opp):具有灵活,代码可复用性,高度模块化等特点

  1. 对象是单个实物的抽象
  2. 对象是一个容器,封装了对应属性和方法
    属性是对象的状态,方法是对象的行为

构造函数

(表示一类实物的共同特征)需要一个模板,让对象生成
类(class)就是对象的模板
js不是基于类的,而是基于构造函数(constructor)和原型链(prototype)

//Dog是构造函数,为了和普通函数区别,构造函数的名字的第一个字母通常大写
//特点:
//1.函数体内是用this关键字,指向的是所要生成的对象实例如(dog1)
//2.生成对象,必须是用new关键字实例化
function Dog(name, age) {
      //name和age就是当前实例化对象的属性
      this.name = name;
      this.age = age;
    }
    var dog1 = new Dog('cokie', 4);
    console.log(dog1.name);//cokie
    console.log(dog1.age);//4

instanceof

function Dog(name){
    if(!(this instanceof Dog)){//判断this指向的这个是否为Dog的实例(有无new)
        return new Dog(name);
    }
    this.name = name;
}
var d1 = Dog('cokie');
console.log(d1);

new命令的原理

  1. 创建一个空对象,作为将要返回对象实例
  2. 将这个空的对象的原型对象,指向了构造函数的prototype属性对象
  3. 将这个实例对象的值赋值给函数内部的this关键字
  4. 执行构造函数体内的代码

constructio属性

每个对象在创建时都会自动拥有一个构造函数属性constructor
constructor继承自原型对象,指向了构造函数的引用

原型对象、实例对象、构造函数之间关系

Foo身为实例对象有constructor以及__proto__属性 FOO身为构造函数有prototype属性

js继承机制

//通过原型对象实现继承
//原型对象的作用就是定义所有实例对象共享的属性和方法
function Foo(){};
Foo.prototype.name = 'qaq';
var f1 = new Foo();
var f2 = new Foo();
console.log(f1.name);//qaq
console.log(f1.name);//qaq

原型链

JS规定,所有的对象都有自己的原型对象

根据原型链查找,一层一层往上查找,所有对象的原型最终都能寻找到Object.prototype,Object构造函数的prototype

所有的对象都继承了Object.prototype上的属性和方法

读取属性和方法的规则:js引擎会先寻找对象本身的属性和方法,如果找不到就到它的原型对象去找,如果还是找不到,就到原型的原型去找,如果直到Object.prototype还是找不到,返回undefined

constructor

function Myarray(){};
Myarray.prototype = Array.prototype;//可以调用array的方法
console.log(Myarray.prototype.constructor);//打印的是Array()
var arr = new Myarray();

一旦我们修改构造函数的原型对象,为防止引用出现问题,同时也要修改原型对象的constructor属性

function Myarray(){};
Myarray.prototype = Array.prototype;//可以调用array的方法
Myarray.prototype.constructor = Myarray;
console.log(Myarray.prototype.constructor);//打印的是 Myarray()
var arr = new Myarray();

constructor属性表示原型对象和构造函数之间的关联关系