Prototype原型原型及原型链javaScript的es5的继承

Prototype原型

  • 0 原型的意义:
  • 1 es5对象中的方法在new出实例化对象时,是不同的方法,会造成资源浪费
  • 2 挂在prototype原型上的属性和方法可供new出的实例化对象所共享,节省资源
  • 3 实例化对象自身有该属性或方法就不会再去原型上找这个属性或方法了
  • 4 静态方法 实例方法
  • 5 静态属性 实例属性
  • 6 __proto__属性
  • 7 constructor属性
  • 8 instanceof 运算符[只能检测对象]
  • 9 方法
  • 10 es5继承

0 原型的意义:

	原型上挂载的属性和方法是为所有实例化对象所共享的,可以帮我们节省内存空间。
	每一个 JavaScript 对象(null 除外)在创建的时候就会与之关联一个对象,这个对象就是我们所说的原型。
	可以理解为原型是在模仿类的概念。

原型链
Prototype原型原型及原型链javaScript的es5的继承_第1张图片

1 es5对象中的方法在new出实例化对象时,是不同的方法,会造成资源浪费

		function Person(name,age){
            //  属性
             this.name = name;
             this.age = age;
            //  方法
            this.sayHello = function(){
                console.log("hello");
            }
         }
         
         var zhangsan = new Person("张三",20);
         var lisi = new Person("李四",22);
         
         zhangsan.sayHello(); //hello
         lisi.sayHello(); //hello

        // 说明每次通过new来创建新的对象的时候,都会创建一个新的sayHello方法,造成资源浪费
        // 这两个对象的sayHello方法不同
         console.log(zhangsan.sayHello=== lisi.sayHello);//false 

2 挂在prototype原型上的属性和方法可供new出的实例化对象所共享,节省资源

Person.prototype 就是原型对象,Person.prototype.xxx 是 我们自己 对原型对象进行的 扩展,目的就是 Person 构造函数的所有实例都可以 继承 这些属性或方法。
        
        function Person(name,age){
            this.name = name;
            this.age = age;
        }
        // 放在原型身上
        Person.prototype.sayHello= function(){
            console.log("hello");
        }
        Person.prototype.job = "it";

        var zhangsan = new Person("zhansgan",30);
        var lisi = new Person("lisi",25);

        zhangsan.sayHello(); // hello
        lisi.sayHello();// hello

        console.log(zhangsan.job);; //it
        console.log( lisi.job);;//it   

        console.log(zhangsan.sayHello === lisi.sayHello); // true
        console.log(zhangsan.job === lisi.job); // true

3 实例化对象自身有该属性或方法就不会再去原型上找这个属性或方法了

// 原型对象的作用,就是定义所有实例对象共享的属性和方法。
        function Person(){
            this.job = "it"; // 自身属性
        }
        console.log(Person.prototype);
        Person.prototype.job= "运营"; //原型属性

        var p1 = new Person();
        var p2 = new Person();
        p2.job = "客服"; // 可单独给对象的属性赋值,来改变值

        console.log(p1.job); // it
        console.log(p2.job); // 客服

4 静态方法 实例方法

//  实例: 实例方法  实例属性
       //  静态: 静态方法  静态属性

        function Person(name,age){
            this.name = name;
            this.age = age;
        }
        // 实例方法
        Person.prototype.sayHello = function(){
            console.log("hello");
        }
        // 静态方法
        Person.sayBye = function(){
            console.log("byebye");
        }

        // 实例方法调用————实例对象来调用 
        var p = new Person("zhangsan",20);
        p.sayHello(); // hello
        
        // 静态方法调用————类名.方法名 调用
        Person.sayBye(); //byebye

5 静态属性 实例属性

		function Person(name){
            this.name = name;
        }

        // 实例属性
        Person.prototype.hello = "hello";
        // 静态属性
        Person.bye = "bye";

        // 实例属性调用  实例对象.属性
        var P =  new Person();
        console.log( P.hello); // hello

        // 静态属性调用  类名.属性
        console.log(Person.bye); // bye

6 __proto__属性

:该属性只有浏览器环境下有,其他环境下没有这个属性。

        function Person(){}
        // 实例化对象
        var p = new Person();
        
        // 通过类名获取原型
        console.log(Person.prototype); // 以前是这样获得原型的

        // 通过实例对象P来获得原型,这里的每个下划线都是两个_
        console.log(p.__proto__); // 对象的原型  
        
        console.log(Person.prototype === p.__proto__); // true

7 constructor属性

constructor属性作用:当构造函数外部访问不到时,可以通过实例化对象在原型上继续扩展属性和方法,添加完成后可继续被其他实例化对象共享

        function Person(name){
            this.name = name;
        }
        var zs = new Person("zhangsan");
    	// 实例化对象的构造函数:就是Person函数
    	console.log(Person); // Person的函数体
        console.log(zs.constructor === Person); // true
        console.log(Person.prototype.constructor === zs.constructor); // true

