文档章节

如何让你快速轻松理解js的函数和构造函数的区别

 宁哥实战课堂
发布于 2017/04/23 10:57
字数 1596
阅读 9
收藏 1

如何轻松理解js的函数和构造函数的区别,这是个一直头大的问题,很多例子都没有清晰的描述清楚,在这里,我就用平常的道理来阐述一下,希望能理解清楚。

从这里开始入手吧

  • <!DOCTYPE HTML>

  • <html>

  • <head>

  • <meta charset="utf-8" />

  • <title>PHP葵花宝典(2017)-js推理篇</title>

  • <style type="text/css">

  • </style>

  • <script type="text/javascript">

  • window.onload=function (){

  • function myfunc(end_number){

  • var sum=0;

  • for (var i = 1; i <= end_number; i++) {

  • sum+=i;

  • };

  • return sum;

  • }

  • var result=myfunc(36); //666

  • alert(result);

  • }

  • </script>

  • </head>

  • <body>

  • </body>

  • </html>

这是普通函数的定义和调用方式。看起来没什么特别的,但是往下看就有奇怪的东西了。

再做一个:

  • <!DOCTYPE HTML>

  • <html>

  • <head>

  • <meta charset="utf-8" />

  • <title>PHP葵花宝典(2017)-js推理篇</title>

  • <style type="text/css">

  • </style>

  • <script type="text/javascript">

  • window.onload=function (){

  • function Person(name){

  • this.name=name;

  • }

  • var p=new Person('niexiaoqian');

  • alert(p.name); //niexiaoqian

  • }

  • </script>

  • </head>

  • <body>

  • </body>

  • </html>

你没发先一个很奇怪的现象吗?

你的这个函数里面并没有返回什么,也就是没有return ,但是你调用的时候却可以接受啊,如:var p=new Person('niexiaoqian'); alert(p.name); //niexiaoqian

如果是一般函数的调用,没有返回东西,你接受不到任何东西,那就会有问题。

  • <!DOCTYPE HTML>

  • <html>

  • <head>

  • <meta charset="utf-8" />

  • <title>PHP葵花宝典(2017)-js推理篇</title>

  • <style type="text/css">

  • </style>

  • <script type="text/javascript">

  • window.onload=function (){

  • function Person(name){

  • this.name=name;

  • }

  • var p=Person('niexiaoqian');

  • alert(p.name);

  • }

  • </script>

  • </head>

  • <body>

  • </body>

  • </html>

如何让你快速轻松理解js的函数和构造函数的区别

所以,它限制了你那样的使用,就是让你用new的方式来启动它的另外处理的功能。做成了当你new的时候,它就自动帮你返回东西了,你就可以继续的.出东西了,也就是说:

new的方式,它帮你自动返回了,不需要你在写return this;

否则就错。这样它可以在后续使用的过程中继续添加东西进行扩展,扩大了它的应用能力。为了区别,它函数的首字母都大写。

当然,如果你做成了返回:

  • <!DOCTYPE HTML>

  • <html>

  • <head>

  • <meta charset="utf-8" />

  • <title>PHP葵花宝典(2017)-js推理篇</title>

  • <style type="text/css">

  • </style>

  • <script type="text/javascript">

  • window.onload=function (){

  • function Person(name){

  • this.name=name;

  • return this;

  • }

  • var p=Person('niexiaoqian');

  • alert(p.name);

  • }

  • </script>

  • </head>

  • <body>

  • </body>

  • </html>

同样是弹出来了,但是使用的原理变了。

1:你这是同一个函数在调用两次,如果你打印两次的函数首地址,当然就一样;

2:你调用了两次,传递了不同的参数,但是它是同一个地方的啊,后来的就覆盖以前的了。当然两次打印就一样的了。

看打印例子:

  • <!DOCTYPE HTML>

  • <html>

  • <head>

  • <meta charset="utf-8" />

  • <title>PHP葵花宝典(2017)-js推理篇</title>

  • <style type="text/css">

  • </style>

  • <script type="text/javascript">

  • window.onload=function (){

  • function Person(name){

  • this.name=name;

  • return this;

  • }

  • var p=Person('niexiaoqian');

  • var p2=Person('xiaodie');

  • alert(p==p2);//true

  • alert(p.name);//xiaodie

  • alert(p2.name);//xiaodie

  • }

  • </script>

  • </head>

  • <body>

  • </body>

  • </html>

但是你如果是new的方式,它就是用那个模子造了两个对象出来,占据内存的不同的地方。当然就不一样的首地址,各自互不影响。自然打印的就是另外的样子了:

看打印例子:

  • <!DOCTYPE HTML>

  • <html>

  • <head>

  • <meta charset="utf-8" />

  • <title>PHP葵花宝典(2017)-js推理篇</title>

  • <style type="text/css">

  • </style>

  • <script type="text/javascript">

  • window.onload=function (){

  • function Person(name){

  • this.name=name;

  • return this;

  • }

  • var p=new Person('niexiaoqian');

  • var p2=new Person('xiaodie');

  • alert(p==p2);//false

  • alert(p.name);//niexiaoqian

  • alert(p2.name);//xiaodie

  • }

  • </script>

  • </head>

  • <body>

  • </body>

  • </html>

现在的内存占据情况:造一个对象(存放在其他的地址哦),再造一个对象,又是存放到另外的地址,所以这是两个对象;总的来说现在是有3个地方(函数自己,两个对象)占据内存了,以前只是一个地方(就是函数);所以它们3个的首地址自然是不一样的;

