一、函数对象和普通对象

JS中万物皆为对象,总的分类是两种:普通对象和函数对象,也就是Object和Function.

1.认识函数对象(Function Object)

ECMAScript 的函数实际上是功能完整的对象。

  • 可以用function关键字定义一个函数,并为每个函数指定一个函数名,通过函数名来进行调用。在JavaScript解释执行时,函数都是被维护为一个对象,这就是要介绍的函数对象(Function Object)。

  • 函数对象与其他用户所定义的对象有着本质的区别,这一类对象被称之为内部对象,例如日期对象(Date)、数组对象(Array)、字符串对象(String)都属于内部对象。这些内置对象的构造器是由JavaScript本身所定义的:通过执行new Array()这样的语句返回一个对象,JavaScript内部有一套机制来初始化返回的对象,而不是由用户来指定对象的构造方式。

  • 在JavaScript中,函数对象对应的类型是Function,正如数组对象对应的类型是Array,日期对象对应的类型是Date一样,可以通过new Function()来创建一个函数对象,也可以通过function关键字来创建一个对象。为了便于理解,我们比较函数对象的创建和数组对象的创建。先看数组对象:下面两行代码都是创建一个数组对象myArray:

以下是引用片段:

var myArray=[];

//等价于

var myArray=new Array();

同样,下面的两段代码也都是创建一个函数myFunction:

function myFunction(a,b){ return a+b;
}

//等价于

var myFunction=new Function("a","b","return a+b");
  • 通过和构造数组对象语句的比较,可以清楚的看到函数对象本质,前面介绍的函数声明是上述代码的第一种方式,而在解释器内部,当遇到这种语法时,就会自动构造一个Function对象,将函数作为一个内部的对象来存储和运行。从这里也可以看到,一个函数对象名称(函数变量)和一个普通变量名称具有同样的规范,都可以通过变量名来引用这个变量,但是函数变量名后面可以跟上括号和参数列表来进行函数调用。

  • 用new Function()的形式来创建一个函数不常见,因为一个函数体通常会有多条语句,如果将它们以一个字符串的形式作为参数传递,代码的可读性差。下面介绍一下其使用语法:

以下是引用片段:

var funcName=new Function(p1,p2,...,pn,body);

参数的类型都是字符串,p1到pn表示所创建函数的参数名称列表,body表示所创建函数的函数体语句,funcName就是所创建函数的名称。可以不指定任何参数创建一个空函数,不指定funcName创建一个无名函数,当然那样的函数没有任何意义。

  • JavaScript引入Function类型并提供new Function()这样的语法是因为函数对象添加属性和方法就必须借助于Function这个类型。js 中任意函数都是Function 的实例

  • 函数的本质是一个内部对象由JavaScript解释器决定其运行方式 。通过上述代码创建的函数,在程序中可以使用函数名进行调用。

二、原型

proto(隐式原型)与prototype(显式原型,也叫原型对象)

1.是什么
  • 显式原型:每一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象。
  • 隐式原型:JavaScript中任意对象都有一个内置属性[[prototype]],在ES5之前没有标准的方法访问这个内置属性,但是大多数浏览器都支持通过__proto__来访问。ES5中有了对于这个内置属性标准的Get方法Object.getPrototypeOf(). Object.prototype 这个对象是个例外,它的__proto__值为null
2.两者的关系和作用

关系:隐式原型指向创建这个对象的函数(constructor)的prototype
作用:

  • 显式原型的作用:用来实现基于原型的继承与属性的共享。
  • 隐式原型的作用:构成原型链,同样用于实现基于原型的继承。举个例子,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着__proto__依次查找。
3.图解


首先,要明确几个点:

1.在JS里,万物皆对象
方法(Function)是对象,方法的原型(Function.prototype)是对象。因此,它们都会具有对象共有的特点。
即:对象具有属性__proto__,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法。

2.方法(Function)
方法这个特殊的对象,除了和其他对象一样有上述_proto_属性之外,还有自己特有的属性——原型属性(prototype),这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。

原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。constructor属性用来测试对象的类型,除此之外,就不要使用。同时,原型对象的__proto__指向Object.prototype

知道了这两个基本点,我们来看看上面这副图。
1.构造函数Foo()
构造函数的原型属性Foo.prototype指向了原型对象,在原型对象里有共有的方法,所有构造函数声明的实例(这里是f1,f2)都可以共享这个方法。

2.原型对象Foo.prototype
Foo.prototype保存着实例共享的方法,有一个指针constructor指回构造函数。

3.实例
f1和f2是Foo这个对象的两个实例,这两个对象也有属性__proto__,指向构造函数的原型对象,这样子就可以像上面1所说的访问原型对象的所有方法啦。

另外:
构造函数Foo()除了是方法,也是对象啊,它也有__proto__属性,指向谁呢?
指向它的构造函数的原型对象呗。函数的构造函数不就是Function嘛,因此这里的__proto__指向了Function.prototype。
其实除了Foo(),Function(), Object()也是一样的道理。

