js19--继承终极版本

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Untitled Document</title>
        <script type=text/javascript charset=utf-8>
        function extend(Child ,Parent){
             var F = new Function();//创建一个函数F,跟写 function F(){};一样
             F.prototype = Parent.prototype; 
             Child.prototype = new F(); 
             Child.prototype.constructor = Child ;
             
             //保存一下父类的原型对象: 一方面方便解耦  另一方面方便获得父类的原型对象
             Child.superClass = Parent.prototype; //自定义一个子类的静态属性 保存父类的原型对象,写 Child.superClass = Parent也可以。保证子类中可以找到父类。
             alert(Parent.prototype.constructor);
             alert(Parent);
             /*function Person( name , age){
                this.name = name ; 
                this.age = age ; 
            }*/
             alert(Parent.prototype.constructor ===  Parent);//true
             //判断父类的原型对象的构造器 (加保险),Person.prototype = {中不写constructor: Person ,那么Parent.prototype.constructor就是Object
             if(Parent.prototype.constructor == Object.prototype.constructor){
                Parent.prototype.constructor = Parent ; //容错性,就是写出你不知道的情形。
             }
        }
        
        
        function Person( name , age){
            this.name = name ; 
            this.age = age ; 
        }
        
        Person.prototype = {
            sayHello: function(){
                alert('hello world!');
            }
        };
        Object.defineProperty(Person.prototype , 'constructor' , {
             enumerable : false , 
             value : Person 
        });
        Person.prototype.say = function(){
            alert('hello world!');
        }
        
        function Boy(name , age , sex){
            //call,子类就可以直接new Boy(传3个参数),否则只能通过父类实例对象来访问添加的属性。
            //Person.call(this,name,age); Boy.superClass.constructor=Person,解耦,子类中不写父类的东西。
            Boy.superClass.constructor.call(this , name , age);
            this.sex = sex ;
        }
        extend(Boy , Person);
        Boy.prototype.sayHello = function(){//覆盖父类的方法
            alert('hi javascript!');
        }
        
        
        
        
        var b = new Boy('张三' , 20 , '');
        alert(b.name); //张三
        alert(b.sex);//
        b.sayHello();//hi javascript!
        //调用父类方法
        Boy.superClass.sayHello.call(b);//hello world!
        b.__proto__.__proto__.sayHello();//hello world!
        b.constructor.prototype.__proto__.sayHello()//hello world!
        alert(Boy.superClass.constructor);
        /*function Person( name , age){
            this.name = name ; 
            this.age = age ; 
        }*/
        </script>
    </head>
    <body>
    </body>
</html>
第一,子类调用call方法。
第二,子类原型对象的构造函数要改变,原型对象和自己对象的构造器指向函数本身(函数本身的prorotype和对象的__proto__指向原型对象)。
第三,子类增加一个静态属性指向父类的原型对象,办证子类可以找到父类。
第四,子类原型对象新增属性要写在creat之后,因为creat之后子类才有了原型对象。



function F(){
    this.name = "yw";
    var age = 32;
    sch = 890;
}    

var f = new F();  
alert(f.name);//yw
alert(f.age);//undefined
alert(f.sch);//undefined
alert(window.name);//空
F();
alert(window.name);//yw


var F = new Function();//创建一个函数F,跟写 function F(){};一样

//可以直接写constructor,prototype,不能写__proto__,_proto__是为了表示对象是怎么找到类的原型对象的属性方法的。

子类通过prototype访问父类原型对象的属性、方法。

子类通过call访问父类实例对象的属性、方法。不加call方法,访问不到父类实例对象的属性、方法。

父类和对象以静态方式加的属性、方法,子类对象访问不到。

 

posted @ 2017-05-19 13:45  无天666  阅读(351)  评论(0编辑  收藏  举报