Object and 继承

理解对象:
            属性类型:
                数据属性:
                    configurable
                    Enumerable
                    writable
                    value
                访问器类型:
                    configurable
                    enumerable
                    get
                    set
                两类属性类型都可以通过Object.defineProperty()来定义
                读取属性特性的方法:
                    Object,getOwnPropertyDescriptor() // 参数:属性所在的对象  属性的名称
            
            创建对象:
                工厂方法:
                     function creatPerson (name, age, job) {
                        var o = {};
                        o.name = name;
                        o.age = age;
                        o.job = job;
                        o.sayname = function() {
                            console.log(this.name);
                        }
                    }
                    var person = creatPerson('nichao', 29, 'dotor')
                    问题:没有解决对象识别的问题

                构造函数:
                    优点:直接将属性和方法赋给了this对象
                          可以将它的实列标识为一种特定的类型
                    new关键字执行四部操作:
                        1.创建一个新对象
                        2.将构造函数的作用域给新对象(因此this指向了这个新对象)
                        3.执行构造函数中的代码
                        4.返回新对象
                    问题:内部方法,每个实列创建时都会创建一个方法,影响内存

                原型模式:
                    isProtopertyOf() // 确定对象间是否存在这种关系
                        Person.prototype.isPrototypeOf(person1)

                    Object.getPrototypeOf() // 返回prototype的值
                        Object.getPrototypeOf(person) == Person.prototype // true

                    hasOwnProperty() // 检测一个属性存在实列中还是存在原型链中
                        属性存在于实列中才会返回true,存在于原型中则返回false

                    in 操作符会通过对象能访问属性时返回true
                    
                    for in 可枚举所有实列能访问的属性,屏蔽了原型中不可枚举的属性的实列属性也可以在for in 循环中返回

                    Object.keys() 返回对象的属性

                    问题:如果原型中的属性值是一个复杂数据类型,实列可改变数据,会破坏原型上的数据
                          重写原型对象最好在实例之前,不然实列会引用原先原型的指针,导致错误
                
                继承:
                    组合式继承:
                         function Supertype(name) {
                            this.name = name
                        }
                        Supertype.prototype.sayname = function () {
                            console.log(this.name);
                        }
                        function Subtype(name, age) {
                            this.age = age
                            // 继承属性
                            upertype.call(this, name)

                            this.age = age
                        }
                        // 继承方法
                        Subtype.prototype = new Supertype();
                        Subtype.prototype.constructor = Subtype;
                        Subtype.prototype.sayage = function () {
                            console.log(this.age);
                        }
                    问题:调用了两次超类的构造函数,会产生两组超类构造函数中的实例属性,一组保存在原型上,一组保存在实例中

                    寄生式继承:
                        将超类的原型拷贝一份给子类