js对象

作者: IDO0 | 来源:发表于2018-07-28 17:22 被阅读0次

    对象属性

    一属性类型:

    1:数据属性
    [[configurable]]:表示能否delete删除属性,默认为true
    [[enumerable]]:能否通过in迭代访问
    [[writable]]:能否修改属性值
    [[value]]:包含这个属性的数据值,读取和访问时都说该值,默认undefined。
    2:访问器属性
    [[get]]:读取属性时调用,默认值undefined。
    [[set]]:写入属性时调用,默认值undefined。

    二属性访问:

    1:定义属性特性
    object.defineProperty();
    object.defineProperties();
    2:读取属性特性
    object.getOwnPropertydescriptor()

    创建对象

    目标:

    1:获得对象实例,
    2:共享对象方法,
    3:属性为每个实例私有,
    4:实例可以判断类型
    5:可以配置参数初始化

    一:工厂方式

    function createPerson(name) {
        var o = new Object();
        o.name = name;
        o.sayName = function () {
            console.log(this.name)
        }
        return o;
    }
    //1满足 每次调用返回一个新对象  
    //3满足 属性为每个实例私有
    //5满足
    //4不满足 对象都是object类型 不能对象识别,
    //2不满足 方法不能共享
    //要知道sayName是一个函数,函数也是一种对象,
    // 所以以上方式创建了一个o对象和一个赋值sayName的匿名对象,如果有多个方法,那么每次都会新建n(方法数)+1个对象,对象会占据内存,因此内存开销太大。
    

    二:构造函数模式

    function Person(name) {
        this.name = name;
        this.sayName = function () {
            console.log(this.name)
        }
    }
    let p = new Person("wye");
    //直接将属性和方法赋值给this
    //通过new 创建一个新对象
    //将构造函数的作用域给新对象(this指向新对象)
    //执行构造函数 给this添加属性方法
    //返回this 
    //1,3,4(p instance Person),5 满足,
    //2不满足
    // 可以换一种写法等效
    o.sayName = new function () {
           console.log(this.name)
        }
    

    三:原型模式

    //写法一:
    function Persion() {}
    Persion.prototype.name = "wyq";
    Persion.prototype.friends = ["a","b","c"];
    Persion.prototype.sayName = function () {
        console.log("this.name",this.name);
    };
    let p = new Persion();
    //写法二:重写对象原型
    function Persion() {}
    var p = new Persion();
    Persion.prototype = {
        name: "wyq",
        friends: ["a", "b", "c"],
        sayName: function () {
            console.log("this.name", this.name);
        },
    };
    var m = new Persion();
    p.friends.push("d"); //P访问不到 m可以访问 
    //因为p.constructor= Persion 在实例化时就确定了指向,
    //而在重写原型对象以后实例化的m.constructor指向的是
    //匿名对象 即
    object= {
        name: "wyq",
        friends: ["a", "b", "c"],
        sayName: function () {
            console.log("this.name", this.name);
        },
    };
    console.log("m",m.friends);
    //注意:原型的属性和方法是动态添加以后所有实例都可以访问的,
    //但是实例与原型的指向关系是静态的,在实例化时就确定的,
    //当实例已经存在时,重新覆盖原型会切断已经实例化的对象与原型的关系。
    问题:
    //3,5不满足
    //如果属性是一个引用类型的对象friends,改变一个实例所有实例属性都会发生变化。
    function Persion() {}
    Persion.prototype.name = "wyq";
    Persion.prototype.friends = ["a","b","c"];
    Persion.prototype.sayName = function () {
        console.log("this.name",this.name);
    };
    var p = new Persion();
    var m = new Persion();
    p.friends.push("d");
    console.log("m",m.friends); //["a","b","c","d"]
    

    四:组合构造和原型模式

    //将私有属性放到构造函数里面,将共享属性放到原型上面
    //方法一
    function Persion() {
        this.name="wyq";
        this.friends=["a", "b", "c"];
    }
    Persion.prototype = {
        sayName: function () {
            console.log("this.name", this.name);
        },
    };
    

    对象继承

    一:原型链继承

    function SuperType() {
        this.colors = ["a","b","c","d"];
    }
    SuperType.prototype.getColor = function (i) {
        return this.colors[i];
    };
    function SubType() {}
    SubType.prototype = new SuperType();
    
    let sub1 = new SubType();
    let sub2 = new SubType();
    
    sub1.colors.push("e");
    console.log("sub1.getColor(1)",sub1.getColor(1));
    console.log("sub2.colors",sub2.colors);
    //缺点:
    //1:子类所有实例,共享父类属性。
    //2:没有办法在不影响所有子类实例的情况下给超类传递参数
    

    二:借用构造函数组合继承

    //只需修改子类构造如下
    function SubType() {
        SuperType.call(this); //实例属性私有化
        this.size = "15"//定义子类自己的属性
    }
    sub1.colors.push("e");
    console.log("sub1.colors",sub1.colors);//["a", "b", "c", "d", "e"]
    console.log("sub2.colors",sub2.colors);//["a", "b", "c", "d"]
    

    三:寄生组合继承

    方式二会调用两次超类的构造函数,一次在创造子类原型,一次在子类构造函数内部。

    function inherit(subType,superType) {
        var prototype = {...superType.prototype}
        prototype.constructor = subType;//将子类实例构造指向子类 否则为父类
        subType.prototype = prototype;
    }
    
    function SuperType() {
        this.colors = ["a","b","c","d"];
    }
    SuperType.prototype.getColor = function (i) {
        return this.colors[i];
    };
    
    function SubType() {
        SuperType.call(this); //实例属性私有化
        this.size = "15"//定义自己的属性
    }
    // SubType.prototype = SuperType.prototype; 这种方式子类实例构造指向父类
    inherit(SubType,SuperType);
    let sub1 = new SubType();
    let sub2 = new SubType();
    sub1.colors.push("e");
    console.log("sub1.construnct",sub1.constructor);
    

    四:拷贝对象实现继承

    Object.create()
    es6 扩展运算符...
    

    相关文章

      网友评论

        本文标题:js对象

        本文链接:https://www.haomeiwen.com/subject/ndsomftx.html