js深入理解构造函数和原型对象
1.在典型的oop的语言中,如java,都存在类的概念,类就是对象的模板,对象就是类的实例。但在js中不存在类的概念,js不是基于类,而是通过构造函数(constructor)和原型链(prototype chains)实现的。但在ES6中引入了类(class)这个概念,作为对象的模板,新的class写法知识让原型对象的写法更加清晰,这里不重点谈这个
2.首先我们来详细了解下什么是构造器
构造函数的特点:
a:构造函数的首字母必须大写,用来区分于普通函数
b:内部使用的this对象,来指向即将要生成的实例对象
c:使用New来生成实例对象
eg1:
 function Person(name,age){
      this.name = name;
      this.age = age;
      this.sayHello = function(){
          console.log(this.name +"say hello");
     }
 }
 var boy = new Person("bella",23);
 boy.sayHello(); // bella say hello
构造函数的缺点:
所有的实例对象都可以继承构造器函数中的属性和方法。但是,同一个对象实例之间,无法共享属性
解决思路:
a:所有实例都会通过原型链引用到prototype
b:prototype相当于特定类型所有实例都可以访问到的一个公共容器
c:那么我们就将重复的东西放到公共容易就好了
eg2:
 function Person(name,age){
     this.name = name;
     this.age = age;
     this.sayHello = function(){
         console.log(this.name + "say hello");
     }
 }
 var girl = new Person("bella",23);
 var boy = new Person("alex",23);
 console.log(girl.name);  //bella
 console.log(boy.name);   //alex
 console.log(girl.sayHello === boy.sayHello);  //false
      
一个构造函数Person生成了两个对象实例girl和boy,并且有两个属性和一个方法。但是sayHello方法是不一样的。如上图(图画得很丑)。也就是说当New一个实例对象的时候,都会去创建一个sayHello方法,这就浪费了内存资源,因为sayHello方法使一样的行为的,完全可以被两个实例对象共享。
所以,缺点就是:同一个构造函数的对象实例之间无法共享属性和方法。
为了解决构造函数的这个缺点,js提供了prototype属相来解决该问题。
prototype属性的作用
js中每个数据类型都是对象,除了null 和 undefined(这个可以参考另一篇将null 和 undefined的博客),而每个对象都是继承自一个原型对象,只有null除外,它没有自己的原型对象,最终的Object的原型为null
eg3:
 function Person(name,age){
     this.name = name;
     this.age = age;
 }
 Person.propotype.sayHello = function(){
     console.log(this.name + "say hello");
 }
 var girl = new Person("bella",23);
 var boy = new Person("alex",23);
 console.log(girl.name);  //bella
 console.log(boy.name);   //alex
 console.log(girl.sayHello === boy.sayHello);  //true
                   
由上图可以看出,prototype是构造函数的属性,而consructor则是构造函数的prototype属性所指向的那个对象,也就是说constuctor是原型对象的属性。
constructor属性是定义在原型对象上面,意味着也可以被实例对象继承
eg4:
 function Person(name,age){
     this.name = name;
     this.age = age;
 }
 Person.propotype.sayHello = function(){
     console.log(this.name + "say hello");
 }
 var girl = new Person("bella",23);
 console.log(girl.construcotr); //Person()
 console.log(girl.construcotr == Person.propotype.construcotr); //true
constructor属性的作用
a:分辨原型对象到底是哪个构造函数
 function Person(){};
 var person1 = new Person();
 console.log(person1.construcotr === Person); //true
b:从实例新建另一个实例
 function Person(){};
 var person1 = new Person();
 var person2 = new person1.construcotr();
 console.log(person2 instanceof Person); //true
c:由于constructor属性是一种原型对象和构造函数的关系,所以在修改原型对象的时候,一定 要注意construtor的指向问题,避免instanceof失真,关于这一点,会在继承中讲到。
3.了解了构造器,我们来看下原型prototype
JS中万物都是对象,但是对象也分为:普通对象和函数对象,也就是Object 和 Function.
那么怎么区分普通对象和函数对象呢? ---凡是通过New Function()创建的对象都是函数对象,其他的都是普通对象.
需要注意的是:普通对象没有propotype(prototype即是属性也是对象),但是有__proto__属性。
js创建对象的时候都有一个__propo__内置属性,用于指向创建它的函数对象的原型对象prototype。
我们还是来根据eg3的代码来分析原型链
console.log(girl.__proto__ === Person.protype);//true
console.log(Persion.propotype.__proto__ === Object.propotype);//true
console.log(Object.porpotype.__proto__); //null
通过__proto__串起来直到Object.propotype.__proto__为null的链叫做原型链(矩形表示函数对象,椭圆形表示普通对象)
  
