JS面向对象编程--过程式分析

声明:php

概念性介绍会简单穿插,以过程式分析问题为主,便于提升实践的意义。

前言:java

面向对象,早已烂熟于耳,以java为最,php5.6以后更是扩展了面向对象式开发(起先引入对象概念,没当个大方向,这下无意插柳柳成荫,繁盛起来了),js也基于对象式开发了。。。

开扒浏览器

可是,JS没有类的概念,是构造函数和原型链的方式来体现的。

我这里仅经过1个例子(有点懒~),尽可能全面的分析下实现过程。app

/*=================定义“类”=================*/
   /*=======父类Foo=======*/
   function Foo(name,age){
     this.name = name;    //this是当前 [调用FOO()构造函数的] 对象,若是有子类Bar继承则表明子类对象
     this.age = age;      //this.参数名,则意味着各个对象,有属于本身的名字和年龄
    }                     //如上,是对象间差别化、独立性的体现
    
    /*父类Foo的原型*/
    Foo.prototype = {         //在此定义Foo对象公有的方法/属性,以节省内存、便于维护(性能上:若是把sayHi()方法定义在了Foo(name,age)构造函数中,等于说每new一个Foo或子类对象,每一个对象在堆内存就会多占点空间来存放sayHi()方法,耗内存啊。)   
        sayHi:function(){     //公有方法  
            alert("Hi,I'm "+this.name);
        },
        guess:888             //公有属性
    };
    
    /*=======子类Bar=======*/
    function Bar(name,age,sex){    
        Foo.call(this,name,age); //等同于Foo.apply(this,[name,age]);你要初始化的东东,父类搞好了,只管调用
        this.sex = sex;          //Bar对象自己的特有属性
    }  
    /*子类Bar的原型是个Foo对象*/
    Bar.prototype = new Foo();   //Bar的原型类=Foo对象,意味着Bar对象能调到自己没有却在(Foo对象或者Foo.prototype)中存在的属性或方法
    
    //建立并调用
    var bar = new Bar('Lin',18,'male'); 
    bar.sayHi();

运行效果:函数

clipboard.png

案例补充说明:性能

1)var bar = new Bar('Lin',18,'male'); 
    解释:
        new 一个 Bar对象,名为bar.
        bar就继承了Foo类的属性和Foo原型上的方法。
        
    2)bar.sayHi();    //可调
    解释:
        bar对象,首先自身查找是否有sayHi()方法,没有则bar.__proto__获得Bar.prototype;
        在Bar.prototype这个原型对象中继续查找,而前面咱们已指定Bar.prototype = new Foo();
        则意味着是在Foo对象中查找,然而Foo对象自己没有sayHi()方法;
        则调用(new Foo()).__proto__获得原型对象Foo.prototype;
        继续在该原型对象Foo.prototype中查找sayHi()方法;
        终于找到了!!!返回结果吧。
    
    扩展:
       若是依然没找到,就会Foo.prototype.__proto__获得Object.prototype,
       Object.prototype自己没有sayHi()方法,就会
       Object.prototype.__proto__获得null.
       null是最顶级的对象。在该对象中,查无此方法,就报错了;查无此属性,就undefined.

涉及术语:this

原型链
    各构造函数,各有与之相对应的原型;
    类之间的继承,就暗暗的把原型间的关系统筹在了一块儿。
    顶层原型上方法或属性的查找过程,就是依靠着原型间的这种关系,一层一层的向上查找的。

原型继承
     Bar.prototype = new Foo(); 

借用继承
     Foo.call(this,name,age); //Foo.apply(this,[name,age]);

组合继承
     function Bar(name,age,sex){    
        Foo.call(this,name,age);
        this.sex = sex;                
     }  
    Bar.prototype = new Foo();  

    现象式总结:        
        仅是原型继承,子类Bar确实可调用(父类Foo的属性和原型上的方法)了,但实例化出来的Bar对象就不独立了。意味着某个对象对Foo构造函数中的属性或方法的修改,会影响到其余对象调用的结果.
        简言之,子类可调父类了,可是实例化的对象不独立。

        仅是借用继承,子类bar实例化的对象是独立的,对象间不受影响,但父类原型上的方法调不了了.
   
        推荐组合继承,既保证了对象间的独立性,又能调用到父类的原型上的方法。

福利:spa

1.原型链图示(网上找的,看懂便可跳过上述内容)

clipboard.png
该图把原型和构造函数间的关系理的很清楚,可在Google浏览器的console运行demo并查看对象下原型间的关系。prototype

2.JS高级部分,以前看的是ali的Bosn的JavaScript深刻浅出

若有不适内容,欢迎指正。code

相关文章
相关标签/搜索