欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

原型模式的不足和解决办法

程序员文章站 2022-05-08 16:51:25
...

原型模式的缺点:
* 虽然省略了为构造函数传递初始化参数这一环节,结果所有的实例都有了默认的相同的属性值。会带来一些不方便,但主要问题还是由其共享的本质所导致的。
* 原型中所有的属性是被很多实例共享的,这对于函数非常舒服,但对于包含引用类型的属性来说,问题就出来了:

function Person() {
    }

    Person.prototype = {
        name: "Hongbin",
        age: 21,
        friends: ["A", "B"],
        satFriend: function () {
            console.log("my friends: "+this.friends);
        }
    };

    var person1 = new Person();
    var person2 = new Person();

    person1.friends.push("C");
 	console.log(person1);//["A","B","C"]

    console.log(person2);//["A","B","C"]

原型模式的不足和解决办法
person1 用push()方法给friends属性添加一个字符串,但person2的friends也跟着改变了
问题:共享属性,一个实例按照自己想要实现的功能改变了属性的值,与其共享属性的实例对应属性的值也随之发生改变。
原因:person1实例中没有friends属性,向上找,找到了Person中的friends属性,改变了它,共享的person2也随之影响。

//解决办法 :******组合使用构造函数模式与原型模式********
//这是创建自定义类型的最常见方式。
//构造函数模式用于定义实例属性,原型模式用于定义方法和共享属性。这样每个实例都会自己的一份实例属性的副本,同时又共享着对方法的引用,最大限度的节省了内存。还有,这种模式还支持向构造函数传递参数;可谓集两家之所长。

原型模式的不足和解决办法

function Person(name,age,sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.friends = ["A","B"];
    }

    Person.prototype = {
        constructor : Person,
        sayHello:function () {
            console.log("Hi!"+this.friends);
        }
    };

    var person1 = new Person("Hongbin",21,true);
    var person2 = new Person("xiaomei",20,false);

    person1.friends.push("C");
    console.log(person1);//Person {name: "Hongbin", age: 21, sex: true, friends: Array(3)}
    console.log(person2);//Person {name: "Hongbin", age: 21, sex: true, friends: Array(2)}
	console.log(person1.friends == person2.friends);//false
    console.log(person1.constructor == person2.constructor);//true
    console.log(person1.sayHello == person2.sayHello);//true