javascript - JS继承,如何避免父类原型的object类型属性会受子类影响的情况;
问题描述
parent为父类,child继承parent,当修改child实例的sex的值时,会引起parent和其他子类实例的sex的变更;这类object类型的属性是否只能放在构造函数内,或者约定好不允许修改prototype中的object属性,来避免子类实例对父类和其他子类的影响;有没有其他的解决方案?
function extend(p, c) {var f = function () {};f.prototype = p.prototype;c.prototype = new f();c.prototype.constructor = c; } function parent() {} parent.prototype.aaa = 123; parent.prototype.sex = [’男’, ’女’]; function child() {} extend(parent, child); c1 = new child(); c2 = new child(); console.log(’设置实例c1之前,父类的sex值:’,parent.prototype.sex); console.log(’设置实例c1之前,实例c2的sex值:’,c2.sex); c1.sex.push(’其他’); console.log(’设置实例c1之后,父类的sex值:’,parent.prototype.sex); console.log(’设置实例c1之后,实例c2的sex值:’,c2.sex);
问题解答
回答1:这个方式可以让子类和对象访问 sex 的时候,如果 sex 不存在则为其创建一个父类 sex 的副本,存在则直接返回。
function extend(p, c) { var f = function() {}; f.prototype = p.prototype; c.prototype = new f(); c.prototype.constructor = c;}function parent() {}parent.sex = [’男’, ’女’];parent.prototype.aaa = 123;Object.defineProperty(parent.prototype, ’sex’, { configurable: true, enumerable: true, get: function () { if (this === parent || this === parent.prototype) { return parent.sex; } if (!this.hasOwnProperty(’sex’)) { Object.defineProperty(this, ’sex’, {value: parent.sex.slice(),configurable: true,enumerable: true,writable: true }); } return this.sex }, set: function (value) { if (this === parent || this === parent.prototype) { parent.sex = value; } else if (!this.hasOwnProperty(’sex’)) { Object.defineProperty(this, ’sex’, {value: value,configurable: true,enumerable: true,writable: true }); } else { this.sex = value; } }});function child() {}extend(parent, child);var c1 = new child();var c2 = new child();var p1 = new parent();console.log(’设置实例c1之前,父类的sex值:’, parent.prototype.sex);console.log(’设置实例c1之前,实例p1的sex值:’, p1.sex);console.log(’设置实例c1之前,实例c2的sex值:’, c2.sex);c1.sex.push(’其他’);console.log(’设置实例c1之后,父类的sex值:’, parent.prototype.sex);console.log(’设置实例c1之后,实例p1的sex值:’, p1.sex);console.log(’设置实例c1之后,实例c1的sex值:’, c1.sex);console.log(’设置实例c1之后,实例c2的sex值:’, c2.sex);回答2:
子类定义一个同名属性, 覆盖父类的?
回答3:非方法的属性不推荐设置在原型上
回答4:在初始化子类child时候,定义私有属性:
function child() { this.sex = ’’;}