8 instanceof 运算符[只能检测对象]

instanceof 运算符 返回一个布尔值,表示对象是否为某个构造函数的实例化对象,instanceof会检查整个原型链

 function Person(){}
 var p = new Person();
 console.log(p instanceof Person); //true: p是Person的实例对象
 console.log(p instanceof Object); //true   // instanceof会检测整个原型链

9 方法

Object.getPrototypeOf(实例化对象名称):获取实例对象的原型对象的标准方法

       function Person(){ }
       Person.prototype.getName= function(){}
       var zs = new Person();  
       
// 获取原型对象的三种方法
       console.log(Object.getPrototypeOf(zs)); // 方法一
       console.log(Person.prototype); // 方法二-通过类名获取原型
       console.log(zs.__proto__);// 方法三-只有浏览器可用【不推荐】
       
       console.log(Person.prototype === zs.__proto__); // true
       console.log(Object.getPrototypeOf(zs) === Person.prototype); // true

Object.create() 方法: es5继承,让一个对象继承另一个对象的属性和方法。
在原型上添加或修改任何方法,会立刻反映在新对象之上
方法还可接受第二个参数。该参数是一个属性描述对象,它所描述的对象属性,会添加到实例对象,作为该实例对象自身的属性。

 	  function Parent(){
 	 		 // 属性
           this.name = '张三';
       }

       function Son(){
          // 属性继承,此处this的指向是Son的实例化对象
          // apply将Parent类中的this指向变成了Son的实例化对象,所以Son类继承了Person的属性
           Parent.apply(this);
       }

       Parent.prototype.getName = function(){
           console.log("111");
       }

       // 子类继承父类Object.create()
       Son.prototype = Object.create(Parent.prototype);
       var s = new Son(); // 子类的实例化对象
       s.getName(); // 111
       console.log(s.name); // 张三
        var animal = {
            cat:"猫",
            dog:{
                value:"狗"
            }
        }
        // create第二个属性必须是一个对象类型
        var zoo = Object.create(animal,{
            pig:{
                value:"猪"
            }
        });
        console.log(zoo.cat); // 猫
        console.log(zoo.pig); // 猪

10 es5继承

        function Person(name,age){
            this.name = name;
            this.age = age;
        }
        Person.prototype.getName = function(){
            console.log(this.name); 
        }
        Person.prototype.getAge = function(){
            console.log(this.age);
        }
        
        function Student(name,age,learn){
            // 继承属性
            Person.call(this,name,age);  // Person中的this指向变成了student,name/age为Person中传的参数
            this.learn = learn;
        }


// 继承--------------------------------------------------
        // 【本程序重点】继承父类方法
        for(var p in Person.prototype){
            Student.prototype[p] = Person.prototype[p];
        }
// -------------------------------------------------------

        // 给学生添加自己的原型方法
        Student.prototype.getLearn = function(){
            console.log("学习");
        }
        // 就近原则:自己身上有用自己的,自己身上没有用继承的
        Student.prototype.getName = function(){
            console.log("姓名:"+this.name);
        }
        var student = new Student("zs",19);
        student.getAge(); // 19
        student.getName(); // zs
        student.getLearn(); // 学习
        function Eat(){
            // 属性
            this.eat = "吃猫粮";
        }
        // 实例方法
        Eat.prototype.getEat = function(){
            console.log('小猫吃猫粮');
        }

        function Voice(){
            // 属性
            this.voice = "喵喵喵";
        }
        // 实例方法
        Voice.prototype.getVoice = function(){
            console.log('小猫喵喵喵');
        }

        function Cat(name){
            // apply改变this指向,完成属性继承
            Eat.apply(this);
            Voice.apply(this);
            // name参数是Cat类自身的属性
            this.name = name;
        }

// 多重继承------------------------------------------
        // Cat继承Eat类和Voice类
        // Object.create()  Cat先继承Eat类
        Cat.prototype = Object.create(Eat.prototype);
        // Object.assign()  继承Eat类后的Cat类与Voice类合并
        Object.assign(Cat.prototype,Voice.prototype);
        // 完成继承后Cat类的原型对象少一个构造方法,加上
        Cat.prototype.constructor = Cat;
// ----------------------------------------------------------
        console.log(Cat.prototype);

        // 给Cat添加自身的实例方法
        Cat.prototype.getName = function(){
            console.log('花花花');
        }

		// 实例化对象
        var hh = new Cat('花花');
        hh.getEat(); // 小猫吃猫粮
        console.log(hh.eat); // 吃猫粮
        hh.getVoice(); // 小猫喵喵喵
        console.log(hh.voice); // 喵喵喵
        hh.getName(); // 花花花
        console.log(hh.name); // 花花

参考图片:
Prototype原型原型及原型链javaScript的es5的继承_第2张图片
Prototype原型原型及原型链javaScript的es5的继承_第3张图片

你可能感兴趣的:(web前端,javascript,原型模式,前端)