也许看到这个图会有几个疑问
a:为什么Object.__proto__指向Function.prototype?
Object是函数对象,是通过new Function()创建的,所以...
b:Function.__proto__ === Function.prototype //true
Function也是对象函数,通过new Function()创建,所以...
js深入理解构造函数和原型对象的更多相关文章
- 第186天:js深入理解构造函数和原型对象
		1.在典型的oop的语言中,如java,都存在类的概念,类就是对象的模板,对象就是类的实例.但在js中不存在类的概念,js不是基于类,而是通过构造函数(constructor)和原型链(propoty ... 
- Javascript深入理解构造函数和原型对象
		1.在典型的oop的语言中,如java,都存在类的概念,类就是对象的模板,对象就是类的实例.但在js中不存在类的概念,js不是基于类,而是通过构造函数(constructor)和原型链(propoty ... 
- 怎样理解构造函数的原型对象prototype
		通过构造函数生成的实例对象中的属性和方法其实是从构造函数中"copy"一份后生成的, 也就是说虽然生成的对象是构造函数的实例, 但里面的属性和方法确实相互独立的, 比如下面的lil ... 
- 深入理解Javascript中构造函数和原型对象的区别
		在 Javascript中prototype属性的详解 这篇文章中,详细介绍了构造函数的缺点以及原型(prototype),原型链(prototype chain),构造函数(constructor) ... 
- 深入理解Javascript中构造函数和原型对象的区别(转存)
		Object是构造函数,而Object.prototype是构造函数的原型对象.构造函数自身的属性和方法无法被共享,而原型对象的属性和方法可以被所有实例对象所共享. 首先,我们知道,构造函数是生成对象 ... 
- Js中关于构造函数,原型,原型链深入理解
		在 ES6之前,在Javascript不存在类(Class)的概念,javascript中不是基于类的,而是通过构造函数(constructor)和原型链(prototype chains)实现的.但 ... 
- 构造函数、原型对象prototype、实例、隐式原型__proto__的理解
		(欢迎一起探讨,如果有什么地方写的不准确或是不正确也欢迎大家指出来~) PS: 内容中的__proto__可能会被markdown语法导致显示为proto. 建议将构造函数中的方法都定义到构造函数的原 ... 
- JS中构造函数与原型对象的同名属性,实例会取哪一个
		构造函数与原型对象的同名属性,实例会取哪一个? 看了下面的过程,再回忆JS高程3里关于这部分的示意图.实例my在new的时候,本身就获得了a属性,所以my.a是1,倘若在new的时候如果没有赋予a属性 ... 
- javascript构造函数以及原型对象的理解
		以下是一个构造函数的例子 如果是实例方法,不同的实例化,它们引用的地址是不一样的,是唯一的. //定义一个构造函数 function People(name,age){ this.name=name; ... 
随机推荐
- git 客户端提交
			01 按照git到本地 02 按照小乌龟操作面板, 03 (git 和小乌龟)自动加载到右键快捷方式 
- php 分析
			php code in D:\10\11\php test in D:\10\11\php\test issue 1: <html><head><title>标记 ... 
- 7. Shell 函数
			1. 格式 [ function ] funname [()] { action; [return int;] } 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数 ... 
- set, list 和map知识总结
			set就是集,无序,不可重复 举例:HashSet,LinkedHashSet List是映射,通过键值对存储,无序,不可重复 举例:HashMap,HashTable,LinkedHashMap 在 ... 
- laravel利用subquery使左连接查询右表数据唯一查询
			如:表a,连接表b,b中有多条符合查询的记录 1.建立需要的子查询 $sub = DB::table('b')->select(['aid'])->selectRaw('max(id) a ... 
- 小demo--横向+展开菜单,支持m站
			<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ... 
- OpenCV程序在Debug时出现「PDB文件无法加载」的一个解决方法
			这几天毕设要用到OpenCV,按照网上的教程来搭建开发环境. 用的是OpenCV 3.0 beta + Visual Studio Community 2013.我的系统64位是Win 8.1,但在加 ... 
- windows10安装composer并解决和xdebug的冲突
			环境:windows10,php7,php安装目录C:\php\,php目录已加入windows的PATH. 1.下载composer,在Windows下最简单的办法是下载composer.phar并 ... 
- 重读The C programming Lanuage 笔记三:简单计算器程序
			//简单计算器 #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <str ... 
- Python朝花夕拾
			Q1:HTTP Error 403: Forbidden python中经常使用urllib2.urlopen函数提取网页源码,但是有些时候这个函数返回的却是:HTTP Error 403: Forb ... 
