zoukankan      html  css  js  c++  java
  • JS面向对象编程的实现

    先从问题说起

    今天脑袋短路,有种有这么一种问题困扰我:

        let Computer = function () {
            this.computerValue  = 'computerValue';
        };
        Computer.prototype.fun = function () {
            console.log('calculate');
        };
        let mac = new Computer();
        mac.fun = 1;
        let acer = new Computer();
        console.log(acer.fun); //为什么acer的fun不是1

    这个问题问的真愚蠢!但是却让我醒悟,长时间的使用框架与类库,导致JS的一些思想完全忘记了。

    从图中可以看出mac与acer都是Computer类的实例,当执行 mac.fun=1时实质上是在mac对象上新增一个fun属性。

    暂时下结论:实例无法修改原型链上的方法,只能继承使用(作用域链采取就近原则)先提示一下这个结论是错误的,看下面的例子:

        function Human() {
            this.name = 'parent'
        }
        Human.prototype.books = ['Css', 'Js', 'Html'];
    
        var male = new Human();
        var female = new Human();
    
        male.books.push('Php');
        console.log(female.books); // ['Css', 'Js', 'Html', 'Php'];

    从上面可以看,执行 male.books.push('Php') 时, female.books也被改变了,这是为什么呢?下面上图:

    看出猫腻了么? 执行 male.books.push('Php') 实际上是直接操作原型对象上的books属性,这个操作并没有为male添加books属性。所以访问female.books也就是原型对象上的books。
    总结:在操作实例对象instance的原型属性property时,如果你使用instance.property= express,相当于给实例本身新增加一个property属性,并没有改变原型对象的property的属性。如果你没有使用=进行辅助而是改变instance.property的值,那么相当于你改变了原型对象的property属性值。

    所以原型对象上一般存放方法,修改方法是通常是使用 = 进行赋值,这样就不会改变原型对象了。

  • 相关阅读:
    内存泄漏检测工具VLD在VS2010中的使用举例
    boost::threadpool 调用类成员变量并传入参数 的方法
    boost之ThreadPool
    DllMain 用法
    分布式锁的几种实现方式
    利用cbmakegen导出Code::blocks的Makefile
    搜集C++实现的线程池
    微软开源rDSN分布式系统开发框架
    腾讯互娱开源分布式开发框架Pebble
    SpringBoot指定额外需要扫描的包
  • 原文地址:https://www.cnblogs.com/noper/p/6770609.html
Copyright © 2011-2022 走看看