关于 JS 中的继承的奇葩问题

2015-01-05 15:31:39 +08:00
 haozhang
function superClass(name, age){
    this.name = name;
    this.age = age;
    this.test = "1111"
}

superClass.prototype = {
    consturct: superClass,
    init: function () {
        console.log("this is superClass init");
    }
}

function subClass (name, age, job) {
    superClass.call(this, name, age);
    this.job = job;
    this.test = "22222";
}

subClass.prototype = new superClass();
subClass.prototype.init = function init () {
    console.log(this.job);
}

var s = new superClass("zhanghao", 22);
console.log(s.test); // "1111"
s.test = "wo gai le a";
console.log(s.test); // "wo gai le a"

delete(s.test);
console.log(s.test); // undefined

var ss = new subClass("haha", 22, "av nan you");
console.log(ss.test); // "22222"
ss.test = "qtmlgb";
console.log(ss.test); // qtmlgb

delete(ss.test)
console.log(ss.test); // "1111"

delete(ss.test);
console.log(ss.test); // "1111"

谁能讲解一下这个奇葩现象...

3328 次点击
所在节点    JavaScript
15 条回复
bluec
2015-01-05 16:03:27 +08:00
不知道你说的奇葩现象是什么?是指delete(ss.test)之后还能打印11111?你只要仔细研究一下js的原型链就明白了。
Mutoo
2015-01-05 16:46:20 +08:00
如果一个对象的属性不存在,js会尝试在 prototype 中查找该属性。一直找到最上游,直到找到或者不存在。
haozhang
2015-01-05 16:58:10 +08:00
@bluec 这两个属性肯定不在原型链里面。我用的this没有用prototype
haozhang
2015-01-05 16:59:53 +08:00
@Mutoo 你没仔细看我的代码,原型链这种基础知识...我是知道的。我在this上添加的属性,只能说明this上添加了属性和prototype里面的属性有点不一样
Mutoo
2015-01-05 17:03:23 +08:00
@haozhang 道理还是一样的,因为你写了这句 subClass.prototype = new superClass();
haozhang
2015-01-05 17:04:27 +08:00
@bluec 按原型链的说法,我第一次delete(ss.test)
log出来的应该是22222而不是1111
haozhang
2015-01-05 17:08:41 +08:00
@Mutoo 我用this.test=22222,不是prototype.test=22222。这test属性压根不应该在原型链里面。但是ss.test在delete之后竟然可以搜索到父类的test...但是父类的test根本不是自身原型的属性
novaeyoucom
2015-01-05 17:09:10 +08:00
js的delete有很多限制, 继承来的属性不能被删除是之一, 举个栗子: 一个人觉得老爹的房子户型很傻逼,看着就闹心,不想要但也不能给砸了,否则自家其他兄弟能把他打出屎来。
haozhang
2015-01-05 17:10:45 +08:00
@novaeyoucom 原来如此。我去研究研究delete-_-#
laike9m
2015-01-05 18:41:34 +08:00
确切说是无法删掉原型链中的属性
@haozhang
haozhang
2015-01-05 18:51:32 +08:00
@laike9m 不仅是原型中的属性不能删,继承的普通属性也不能删。
haozhang
2015-01-05 18:54:41 +08:00
@laike9m 上面代码就说明了,删除了子类对象的test属性就暴露出了父类的test属性,即便这个test属性是在构造函数中this.test=1111而不是superClass.prototype.test=1111
Mutoo
2015-01-05 19:02:15 +08:00
@haozhang 你的理解还是错的。

你在执行 subClass.prototype = new superClass(); 的时候,实际上创建了一个带 test 属性的对象,并赋值给 subClass 的 原型,也就是说这时候:
subClass.prototype = {test: "1111", /* other...*/}

superClass.prototype.test 确实是 undefined 没错,但 subClass.prototype.test 却是实打实的 1111
haozhang
2015-01-05 19:25:54 +08:00
@Mutoo 你根本没看懂我的代码,superClass的test不是prototype的属性,我是在superClass的构造函数里面this.test=1111,而不是superClass.prototype=1111
haozhang
2015-01-05 19:28:14 +08:00
@Mutoo 我懂了,是我理解错了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/159394

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX