文档章节

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

 宁哥实战课堂
发布于 2017/04/23 10:57
字数 1596
阅读 7
收藏 1
点赞 0
评论 0

如何轻松理解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
博文 70
码字总数 75824
作品 0
长沙
其他
JavaScript继承详解(二)

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

solu
2010/12/22
0
0
浅谈JavaScript中的继承

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

lanzhiheng
05/29
0
0
JavaScript的计时器的工作原理

最近都在看一些JavaScript原理层面的文章,恰巧看到了jQuery的作者的一篇关于JavaScript计时器原理的解析,于是诚惶诚恐地决定把原文翻译成中文,一来是为了和大家分享,二来是为了加深自己对...

第三方支付接口
2014/11/30
0
0
如何轻松快速学习JavaScript 呢?

JS给人那种感觉的原因多半是因为它如下的特点: 1:本身知识很抽象、晦涩难懂,如:闭包、内置对象、DOM。 2:本身内容很多,如函数库,对象库就一大堆。 3:混合多种编程思想。 4:辛苦学习...

课工场CC老师
2017/11/04
0
0
javascript技术难点(三)之this、new、apply和call详解

原文出处:夏天的森林 讲解this指针的原理是个很复杂的问题,如果我们从javascript里this的实现机制来说明this,很多朋友可能会越来越糊涂,因此本篇打算换一个思路从应用的角度来讲解this指...

夏天的森林
2014/12/10
0
0
面向对象的JavaScript——类

在java里,我们定义类的时候用的是class关键字,但是JavaScript中class是保留字,另有用途,所以我们要采用其他的方法来定义JavaScript中的类。 定义类 利用JavaScript中的function关键字,类...

小微
2012/09/21
0
3
如何编写高质量的Javascript代码

优秀的Stoyan Stefanov在他的新书中(《Javascript Patterns》)介绍了很多编写高质量代码的技巧,比如避免使用全局变量,使用单一的var关键字,循环式预存长度等等。 这篇文章不仅仅从代码本...

SeanCai
2011/03/03
0
0
JavaScript面试大全(二)

eval()是做什么的? [eval()是“魔鬼”][1] null,undefined 的区别? [来看看大神阮一峰的解释吧][2] 写一个通用的事件侦听器函数。 [JS事件监听器][3] Node.js的适用场景? [NodeJS优缺点及...

百变茄
2014/06/05
0
0
用JavaScript的5个原因

你可能不喜欢JavaScript,也有一个很好的理由。自从90年代末,JavaScript就一直处于崛起阶段,主要是在网站和应用程序开发方面的崛起。 早期不同浏览器之间的不兼容性导致了需要开发各种库,...

samday
2014/05/04
0
0
JavaScript 中的继承:ES3、ES5 和 ES6

选择一种继承方式 JavaScript 是一门动态语言,动态意味着高灵活性,而这尤其可以体现在继承上面。JavaScript 中的继承有很多种实现方式,可以分成下面四类: Mixin 模式,即属性混入,从一个...

天方夜
07/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

sklearn学习笔记之简单线性回归

简单线性回归 线性回归是数据挖掘中的基础算法之一,从某种意义上来说,在学习函数的时候已经开始接触线性回归了,只不过那时候并没有涉及到误差项。线性回归的思想其实就是解一组方程,得到...

wangxuwei
5分钟前
0
0
feign之动态interceptor(二)

背景 上文提到了按照不同的feignClient可以根据多个不同的key来进行多个不同的bean的配置 那么我们如何完成多个interceptor的配置呢? 分析 我们刚提到多个配置的玄机就在FeignClientProper...

Mr_Qi
7分钟前
1
0
Linux Kernel 4.16 系列停止维护,用户应升级至 4.17

知名 Linux 内核维护人员兼开发人员 Greg Kroah-Hartman 近日在发布 4.16.18 版本的同时,宣布这是 4.16 系列的最后一个维护版本,强烈建议用户立即升级至 4.17 系列。 Linux 4.16 于 2018 年...

问题终结者
31分钟前
0
0
Apache配置时.htaccess失效不起作用的原因分析

.htaccess 失效的原因 1. 重写规则有问题,检查自己的重写规则 2.Apache配置问题,配置中没有配置启用 rewrite a2enmod rewrite 3.网站配置文件没有启用配置需要配置 000-default.conf <Dire...

TU-DESGIN
51分钟前
1
0
两个求最大公约数C/C++算法实现

#include<stdio.h> #include<time.h> #include <iostream>using namespace std;//求最大公约数 LCD(Largest Common Division)//短除法 //m=8251, n=6105; int LCD_ShortDiv(int m, ......

失落的艺术
57分钟前
1
0
QueryPerformanceCounter

windows的Sleep函数,睡眠线程指定毫秒数,可以用来做毫秒延时。 对于微秒延时,没有一个现成的函数,但是可以通过 QueryPerformanceFrequency QueryPerformanceCounter 来间接实现。原理就是...

开飞色
今天
1
0
log4j2使用AsyncRoot不显示行号问题处理

<AsyncRoot level="info" includeLocation="true"> <AppenderRef ref="File"/></AsyncRoot><!--1.异步logger,还需要在pom.xml中添加disruptor的依赖。2.includeLocation结合异......

小翔
今天
3
0
安卓手机上 K 歌,声音延迟怎么解决?

这篇文章可以为你提供一个解决录音和播放同步问题的思路,而且解决了声音从手机传输到耳机上有延时的问题。 初识音频 在开始之前,我先简单介绍一下音频相关的基础知识,方便下文理解。 我们...

编辑部的故事
今天
2
0
使用token实现在有效期内APP自动登录功能

使用token实现在有效期内APP自动登录功能 http://sevennight.cc/2016/07/19/auto_login_impl.html

风云海滩
今天
2
0
Spring Boot集成RabbitMQ发送接收JSON

默认情况下RabbitMQ发送的消息是转换为字节码,这里介绍一下如何发送JSON数据。 ObjectMapper 最简单发送JSON数据的方式是把对象使用ObjectMapper等JSON工具类把对象转换为JSON格式,然后发送...

小致dad
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部