面向对象

Posted by KID-1912’s Blog on December 28, 2020

面向对象

面向对象是高级语言的特性,对象具有封装性,继承性,多态性;

创建对象

创建一个Object实例

  1. var obj = {}; //字面量
  2. var obj = new Object(); //构造函数

批量创建对象

工厂模式

function person(n,a,g){
    var o = {};
    o.name = n;
    o.age = a;
    o.gender = g;
    o.say = function(word){console.log(word)};
    return o;
}
  • 对创建对象的重复代码进行封装,使其复用;
  • 创建输出的对象都是独立的Object个体,互不关联;

构造函数+原型

function Person(n,a,g){
    this.name = n;
    this.age = a;
    this.gender = g;
};
Person.prototype.cate = '';
Person.prototype.say = function(word){console.log(word)};
let page = new Person('page','20','');
  • 构造函数自动创建Object实例,函数内this指向该实例,执行内部代码并返回实例
  • 构造函数内,实例的_proto_设置为自身的prototype,设置实例的原型
  • 为实例原型,即Person.prototype添加属性和方法,由于原型链,所有Person实例都能共享同一个prototype的方法和属性

  • 手写new操作符

    function newObject(classFunc,...options){
        let newObj = {};
        // 将newObj._proto_指向函数的prototype
        Object.setPrototypeOf(newObj,classFunc.prototype);  
        let result = classFunc.apply(newObj,options);
        return result instanceof Object ? result : newObj;
    }
    
  • 注:什么是原型链

    js通过原型链实现继承,即每个对象实例都有一个_proto_的属性,该属性指向一个作为当前实例原型的对象。当访问实例的某个属性时,js会自动在实例上搜索,没找到则在该实例的原型上搜索,实例原型不存在则在原型对象的_proto_指向的对象上继续搜索,搜索中多个_proto_之间形成的关联即原型链

继承

原型链上每个类的实例继承构造函数的prototype,如果我们希望protype继承另一个对象,这样实例就能拥有该对象的属性/方法

prototype原型

Subtype.prototype = new Suptype();
Suntype.prototype.ownMethod = function(){...};      //自己的方法

让类的原型指向超类的实例,实现继承;

为什么不直接这样写?

Subtype.prototype = Suptype().prototype;
Subtype.prototype.ownMethod = function(){...};      //自己的方法
  1. 这会使Subtype.prototype和Suptype.prototype指向同一个对象
  2. 意味着Subtype.proyotype.constructor值为Suptype,这不是我们想要的,这不符合继承;
  3. 为了控制Subtype实例,我们对Subtype.prototype的操作也会影响到Suptype的实例,这是因为二者是平级关系,而非继承

Object.create()

let o = {cate: '',say(){console.log(this.cate)}};

创建一个继承o的对象,使其拥有o的全部属性/方法(单例对象的继承)

// 设置原型即可
var obj = {};
Object.setPrototypeOf(obj,o);
// or
function createBy(obj){         // 创建临时构造函数,
    let Fn = function(){};      // 利用构造函数的new设置返回实例的原型为o
    Fn.prototype = obj;
     return new Fn();
};
let obj = createBy(o);
  • 构造函数

    想让Subtype继承Suptype构造函数内的属性,我们可以

    Subtype.prototype = new Suptype('');   // 实例化一个Suptype实例作为原型
    

这确实能让Subtype实例拥有确定的Suptype属性,但所有Subtype实例的Suptype属性都是一个固定值,如果你想个性化化每个Subtype的属性值,尝试

Subtype(gender){
    Suptype.call(this,'gender);
};
Subtype.prototype = new Suptype();