其实呢,“函数function”和“对象object”之间还有这么一句话:对象是通过函数来创建的,而函数却又是一种对象

这个函数是一种对象,上节中“Javascript之一切皆为对象1”也清楚的阐述了。

但这个对象又是通过函数来创建的,咳咳,似乎在平时代码中也是哈。

请看下面代码

function Fn(){

}
var fn =new Fn();

你可能会说,哥们,不对吧,不是我们也曾写过如下代码吗!!

var obj = {};

哈,是的哈。

但是,还记得么?

以上代码,其本质是这样的:

var obj = new Object();

咦,好吧,我承认是这样的,但是它为什么会这么设置呢?

prototype。

prototype?

对,还记得大明湖畔的原型链么。。。

每个函数都有一个prototype属性,且prototype是一个对象。

当我们通过函数function,(new)创建一个对象时,创建的对象的隐指针__proto__,就指向这个函数的prototype对象。

?!!在说什么。见下图:

上图中,中间是函数Fn,函数Fn有一个prototype对象,prototype对象中,又必须有,且自带一个constructor属性,它又是指向函数Fn本身的,“其他属性”的意思是你自己可以通过prototype对象扩展属性,当函数Fn构建好后,你可以通过new这个函数Fn,创建对象,如上图中左边的fn、fn1,创建的对象,自带一个隐指针__proto__,它是指向函数Fn中的prototype,所以创建的所有对象的__proto__,是同时指向创建它的函数Fn的prototype对象啦。

有点没看懂?

么关系,我们一起来写个demo,一步步理解。

首先,我们一起编写一个函数Fn,并给这个函数Fn的prototype分配两个属性name和age,具体代码如下:

<!DOCTYPE html>
<head>
<title>ttt</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<script>
function Fn(){ }
Fn.prototype.name = 'monkey';
Fn.prototype.age = 24;
console.log(Fn.prototype);
</script>
</body>
</html>

通过chrome调试器,可得下结果图

大家可以看见我利用console.log(Fn.prototype),是输出了age和name,但还有constructor和__proto__,我代码中是没有写的,所以是prototype自带的。

constructor倒好理解了,但它怎么会有个__proto__呢?

你上面不是说每个对象才有__proto__吗?

是的,这个prototype也是对象哦,不要忘啦。

prototype的__proto__从上图可知,是指向Object,修改上面的流程图,可得下图

接下来,我们再通过函数Fn,来创建两个对象fn和fn1,代码如下

<!DOCTYPE html>
<head>
<title>ttt</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<script>
function Fn(){ }
Fn.prototype.name = 'monkey';
Fn.prototype.age = 24;
var fn = new Fn();
var fn1 = new Fn();
console.log( fn.prototype );
console.log( fn1.prototype );
</script>
</body>
</html>

通过chrome调试器,效果图如下

咦,怎么是undefined呢?!!

哈哈哈,仔细看我上面的代码,我console的是对象fn和fn1的prototype哦!只有函数才有prototype,对象只有隐指针__proto__哦,它是指向函数Fn的prototype的哈。

修改代码,通过chrome调试器的效果图如下:

它们的__proto__都是指向创建它们的Fn的prototype的哈,且是同一个。这也就好理解了,为什么它们是共享Fn的prototype了哈。

Javascript之一切皆为对象3

最新文章

  1. DDD 领域驱动设计-如何 DDD?
  2. 数据存储_ SQLite (1)
  3. LeetCode: Ransom Note
  4. Linux-4.4-x86_64 内核配置选项简介【转】
  5. python——创建django项目全攻略(野生程序员到家养程序员的完美进化)
  6. AngularJS_对象数组-filter-orderBy
  7. Redis缓存服务搭建及实现数据读写
  8. freemarker 如何获得list的索引值
  9. richTextBox插入表格 完整版
  10. mysql、mysqli、pdo使用
  11. 狙杀ES6之开光篇
  12. CLR设计类型之接口
  13. while100以内的偶数
  14. API接口签名校验
  15. 初始化仓库(git init)
  16. Docker基本命令与使用 —— Docker容器的网络连接(四)
  17. 【windows核心编程】注入DLL时BUG排除与调试
  18. Isilon上数据是如何存放的?
  19. afx_msg解释
  20. 【WPF】ListBox使用UserContrl作为子控件,引入UserContrl界面

热门文章

  1. C# 使用access,报错:标准表达式中数据类型不匹配
  2. JAVA回调机制和观察者模式实例分享
  3. es查询命令备份(只需要网页9200/_plugin/head/就可以访问)
  4. 【hihoCoder】1036 Trie图
  5. 简单的jquery选项卡效果
  6. CF2.BC
  7. 使用--gc-section编译选项减小程序体积
  8. linux时间同步ntp服务的安装与配置
  9. R语言:常用函数【转】
  10. #IrrlichtEngine# Example1 HelloWorld