面向对象编程 & 原型及原型链

62 阅读1分钟

OOP与继承

面向对象

Object oriented Programming

JS中的面向对象

JS中创建一个对象, 有哪些方法

    Object.create()
    
    var bar = {}
    
    var p = new Person()

var bar = {}Object.create({})有什么区别

new 关键字

    function Person(name, age) {
        this.name = name
        this.age = age
    }
    const p = new Person
    
    // 1. new 创建了一个对象, 这个对象的原型链, 指向了构造函数的原型
    p.__proto__ === Person.prototype
    // 2. Person有个原型,原型上一个constructor, 是Person自己
    Person.prototype.constructor === Person
    
    // 3. p这个对象, 是构造函数构造的,  p的构造函数是Person
    p.constructor === Person  
    

new 关键字

  • 创建了一个对象
  • 这个对象的原型, 指向了这个Person/Function 的prototyp
  • 该对象实现了person的方法
  • 根据一些特定的情况返回对象
    • 如果这个构造函数没有返回值, 或者返回一个非对象类型, 则new最后返回创建的这个对象
    • 如果这构造函数明确返回了一个对象, 则返回这个对象
    function newFunc(Person, ...rest) {
        if (typeof Person !== 'function) {
            throw new Error('')
        }
        var obj = Object.create(Person.prototype)
        var result = Person.call(obj)
        return result && typeof result === 'object' ? result : obj;
    }

实现一个Object.create

    function inherit(p) {
        if (p === null) throw TypeError()
        if (Object.create) {
            return Object.create(p)
        }
        
        if (typeof p !== "object" && typeof p !== "function") throw TypeError()
        
        function f () {}
        f.prototype = p
        return new f()
    }

继承

继承, 类与类值之间的关系

原型继承

    function Parent(name) {
        this.name = name
        this.nameList = ['1', '2']
    }
    
    Parent.prototype.getName =function() {
        console.log(this.name)
    }
    
    function Child() {}
    
    Child.prototype = new Parent()
    Child.prototype.constructor = Child
    
    const c1 = new Child()
    const c2 = new Child()
    
    c1.nameList.pop()
    
    // 1. Child.prototype 不能传参
    // 2. 如果Parent 有属性是引用类型, 一旦修改所有都受影响
    
    

构造函数继承

    function Parent(name) {
        this.name = name
    }
    Parent.prototype.getName =function() {
        console.log(this.name)
    }
    
    function Child() {
        Parent.call(this)
    }
    

组合寄生和Class的区别 Loose模式差不多 , 主要两个区别 class 继承, 会继承静态属性 子类中, 必须在constructor中调用super, 因为子类自己的this对象, 必须先通过父类的构造函数完成