原型对象
Posted 澎湃_L
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原型对象相关的知识,希望对你有一定的参考价值。
一、引入
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; VSCode自定义代码片段12——JavaScript的Promise对象