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 · 3115 次点击
    这是一个创建于 3400 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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=1111
    haozhang
        15
    haozhang  
    OP
       2015-01-05 19:28:14 +08:00 via iPhone
    @Mutoo 我懂了,是我理解错了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2711 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 00:04 · PVG 08:04 · LAX 17:04 · JFK 20:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.