看例子:

  • <!DOCTYPE HTML>

  • <html>

  • <head>

  • <meta charset="utf-8" />

  • <title>PHP葵花宝典(2017)-js推理篇</title>

  • <style type="text/css">

  • </style>

  • <script type="text/javascript">

  • window.onload=function (){

  • function Person(name){

  • this.name=name;

  • return this;

  • }

  • var p=new Person('niexiaoqian');

  • var p2=new Person('xiaodie');

  • var p3=Person('xiaodie');

  • alert(p==p2);//false

  • alert(p2==p3);//false

  • alert(p==p3);//false

  • }

  • </script>

  • </head>

  • <body>

  • </body>

  • </html>

全部都是false就可以证明。

它还可以造很多很多的对象,占据不同的内存地方。它就是要这样的做。因为这样做很有意义:

这样的使用,很容易在后面需要的时候继续添加成员方法来扩充具体某个对象的功能,不像以前那样只能去修改函数体本身(会影响其他地方的调用哦)表现为很灵活了。

这样的应用在现实中也有反映。从现实中的角度来看,如果你要造1000个金币,同时你想为每个金币添加不同的编号刻录在上面。

你很有意义的做法就是:先做个模子,然后用模子快速的生成1000个金币的大概样子,然后再为每个金币去雕刻各自的编号。你不会不做模子就直接去打造一个个的金币去了,那样太浪费时间了。因为如果是10000个呢?

所以这是高效的处理方式,所以它要先费力费时的造个金币模子出来,就是为了用该模子造出很多很多规格一样的具体金币对象出来,同时又可以为每个对象刻画不同的“编号”,既快速又省事,还能顺利实现需求。

而你直接去调用那个函数(不去实例化),就相当于你拿个金币模子到处在外面流传,这是不合法的哦,你肯定马上被抓了。流传到外面的应该是用金币模子造好出来的那些金币,而不是印刷钱的印版啊。

所以,它就是要你用new的方式去调用,为此它还怕你分不清楚,这样的函数它都用首字母大写来标记,这种函数就叫“构造函数”。

© 著作权归作者所有

共有 人打赏支持
粉丝 5
博文 72
码字总数 77184
作品 0
长沙
其他
私信 提问
每个JavaScript工程师都应懂的33个概念

摘要: 基础很重要啊! 原文:33 concepts every JavaScript developer should know 译文:每个 JavaScript 工程师都应懂的33个概念 作者:stephentian Fundebug经授权转载,版权归原作者所有...

Fundebug
10/30
0
0
JavaScript开发者应懂的33个概念

简介 这个项目是为了帮助开发者掌握 JavaScript 概念而创立的。它不是必备,但在未来学习(JavaScript)中,可以作为一篇指南。 本篇文章是参照 @leonardomso 创立,英文版项目地址在这里。 ...

大灰狼的小绵羊哥哥
10/22
0
0
JavaScript继承详解(二)

文章截图 - 更好的排版 这一章我们将会重点介绍JavaScript中几个重要的属性(this、constructor、prototype), 这些属性对于我们理解如何实现JavaScript中的类和继承起着至关重要的作用。 ...

solu
2010/12/22
0
0
JavaScript 原型精髓,读完这篇就够了

一篇文章让你搞清楚 JavaScript 继承的本质、、、 都是什么。 很多小伙伴表示不明白 JavaScript 的继承,说是原型链,看起来又像类,究竟是原型还是类?各种 、、 内部变量更是傻傻搞不清楚。...

linesh
10/23
0
0
浅谈JavaScript中的继承

近期,公司的业务处于上升期,对人才的需求似乎比以往任何时候都多。作为公司的前端,有幸窥探到了公司的前端面试题目,其中有一题大概是这样的(别激动,题目已经改了) 请用你自己的方式来...

lanzhiheng
05/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

EOS官方钱包keosd

EOS官方钱包的名称是keosd,它负责管理你的私钥,并且帮你进行交易的签名。 不过不幸的是,keosd钱包对普通用户并不友好,它是一个命令行程序,目前还没有像以太坊的mist那样的图形化界面,而...

汇智网教程
今天
23
0
ArrayList的实现原理以及实现线程安全

一、ArrayList概述 ArrayList是基于数组实现的,是一个动态的数字,可以自动扩容。 ArrayList不是线程安全的,效率比较高,只能用于单线程的环境中,在多线程环境中可以使用Collections.syn...

一看就喷亏的小猿
今天
24
0
Netty 备录 (一)

入职新公司不久,修修补补1个月的bug,来了点实战性的技术---基于netty即时通信 还好之前对socket有所使用及了解,入手netty应该不是很难吧,好吧,的确有点难,刚看这玩意的时候,可能都不知道哪里...

_大侠__
昨天
33
0
Django简单介绍和用户访问流程

Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。 Django是一个开放源代码的Web应用框架,由Python写成。 Django遵守BSD版权,初...

枫叶云
昨天
40
0
Spring Cloud Stream消费失败后的处理策略(四):重新入队(RabbitMQ)

应用场景 之前我们已经通过《Spring Cloud Stream消费失败后的处理策略(一):自动重试》一文介绍了Spring Cloud Stream默认的消息重试功能。本文将介绍RabbitMQ的binder提供的另外一种重试...

程序猿DD
昨天
21
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部