关于 JS 中的继承的奇葩问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
haozhang
V2EX    Javascript

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

  •  
  •   haozhang 2015-01-05 15:31:39 +08:00 3704 次点击
    这是一个创建于 3933 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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" 

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

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

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

    superClass.prototype.test 确实是 undefined 没错,但 subClass.prototype.test 却是实打实的 1111
    haozhang
        14
    haozhang  
    OP
       2015-01-05 19:25:54 +08:00 via iPhone
    @Mutoo 你根本没看懂我的代码,superClass的test不是prototype的属性,我是在superClass的构造函数里面this.test=1111,而不是superClass.prototype=111
    haozhang
        15
    haozhang  
    OP
       2015-01-05 19:28:14 +08:00 via iPhone
    @Mutoo 我懂了,是我理解错了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3741 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 04:16 PVG 12:16 LAX 21:16 JFK 00:16
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86