每个函数都有一个prototype属性,这个属性是指向一个对象的引用,
这个对象称为原型对象,原型对象包含函数实例共享的方法和属性

用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,
可以为其添加函数供实例访问,其它的就不清楚了,最近看了一些 JavaScript高级程序设计,终于揭开了其神秘面纱。
每个函数都有一个prototype属性,这个属性是指向一个对象的引用,这个对象称为原型对象,原型对象包含函数实例共享的方法和属性,
也就是说将函数用作构造函数调用(使用new操作符调用)的时候,新创建的对象会从原型对象上继承属性和方法。

私有变量、函数

在具体说prototype前说几个相关的东东,可以更好的理解prototype的设计意图。
之前写的一篇JavaScript 命名空间文章中提到过JavaScript的函数作用域,在函数内定义的变量和函数如果不对外提供接口,那么外部将无法访问到,也就是变为私有变量和私有函数。
代码如下:

     function Obj() {var a = 0; //私有变量var fn = function() { //私有函数}}

这样在函数对象Obj外部无法访问变量a和函数fn,它们就变成私有的,只能在Obj内部使用,即使是函数Obj的实例仍然无法访问这些变量和函数
代码如下:

var o=new Obj();
console.log(o.a); //undefined
console.log(o.fn); //undefined

静态变量、函数

当定义一个函数后通过 “.”为其添加的属性和函数,通过对象本身仍然可以访问得到,但是其实例却访问不到,这样的变量和函数分别被称为静态变量和静态函数,用过Java、C#的同学很好理解静态的含义。
代码如下:

     function Obj() {}Obj.a = 0; //静态变量Obj.fn = function() {} //静态函数console.log(Obj.a); //0console.log(typeof Obj.fn); //functionvar o = new Obj();console.log(o.a); //undefinedconsole.log(typeof o.fn); //undefined//输出结果是: [2, 3, 4]

实例变量、函数

在面向对象编程中除了一些库函数我们还是希望在对象定义的时候同时定义一些属性和方法,实例化后可以访问,JavaScript也能做到这样
代码如下:

     function Obj() {this.a = []; //实例变量this.fn = function() {} //实例方法 }console.log(typeof Obj.a); //undefinedconsole.log(typeof Obj.fn); //undefinedvar o = new Obj();console.log(typeof o.a); //objectconsole.log(typeof o.fn); //function

这样可以达到上述目的,然而
代码如下:

     function Obj() {this.a = []; //实例变量this.fn = function() {} //实例方法 }var o1 = new Obj();o1.a.push(1);o1.fn = {};console.log(o1.a); //[1]console.log(typeof o1.fn); //objectvar o2 = new Obj();console.log(o2.a); //[]console.log(typeof o2.fn); //function

上面的代码运行结果完全符合预期,但同时也说明一个问题,在o1中修改了a和fn,而在o2中没有改变,由于数组和函数都是对象,是引用类型,
这就说明o1中的属性和方法与o2中的属性与方法虽然同名但却不是一个引用,而是对Obj对象定义的属性和方法的一个复制。
这个对属性来说没有什么问题,但是对于方法来说问题就很大了,因为方法都是在做完全一样的功能,但是却又两份复制,如果一个函数对象有上千和实例方法,
那么它的每个实例都要保持一份上千个方法的复制,这显然是不科学的,这可肿么办呢,prototype应运而生。

prototype

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,默认情况下prototype属性会默认获得一个constructor(构造函数)属性,
这个属性是一个指向prototype属性所在函数的指针,有些绕了啊,写代码、上图!
代码如下:

function Person(){}

根据上图可以看出Person对象会自动获得prototyp属性,而prototype也是一个对象,会自动获得一个constructor属性,该属性正是指向Person对象。
当调用构造函数创建一个实例的时候,实例内部将包含一个内部指针(很多浏览器这个指针名字为__proto__)指向构造函数的prototype,这个连接存在于实例和构造函数的prototype之间,
而不是实例与构造函数之间。
代码如下:

     function Person(name) {this.name = name;}Person.prototype.printName = function() {alert(this.name);}var person1 = new Person('Byron');var person2 = new Person('Frank');

Person的实例person1中包含了name属性,同时自动生成一个__proto__属性,该属性指向Person的prototype,可以访问到prototype内定义的printName方法,大概就是这个样子的

写段程序测试一下看看prototype内属性、方法是能够共享
代码如下:

     function Person(name) {this.name = name;}Person.prototype.share = [];Person.prototype.printName = function() {alert(this.name);}var person1 = new Person('Byron');var person2 = new Person('Frank');person1.share.push(1);person2.share.push(2);console.log(person2.share); //[1,2]

果不其然!实际上当代码读取某个对象的某个属性的时候,都会执行一遍搜索,目标是具有给定名字的属性,搜索首先从对象实例开始,如果在实例中找到该属性则返回,
如果没有则查找prototype,如果还是没有找到则继续递归prototype的prototype对象,直到找到为止,如果递归到object仍然没有则返回错误。
同样道理如果在实例中定义如prototype同名的属性或函数,则会覆盖prototype的属性或函数。
代码如下:

     function Person(name) {this.name = name;}Person.prototype.share = [];var person = new Person('Byron');person.share = 0;console.log(person.share); //0而不是prototype中的[]

另外例子:

     function Sub1(name) {this.name = name;}Sub1.prototype.age = 30;Sub1.prototype.item = function() {console.log(this.name);}let s1 = new Sub1("张三");let s2 = new Sub1("赵五")console.log(s1.age)//30 *这里的age是Sub1的属性s1.age=50;// 如果在实例中定义如prototype同名的属性或函数,//   则会覆盖prototype的属性或函数。console.log(s1.age);//50,这里的age已不是Sub1的属性console.log(s2.age);//30

构造简单对象
当然prototype不是专门为解决上面问题而定义的,但是却解决了上面问题。了解了这些知识就可以构建一个科学些的、复用率高的对象,如果希望实例对象的属性或函数则定义到prototype中,
如果希望每个实例单独拥有的属性或方法则定义到this中,可以通过构造函数传递实例化参数。
复制代码 代码如下:

     function Person(name) {this.name = name;}Person.prototype.share = [];Person.prototype.printName = function() {alert(this.name);}

*转自原文:https://www.cnblogs.com/socool-hu/p/5665270.html

js prototype 原型对象相关推荐

  1. js 高级 原型对象

    原型链 任何对象都有原型对象,也就是prototype属性,任何原型对象也是一个对象,该对象就有__proto__属性,这样一层一层往上找,就形成了一条链,我们称此为原型链; 函数类,实例和原型对象三 ...

  2. 理解js的prototype原型对象

    我们创建的每一个函数都有一个prototype(原型)属性.这个属性是一个指针,指向一个对象,而这个对象的用途是包括能够由特定类型的全部实例共享的属性和方法.假设依照字面意思来理解,那么prototy ...

  3. 深入理解prototype(原型对象)

    对JavaScript中原型模式的理解 一:什么是原型对象?有什么优点?    简单的来说,无论何时,我们创建的每一个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,这个对象包含 ...

  4. 初学JavaScript:js中的对象(对象+原型对象)

    文章目录 js对象详解 1.创建对象 字面量模式创建对象 构造函数模式创建对象 2.访问对象 访问属性 访问方法 3.遍历对象中的属性和属性值 4.往对象中新添属性 5.删除对象中的属性 6.Obje ...

  5. 关于JavaScript的Prototype及原型对象的理解

    学习JavaScript时,就一定会涉及到两个概念–prototype,原型对象.自己在做项目时可能无意中使用到,但是却没有真正去了解这个东西,在学会使用的基础上,进一步去理解它会帮助自己吸收到更多不 ...

  6. 【JavaScript】JavaScript模拟实现面向对象一张图帮助你深刻理解原型链和原型对象

    文章目录 一.JavaScript模拟面向对象 1.函数是类 2.函数中各种变量的声明 3.关于函数内的this 小结:JavaScript中函数是什么? 4.练习:面向对象思想编写Complex类 ...

  7. javascript中的prototype原型、_proto_属性、原型链

    prototype原型 JavaScript是面向对象的语言,那么继承自然是其重要特征之一.与标准面向对象语言不同,JavaScript继承主要通过prototype原型实现.每一个函数都具有prot ...

  8. JavaScript进阶-编程思想、构造函数的原型对象、对象原型、原型继承以及原型链

    编程思想 面向过程 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次 调用就可以了. 优点: 性能比面向对象高,适合跟硬件联系很紧密 的东西,例如单 ...

  9. 什么是原型对象、实例、原型链讲解(简单易懂,不墨迹)

    一.原型对象.实例.原型链 先写这么一段代码: var M=function(){this.name='123'} //ƒ (){this.name='123'} var a1=new M() //M ...

  10. JavaScript 面向对象 (prototype 原型模式)

    一. JavaScript 设计思想 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.这是历史上第一个比较成熟的网络浏览器,轰动一时.但是,这个版本的浏览器只能用来浏览 ...

最新文章

  1. matlab GUI 界面暂时关闭和打开关闭请求操作
  2. sql parser
  3. Xgboost调参小结
  4. 消除左递归c++代码_python实现文法左递归的消除
  5. Flask--SQLAlchemy
  6. 艾伟_转载:WPF/Silverlight陷阱:XAML自定义控件的嵌套内容无法通过名称访问
  7. Marketing Cloud contact的API介绍
  8. 常识推理相关最新研究进展
  9. 【2015年第4期】面向科技情报的互联网信息源自动发现技术
  10. windows获取IP和MAC地址【Qt】
  11. 华为高管揭秘公司不上市的原因;微信回应「花钱就能查到聊天记录」;马斯克删除「超苹果只要几个月」评论 | 极客头条...
  12. C#获取堆栈信息,输出文件名、行号、函数名、列号等
  13. 【元胞自动机】基于matlab保守策略元胞自动机三车道(不开放辅路,软件园不影响)交通流模型【含Matlab源码 1293期】
  14. 雅虎新频道Buzz截图,Digg竞争者?
  15. 小米手机系统服务组件是干什么的_小米手机的云服务也太好用了吧?!手机丢了完全不用怕了...
  16. 微信实现扫码支付(native)
  17. web移动开发总结(六)
  18. 华为云对象存储obs文件上传
  19. Lumen为《堡垒之夜:大逃杀》第四章带来实时全局光照
  20. 系统运维-20-2-openssh和openssl

热门文章

  1. 约瑟夫问题、约瑟夫环
  2. Git学习笔记(基础操作+分支操作+PR)
  3. 苹果系统如何添加服务器的打印机,哪位清楚macbookair如何添加打印机
  4. 《python股票量化交易从入门到实践》摘要
  5. 【小程序开发】开发一个短信登录验证(后端采用springboot)
  6. 计算机控制技术论文英语版,计算机控制技术外文论文
  7. 百度网盘windows10镜像文件
  8. SSD的TRIM原理及实践
  9. 搜狗浏览器异常问题 - 解决方案
  10. 网络蠕虫和僵尸网络等恶意代码防范技术原理