美文网首页大前端
JavaScript实现继承的4类方式

JavaScript实现继承的4类方式

作者: oldSix_Zhu | 来源:发表于2017-01-06 18:50 被阅读65次

    若有不妥,请多指教
    目录:
    -1.JavaScript实现继承的4类方式
    -2.JavaScript是一门'解释执行'的脚本语言


    1.JavaScript实现继承的4类方式

    先白话一下JavaScript为什么实现继承有那么多种方式,不像OC直接搞个类继承就可以了
    什么是对象
    --生活中的对象就是实物,一辆车,一台手机,一个人
    --对象具有特征(属性)和行为(方法)
    什么是面向对象
    --可以创建自定义的类型,很好的支持继承和多态.(即创建类)
    面向对象的语言很多,OC,swift,java,C++...
    --面向对象的特征:封装,继承,多态
    --万物皆对象:世间的一切事物都可以用对象来描述
    什么是基于对象
    --无法创建自定义的类型,不能很好的支持继承和多态.
    JS就是基于对象的.
    JS的继承是指一个对象可以使用另一对象的属性与方法

    1.1原型继承
    1.1.1

      <script>
           //《JavaScript语言精粹》作者提出了一个方式来实现继承
           function jicheng(obj){
               var o = {};
               o.__proto__ = obj;
               return o;
           }
    
           var obj1= jicheng({name:"邱淑贞"});
           console.log(obj1);
      </script>
    

    1.1.2

    <script>
        //原型继承
        //利用原型中的成员可以被和其相关的对象共享这一特性,可以实现继承
        //这种实现继承的方式,就叫做原型继承
        function Person(name, age){
            this.name = name;
            this.age = age;
        }
        //给原型对象中添加属性或者方法(通过对象的动态特性)
        //不是严格意义上的继承
        Person.prototype.say = function () {
            console.log("爱你呦");
        }
        Person.prototype.beauty = 100;
    
        //这里的p对象就继承原型
        var p = new Person("邱淑贞",18);
        p.say();//爱你呦
        console.log(p.beauty);//100
    
        //2.还可以直接替换原型对象
        var star = {
            say : function () {
                console.log("超级爱你呦");
            }
        }
        Person.prototype = star;
        var p2 = new Person("王祖贤",18);
        p2.say();//超级爱你呦
    </script>
    

    1.1.3

    <script>
        function Person(name, age){
            this.name = name;
            this.age = age;
        }
        Person.prototype.say = function () {
            console.log("爱你呦");
        }
        //直接替换原型对象方法
        //旧的原型中方法被覆盖了
        var star = {
            say : function () {
                console.log("超级爱你呦");
            }
        }
        Person.prototype = star;
        var p2 = new Person("王祖贤",18);
        p2.say();//超级爱你呦
    </script>
    

    1.2混入式继承

        <script>
          var obj1 = {
                name :"爸爸",
                age : 40,
                sayHello :function () {
                    console.log("Hello world");
                }
            }
            var obj2 = {
    
            }
    
            //混入式继承
            for(var k  in obj1){
                obj2[k] = obj1[k];
            }
            console.log(obj2);//打印Object
        </script>
    

    一般这么写:

      <script>
            // 实现混入的函数
            function extend(o1, o2) {
                for ( var key in o2 ) {
                    o1[key] = o2[key];
                }
            }
            // 构造函数Fn
            function Fn() {}
            // 给Fn默认的原型中混入字面量对象的value属性,
            // 这样Fn.prototype里也有了value属性。
            extend(Fn.prototype, {
                value: 100
            });
            // 通过Fn创建一个obj实例
            var obj = new Fn();
            // 因为实例继承Fn.prototype,所以可以使用value属性
            console.log(obj.value);//打印100
      </script>
    

    1.3经典继承Object.create()

      <script>
            //经典继承的语法
            //Object.create(obj)
            //返回值为一个对象,继承自参数中的obj
            //这个方法是ES5中出来的,所以存在兼容性问题,所以一般不用
            var obj1 = {
                name:"邱淑贞"
            };
            var obj2 = Object.create(obj1);
            console.log(obj2.name);//邱淑贞
      </script>
    

    不过也有处理的方法:

      <script>
            //如何处理Object.create的兼容性问题
            var obj = {
                name:"邱淑贞"
            };
    
            //检测浏览器的能力,如果没有Object.create方法就给他添加一个(不推荐使用)
            if(Object.create){
                var o = Object.create(obj);
            }else{
                Object.create = function () {
                    function F() {
                    }
                    F.prototype = obj;
                    var o = new F();
                }
                var o = Object.create(obj);
            }
    
            //自己定义个函数
            function create(obj){
                if(Object.create){
                    return Object.create(obj);
                }else{
                    function F() {
                    }
                    F.prototype = obj;
                    return new F();
                }
            }
      </script>
    

    1.4构造函数实现继承
    不懂可以看下我的这篇文章:<a href="http://www.jianshu.com/p/a888f53c0906">JS函数的4种调用模式</a>

      <script>
            function Person(){
                this.name = "邱淑贞";
                this.age = 18;
            }
    
            function Star(){
                var star = this;
                Person.apply(star);
            }
    
            var star = new Star();
            console.log(star);
      </script>
    

    3.JavaScript是一门'解释执行'的脚本语言

    如果我们将这段js代码放在<head>中,它将无法实现点击button换图片的功能,console出现爆红:

    <head>
      <script type="text/javascript">
        var img1 = document.getElementsByClassName('icon')[0];
        function changeImage() {
            img1.src = 'images/2.JPG';
        }
      </script>
    </head>
    <body>
      ![](images/1.jgp)
      <button onclick="changeImage();">更改图片</button>
    </body>
    

    而如果我们把js代码拿到<body>中最下面,又能实现这个功能了:

    <head>
    
    </head>
    <body>
      ![](images/1.jgp)
      <button onclick="changeImage();">更改图片</button>
      <script type="text/javascript">
        var img1 = document.getElementsByClassName('icon')[0];
        function changeImage() {
            img1.src = 'images/2.JPG';
        }
      </script>
    </body>
    

    这就是'解释执行'的意思了,从上到下依次执行.
    所以在第1份代码中拿到的img1为空,因为还没走到body中创建img;
    第2份代码中body中已经创建好了img,所以即使不在方法中也可以拿到img1.

    关于'解释执行'和'编译执行'整理了一下:
    计算机有个编译器是将一种语言转换成另一种语言(一般是机器语言)的东西,我们的编译执行类语言走这个机器;
    还有个解释器是执行一种语言的东西,解释执行语言走这个机器;
    解释器编译器可以为语言提供更高的复杂度,但执行效率不如编译器,二者背后的最大区别是:对解释执行而言,程序运行时的控制权在解释器而不在用户程序;对编译执行而言,运行时的控制权在用户程序;
    解释具有良好的[动态特性]和[可移植性]比如在解释执行时可以动态改变变量的类型、对程序进行修改以及在程序中插入良好的调试诊断信息等,而将解释器移植到不同的系统上,则程序不用改动就可以在移植了解释器的系统上运行。(这也就是JavaScript作为一种解释性脚本语言可以在浏览器上做抢火车票插件的原因)
    同时解释器也有很大的缺点,比如执行效率低,占用空间大,因为不仅要给用户程序分配空间,解释器本身也占用了宝贵的系统资源

    相关文章

      网友评论

        本文标题:JavaScript实现继承的4类方式

        本文链接:https://www.haomeiwen.com/subject/kfztbttx.html