javascript详解函数原型对象prototype与constructor
1.原型模式
首先我们来谈谈prototype属性,也就是原型属性。每当我们创建一个函数时,函数内部都会自动生成一个指针(既自动生成一个属性就是我们说的prototype),这个指针指向指向原型对象,这个对象的用途是包含可以由它特定类型的所有实例共享的属性和方法,用大白话解释这句话:就是通过用构造函数而创建的它本身这一类的那些对象实例共享原型对象中的属性和方法。注意prototype这个属性在函数中直接看是看不到的,我们可以通过打印函数的prototype来查看。原型对象中会自动生成一个constructor(构造函数)的一个属性:这个属性的指针会指向本函数。有人可能不知道原型对象是什么,其实很好理解,函数的prototype属的值其实就是一个对象(即原型对象)。
下面是原型与实例还有构造函数之间的关系(画的不太好谅解。。)
function Hanshu(){console.log("hi")}console.log(Hanshu.prototype) console.log(Hanshu.prototype.constructor)
第一个console打印出来的就是原型对象(既prototype对应的值),点进去里面会有函数的一些属性,对象里面有一个constructor的一个属性。当我们再去打印prototype属性里面的constructor属性的时候打印出本函数体。
接着我们来看共享原型对象属性的例子。
function Hanshu(a,b,c){this.name=a;this.age=bthis.job=c}Hanshu.prototype.gongxiang="我是原型对象中的一个属性我被所以实例所共享"var a=new Hanshu("大牛","30","装") var b=new Hanshu("大牛2","300","傻")console.log(a.gongxiang) //我是原型对象中的一个属性我被所以实例所共享console.log(b.gongxiang) //我是原型对象中的一个属性我被所以实例所共享
我们可以看到当给Hanshu的原型对象添加属性的时候,在Hanshu的所有实例中都可以访问到gongxiang这个属性,上面这段代码解释了函数原型对象中的属性和方法被它的所有实例所共享。
接下来我们探索一下解释器在读代码的时候,是先访问的实例还是原型对象的问题。
function Hanshu(a,b,c){this.name=a;this.age=bthis.job=cthis.gongxiang="我是实例里面的属性" //新添加了一个属性}Hanshu.prototype.gongxiang="我是原型对象中的一个属性我被所以实例所共享"var a=new Hanshu("大牛","30","装") var b=new Hanshu("大牛2","300","傻")console.log(a.gongxiang) //我是实例里面的属性console.log(b.gongxiang) //我是实例里面的属性
上面这段代码唯一改变的就是我们在函数里面添加了一个与原型对象中属性一致的名字,这个时候我们再去访问实例里面的gongxiang这个属性的时候发现它打印出来的是实例里面的属性。也就是说解释器在读取代码的时候,首先先去实例里面找gongxiang这个属性,然后才回去找原型里面的属性,注意这里函数实例里面的属性屏蔽掉了原型里面的属性。也许这个例子让你感觉不到访问先后顺序,那我们在来改变一下代码位置。
function Hanshu(a,b,c){this.name=a;this.age=bthis.job=c}var a=new Hanshu("大牛","30","装") var b=new Hanshu("大牛2","300","傻")Hanshu.prototype.gongxiang="我是原型对象中的一个属性我被所以实例所共享" //先创建实例在给原型添加属性console.log(a.gongxiang) //我是原型对象中的一个属性我被所以实例所共享console.log(b.gongxiang) //我是原型对象中的一个属性我被所以实例所共享
上面这段代码我们又改变的代码顺序,我们先创建里实例,然后才给原型添加的属性,这个时候依然可以访问到gongxiang这个属性,这就是原型模式的动态属性,当解释器去读取代码的时候,先去访问实例中的代码,发现没有,然后就去访问原型对象,发现有这个属性,再把它读出来。
关于原型对象的从写:
我们一遍一遍的重复的写类似obj.prototype.xxx=???这样的语法太麻烦了,既然原型对象是对象,那我们可以直接去定义原型对象,可以一样问题来了constructor本来是原型对象里面自动执行函数本身的,由于从写constructor不再执行原函数。还有书上并没有说从写原型对象以后,原型对象是否还跟属性共享的问题。请看以下代码
function Abc(){}Abc.prototype={name:"ffk",age:10,job:"work"}var Hanshu=new Abc()console.log(Hanshu.name)//ffk console.log(Abc.prototype)//
原型从写以后原型对象里面的属性和方法依旧被共享。可是当我们去打印构造函数的原型对象的时候,constuctor不再指向函数本身,而是继承obj。
其实从写原型函数带来的问题还是有一些的,我们继续看一下代码
function Abc(){}var Hanshu=new Abc() //换了位置放到了前面Abc.prototype={name:"ffk",age:10,job:"work"}console.log(Hanshu.name)// undefined
★★★重要
当我们把对象创建放到从写原型对象之前,发现再去访问的时候,已经找不到属性了,虽然之前我们说过解释器在读代码的时候先去实例里面找然后再去原型里面找(动态属性)。
在从写原型对象的情况下,也就是说我们创建对象实例之前,你并没有告诉解释器我的原型对象要换对象了,所以在它创建实例的时候它的实例内部指针还指向的是默认的那个最初的原型对象,等你后面再从写原型对象的时候已经晚了,最初原型对象中只有coustructor属性,没有name,所以打印出来是undefined(书上不是这样说的,我是按我自己的理解来解释的,我感觉这样说比书上更好理解。。大家这样理解就行了没问题的)。
转载于:https://www.cnblogs.com/kazy/p/8621103.html
javascript详解函数原型对象prototype与constructor相关推荐
- fread函数详解 函数原型
函数原型: size_t fread( void *buffer, size_t size, size_t count, FILE *stream ) b ...
- 详解JS原型链与继承
详解JS原型链与继承 JavaScript 目录 摘自JavaScript高级程序设计: 概念 确定原型和实例的关系 原型链的问题 借用构造函数 组合继承 原型继承 寄生式继承 寄生组合式继承 new ...
- 深入详解函数的柯里化
深入详解函数的柯里化 一.补充知识点之函数的隐式转换 JavaScript作为一种弱类型语言,它的隐式转换是非常灵活有趣的.当我们没有深入了解隐式转换的时候可能会对一些运算的结果会感动困惑,比如4 + ...
- JavaScript详解一
问题?JavaScript详解 1.在 JavaScript 函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它.(该变量的作用域是局部的). 您可以在不同的函数中使用名称相同的局 ...
- watch深度监听数组_vue watch普通监听和深度监听实例详解(数组和对象)
vue watch普通监听和深度监听实例详解(数组和对象) 下面通过一段代码给大家介绍vue watch的普通监听和深度监听,具体代码如下所示: var vm=new Vue({ data:{ num ...
- Javascript详解
Javascript详解 案例一:使用JS完成注册页面的校验 案例介绍 用户在提交表单是,需要对用户填写的数据进行校验.因为用户如果输入非法内容,则会导致服务器的压力过大,因此,一般提供前端校验和后 ...
- 【JavaScript详解】一文掌握JavaScript基础知识(上)
JavaScript基础 前言 一.什么是JavaScript 1.JavaScript概述 2.javaScript有什么作用 二.JavaScript快速入门 1.引入JavaScript 2.基 ...
- 详解JS原型与原型链
目录 1.构造函数原型prototype 2.对象原型__proto__ 3.constructor构造函数 4.原型链 5.原型对象中的this指向 6.扩展内置对象(原型对象的应用) 在ES6之前 ...
- Typescript之原型对象prototype深入了解
Typescript之原型对象prototype 文章目录 Typescript之原型对象prototype 前言 一.prototype是什么? 1.对象实例的\_\_proto__属性 2.Obj ...
最新文章
- python 空数组_【python三级】二维数组的表示
- 呢篇唔系教程 -- 记录自己第一次Android刷机
- docker-compose执行报错(selinux所致):write /proc/self/attr/keycreate: permission denied
- 关于编写性能高效的javascript事件的技术
- 移动app崩溃原因及场景
- 二叉树的遍历(非递归方式)
- python response重头开始_你必须学写 Python 装饰器的五个理由
- Zookeeper日志文件事务日志数据快照
- Matlab系列教程_基础知识_程序控制
- 台式计算机文件打不开怎么回事,电脑文件打不开怎么回事
- Visual C++ 6.0 Processor Pack 编译xvidcore1.1.0
- 英语单词中后缀-ee和-er的区别
- np.dot、np.outer、np.matmul、np.multipy、np.inner、np.outer与np.cross几个函数之间的区别
- S5p4418 启动配制分析
- Windows 下网卡对802.1Q tag 的支持
- python读取excel数据使用pyecharts展示
- 【优化调度】基于粒子群算法求解水火电调度优化问题含Matlab源码
- 姚期智亲任主编,正规军的高中AI教材来了
- 关于sPLS analysis的一些学习
- 阿里巴巴并购雅虎意愿耐人寻味 或迎来转机
热门文章
- Apache常见配置及问题
- zabbix4.2之网络发现、自动注册
- 在ubuntu中安装PhantomJS
- zabbix常见报错
- Tomcat和Weblogic的区别
- Chrome浏览器 开发者工具中的 Performance
- maven -- 解决“Could not calculate build plan”问题
- 初识Opserver,StackExchange的监控解决方案
- Build path entry is missing: /src/test/java missing 报错问题解决
- Android WebView重定向问题的解决方案