原型对象也是对象啊,它的__proto__属性,又指向谁呢?
同理,指向它的构造函数的原型对象呗。这里是Object.prototype.

最后,Object.prototype的__proto__属性指向null。

总结:

  1. 对象有属性__proto__,指向该对象的构造函数的原型对象。
  2. 方法除了有属性__proto__,还有属性prototype,prototype指向该方法的原型对象。

参考文章:js中__proto__和prototype的区别和关系?

js 函数对象/原型相关推荐

  1. 认识js函数对象(Function Object)

      可以用function关键字定义一个函数,对于每个函数可以为其指定一个函数名,通过函数名来进行调用.这些都是代码给用户的印象,而在JavaScript解释执行的时候,实际上每个函数都是被维护为一个 ...

  2. 28-【JS全解】JS 函数

    文章目录 四种方式定义js函数对象 1.具名函数 2.匿名函数 具名和匿名函数结合,具名不可调用 3.箭头函数 4.构造函数 函数自身fn和函数调用fn() 函数的要素: 1.调用时机 得到6个6,执 ...

  3. 【JS从入门到精通】08-构造函数与原型对象

    笔记来源:尚硅谷最新版JavaScript基础全套教程完整版(140集实战教学,JS从入门到精通)_哔哩哔哩_bilibili 文章目录 构造函数与原型对象 1.使用工厂方法创建对象 2.构造函数 构 ...

  4. 【CyberSecurityLearning 50】JS 基础+函数+对象+事件

    目录 JavaScript简介: JS 简单的语句 如何在HTML中引入JS代码 变量 声明变量 变量类型 null和undefined 数组 对象 流程控制 if语句判断 for循环 for ... ...

  5. 自学JavaScript第二天- JS 进阶: 对象 函数

    自学JavaScript第二天- JS 进阶: 对象 函数 对象进阶 构造函数 使用类 类的继承 静态方法 函数进阶 方法 装饰器 高阶函数 map / reduce filter sort ever ...

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

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

  7. JS原型理解——JS中的原型对象

    JavaScript中的原型对象 下一篇:JS原型理解--JS继承的实现方式 原型 原型是JavaScript中继承的基础,JavaScript的继承就是基于原型的继承. 一 理解原型 1.1 函数的 ...

  8. 一张图说明 函数, 实例(对象), 原型之间的关系

    前言 很多初学者都对函数,实例(对象), 原型之间的关系理不清楚. 网上五花八门的文章很多,要么不知所云,要么是晦涩难懂. 本文意在用最简洁的语言跟示例让初学者理清楚这三者之间的关系,无需理会其内部原 ...

  9. js 中对象--对象结构(原型链基础解析)

    对于本篇对于如何自定义对象.和对象相关的属性操作不了解的话,可以查我对这两篇博客.了解这两篇可以更容易理解本篇文章 用构造函数创建了一个对象 obj对象的本身创建了两个属性  x=1   ,y=2 对 ...

最新文章

  1. linux获取目标主机shell,expect案例-批量获取主机并分发密钥
  2. java面试笔试大汇总(一)
  3. SEM那些被人混淆的事儿(已完结)
  4. POJ2513-Colored Sticks
  5. 电脑QQ能登上,网页打不开的解决办法
  6. Java-Type简单分类
  7. 大数据 Spark :利用电影观看记录数据,进行电影推荐 | 原力计划
  8. 在 Queue 中 poll()和 remove()有什么区别?
  9. 在CentOS中安装和部署nacos配置中心
  10. mysql查询连续次数_Mysql如何查询连续的时间次数
  11. $科大讯飞开放平台——语音听写接口的使用
  12. 前端 img 标签显示 base64 格式的 图片
  13. subtype,supertype 与 subclass,superclass 的异同
  14. 记一次刷票过程的感想
  15. ssd的smt_SMT 工厂基础参数要求
  16. 看看你的骂人水平是几段?
  17. Arduino DRV8825驱动两相步进电机
  18. Axis1.4发布WebService
  19. 如何用VScode 进行调试
  20. 图数据库初探——7. 以红楼梦数据集为例进行Nebula Graph使用

热门文章

  1. 封闭式基金改革.发展提上日程
  2. 机器学习笔记 - 模式识别的应用场景之一简单车牌识别
  3. MSP430单片机各种寄存器总结(7)——USCI_A in UART mode
  4. 【云计算】从Serverless说起,谈谈边缘计算的未来;从物理机到Kubernetes的那些坑与心得
  5. 微信公众号直播的玩法须知(上)
  6. squid 和squid 集群
  7. 职场中14个有趣的问题
  8. Prefix Sum 总结
  9. 2017android新技术总结
  10. 关于肌电、脑电的期刊记录