zoukankan      html  css  js  c++  java
  • 原型对象(上)

    一、引入

    1、JS是一门脚本语言,解释型语言、弱类型语言、基于对象的语言、动态型语言

    2、继承(面向对象有三个特性:封装、继承、多态  )是指类与类之间的关系,JS中没有类的概念,JS中有构造函数的概念,是可以继承的,是基于原型

    3、创建对象的三种方法:字面量、系统方法构造函数、自定义构造函数

       <script>
        //字面量
        var per1={
            name:"刘备",
            age:25,
            show:function(){
                console.log("双股剑");
            }
        }
        //系统方法构造函数创建对象
        var per2=new Object;
        per2.name="张飞";
        per2.age=23;
        per2.show=function(){
            console.log("丈八蛇矛");
        }
        //自定义构造函数创建对象
        function Person(name,age){
            this.name=name;
            this.age=age;
            this.show=function(){
                console.log("青龙偃月刀");
            }
        }
        var per3=new Person("关羽",24)
        </script>

    4、工厂模式和自定义构造函数的区别

    • 共同点:都是函数、都可以创建对象、都可以传入参数
    • 工厂模式:函数名小写,有new,有返回值,new之后的对象是当前的对象,对象创建,直接调用函数
    • 自定义构造函数:函数名大写(首字母),没有new,没有返回值,this是当前对象,对象创建,通过new出来(实例化对象)
       <script>
        //自定义构造函数创建对象
        function Person(name,age){
            this.name=name;
            this.age=age;
            this.show=function(){
                console.log("青龙偃月刀");
            }
        }
        var per1=new Person("关羽",24);
        //工厂模式创建对象
        function creatObj(name,age){
                var obj= new Object;
                obj.name=name;
                obj.age=age;
                obj.show=function( ){
                    console.log("青釭剑");
                }
                return obj;
        }
        var per2=new creatObj("赵云",29);

    5、构造函数和实例函数之间的关系

    • 注意:使用console.dir可以查看结构
    • 实例对象是通过构造函数来创建的,创建的过程叫实例化
    • 实例化对象会指向自己的构造函数(暂时理解)
    • 判断对象是不是这个数据类型,可以通过构造器的方法(实例对象.构造器==构造器名字)或者instanceof(对象 instanceof 构造函数名字 ),推荐后者
       <script>
        function Person(name,age){
            this.name=name;
            this.age=age;
            this.show=function(){
                console.log("青龙偃月刀");
            }
        }
        var per=new Person("关羽",24);
        //查看结构---看下图
        console.dir(Person);//构造函数
        console.dir(per);//实例对象
        //判断对象是不是这个数据类型
        //方法一:
        console.log(per instanceof Person);//true
        //方法二:
        console.log(per.constructor==Person);//true
        </script>

    6、构造函数创建对象带来的问题

    • 产生多个内存空间
        <script>
            //创建的两个实例对象的方法虽然相同,但是并不相等,如果创建的对象过多,就会使占用过多内存
            function Person(name,age){
                this.mame=name;
                this.age=age;
                this.eat=function(){
                    console.log("吃饭");
                }
            }
            var per1=new Person("李白",44);
            var per2=new Person("杜甫",50);
            console.log(per1.eat==per2.eat);//false
        </script>
    • 可以通过使用命名函数方法解决,但是可能会有变量冲突
        <script>
            //通过使用命名函数方法解决,但是可能会有变量冲突-----最好引入原型
            function Person(name,age){
                this.mame=name;
                this.age=age;
                this.eat=myEat;
            }
            function myEat(){
                console.log("吃饭");
            }
            var per1=new Person("李白",44);
            var per2=new Person("杜甫",50);
            console.log(per1.eat==per2.eat);//true
        </script>
    • 所以最好引入原型来解决

    二、原型对象

    1、构造函数创建函数带来的问题,可以通过原型的方法解决-----原型的作用之一:可以实现数据共享,节省内存空间

    2、通过原型来添加方法:构造函数.prototype.方法名=一个函数

       <script>
        function Person(name,age){
            this.mame=name;
            this.age=age;
        }
        Person.prototype.eat=function(){
                console.log("吃饭");
            }
        var per1=new Person("李白",44);
        var per2=new Person("杜甫",50);
        console.log(per1.eat==per2.eat);//true
        </script>

    3、案例:点击按钮改变div样式(使用原型的方法)

    4、什么是原型?

    • 实例对象中有个属性,__proto__,也是对象,叫原型,不是标准的属性,在IE8中可能不支持,主要给是给浏览器使用的
    • 构造函数中有个属性,prototype,也是对象,叫原型,是标准属性,主要给程序开发人员使用
    • 所以原型就是__proto__或者prototype,都是原型对象

    5、构造函数、原型对象、实例对象之间的关系(画图)

    • 构造函数可以实例化对象,产生实例对象
    • 构造函数中有一个属性,prototype,是构造函数的原型对象
    • 构造函数的对象中有一个构造器(constructor)指向构造函数本身
    • 实例对象中的原型对象,__proto__,指向的是该构造函数的原型对象(prototype)
    • 构造函数的原型对象(prototype)中的方法是可以被实例对象直接访问的
      <script>
            //自定义构造函数
            function Person(name,age){
                this.age=age;
                this.name=name;
            }
            //通过原型添加方法
            Person.prototype.sayHi=function(){
                console.log("hello");
            }
            //实例化对象
            per=new Person("小明",20);
            console.dir(Person);
            console.dir(per);
        </script>

    6、利用原型共享数据

    • 需要共享的数据可以写在原型中,可以是属性或者方法
    • 不影响共享的数据写在构造函数中,需要共享的数据写在原型中
        <script>
            //自定义构造函数
            function Student(name,age){
                this.name=name;
                this.age=age;
            }
            //通过原型添加相同的数据,实现共享
            Student.prototype.height="180cm";
            Student.prototype.weight="100kg";
            Student.prototype.sex="都是男的";
            
            //实例化对象
            stu1=new Student("关羽",30);
            stu2=new Student("刘备",31);
            stu3=new Student("张飞",29);
            console.log(stu1.height);//180cm
            console.log(stu2.weight);//100kg
            console.log(stu3.sex);//都是男的
        </script>

    7、简单的原型写法

    • 格式:构造函数.prototype={  属性或者方法  }
    • 但是这种写法需要手动修改构造器的指向----constructor:构造函数名
       <script>
            //自定义构造函数
            function Student(name,age){
                this.name=name;
                this.age=age;
            }
            //通过原型添加相同的数据,实现共享
            //简单的原型写法(放进一个对象里)
            //但是必须要手动修改构造器的指向
            Student.prototype={
                constructor:Student,
                height:"180cm",
                weight:"100kg",
                sex:"都是男的"
            }
            
            //实例化对象
            stu1=new Student("关羽",30);
            stu2=new Student("刘备",31);
            stu3=new Student("张飞",29);
            console.log(stu1.height);//180cm
            console.log(stu2.weight);//100kg
            console.log(stu3.sex);//都是男的}
        </script>

    8、原型中的方法是可以互相进行访问的

       <script>
            //自定义构造函数
            function Student(name,age){
                this.name=name;
                this.age=age;
            }
            //通过原型添加方法
            Student.prototype.eat=function(){
                console.log("吃饭");
            };
            Student.prototype.sleep=function(){
                console.log("睡觉");
                this.eat();//添加eat方法
            };
            Student.prototype.play=function(){
                console.log("玩球");
                this.sleep();//添加sleep方法
            };
            //实例化对象
            var per=new Student("小明",20);
            per.eat();//吃饭
            per.sleep();//睡觉 吃饭
            per.play();//玩球 睡觉 吃饭
        </script>

    9、原型的层层搜索

    • 实例对象使用的属性或者方法,先在实例对象中找,找到了则直接使用
    • 找不到则去实例对象的__proto__指向的原型对象prototype中找,找到了使用
    • 找不到则报错
       <script>
            //自定义构造函数
            function Student(name,age){
                this.name=name;
                this.age=age;
                this.eat=function(){
                   console.log("构造函数中的吃饭");
                }
            }
            //通过原型添加方法
            Student.prototype.eat=function(){
                console.log("原型中的吃饭");
            };
            //实例化对象
            var per=new Student("小明",20);
            per.eat();//构造函数中的吃饭
            //说明实例对象调用方法时,首先在构造函数中寻找这个方法,没有的话,再去原型__proto__去找这个方法
        </script>

    10、为系统内置对象添加原型方法(相当于改变源码)

        <script>
        //例1:字符串中添加一个倒序字符串的方法
        String.prototype.myReverse=function(){
            for(var i=this.length-1;i>=0;i--){
               console.log(str[i]);
            }
        };
        var str="abcd123";
        str.myReverse();//3 2 1 d c b a
        //例2:数组内置对象添加一个方法sayHi
        Array.prototype.sayHi=function(){
            console.log("猴赛雷!!!")
        };
        var arr=[1,2,3];
        arr.sayHi();//猴赛雷!!!
        </script>

    11、把局部变量变成全局变量------把局部变量给window就可以了

       <script>
            (function(){
                var num=10;
                //js是一门动态类型的原因,对象没有属性,点了就有了
                window.num=num;
            })();
            console.log(num);//10
            //结论:把局部变量给Window就可以变成全局变量
        </script>

    12、案例:随机小方块(相当于贪吃蛇案例的食物)

        <div class="map" style=" 800px;height: 800px;background: #ccc;position: relative;"></div>
        <script>
        //产生随机对象的
        (function (window){
            //产生随机数的构造函数
            function Random(){
    
            }
            //在原型中添加方法
            Random.prototype.getRandom=function(min,max){
                return Math.floor(Math.random()*(max-min)+min);
            };
            //把random对象暴露给顶级对象window---->外部可以直接使用这个对象
            window.Random=new Random();//直接示例化对象
        })(window);
        //产生小方块对象
        (function(window){
            //选择器的方法获取元素对象
            var map=document.querySelector(".map");
            //小方块的构造函数
            function Food(width,height,color){
                //默认的小方块的高和宽
                this.width=width||20;
                this.height=height||20;
                //横坐标和纵坐标
                this.x=0;
                this.y=0;
                //小方块的背景颜色
                this.color=color;
                //小方块的元素
                this.element=document.createElement("div");
            }
            //初始化小方块的显示和效果及位置---显示在地图上
            Food.prototype.init=function(map){
                //设置小方块的样式
                var div=this.element;
                div.style.position="absolute";
                div.style.width=this.width+"px";
                div.style.height=this.height+"px";
                div.style.backgroundColor=this.color;
                //把小方块加到地图中
                map.appendChild(div);
                this.render(map);
            };
            //产生随机位置
            Food.prototype.render=function(map){
                //随机产生横坐标
                var x=Random.getRandom(0,map.offsetWidth/this.width)*this.width;
                var y=Random.getRandom(0,map.offsetHeight/this.height)*this.height;
                this.x=x;
                this.y=y;
                var div=this.element;
                div.style.left=this.x+"px";
                div.style.top=this.y+"px";
            };
            var fd=new Food(20,20,"red");
            fd.init(map);
            console.log(fd.x+"========"+fd.y);
        })(window);
        </script>

  • 相关阅读:
    PSP编程
    题库软件1.0发布
    ubuntu上安装netgear wg511v2驱动
    boost的编译
    Plot3D 0.3发布
    立体画板Plot3D
    求教团队内的朋友,在directx中,如何画虚线?
    OpenGL如何显示文本?
    JZ028数组中出现次数超过一半的数字
    JZ027字符串的排列
  • 原文地址:https://www.cnblogs.com/EricZLin/p/9049002.html
Copyright © 2011-2022 走看看