函数的定义方式:
1.声明式函数定义: function 函数名 (){};这种定义方式,会将函数声明提升到该函数所在作用域的最开头,也是就无论你在这个函数的最小作用域的那儿使用这种方式声明的函数,在这个作用域内,你都可以调用这个函数为你所用。
2.函数表达式:let fun = function(){}; 此方式定义的函数,只能在该作用域中,这段赋值代码执行之后才能通过fun()调用函数,否则,由于变量声明提升,fun === undefined。
3.new Function 形式: var fun1 = new Function (arg1 , arg2 ,arg3 ,…, argN , body );Function构造函数所有的参数都是字符串类型。除了最后一个参数, 其余的参数都作为生成函数的参数即形参。这里可以没有参数。最后一个参数, 表示的是要创建函数的函数体。

构造函数
在 JavaScript 中,用 new 关键字来调用的函数,称为构造函数。构造函数首字母一般大写(规范)。
之所以有构造函数与普通函数之分,主要从功能上进行区别的,构造函数的主要 功能为 初始化对象,特点是和new 一起使用。new就是在创建对象,从无到有,构造函数就是在为初始化的对象添加属性和方法。

1、常用的构造函数:
 var arr = []; 为 var arr = new Array();
 var obj = {} 为 var obj = new Object();
 var date = new Date();
 
2、执行构造函数时发生的事 :

let p = new Person();
function Person(name,age,sex){this.name = name;this.age = age;this.sex = sex;
}
Person.prototype.say = function(){console.log('定义了一个Person的新方法say');
}
let f = new Person ('青衣浏阳',18,'男');  //  f.name = '青衣浏阳';f.age = 18; f.sex = '男';
f.say();     //定义了一个Person的新方法say

构造函数会有以下几个执行过程
(1) 当以 new 关键字调用时,会创建一个新的内存空间,标记为 Animal 的实例。
(2)函数体内部的 this 指向该内存

var f1 = new Person('ls',20, '女');  // 创建一个新的内存 #f1
var f2 = new Person('lss',22, '女');  // 创建一个新的内存 #f2

每当创建一个实例的时候,就会创建一个新的内存空间(#f1, #f2),创建 #f1 的时候,函数体内部的 this 指向 #f1, 创建 #f2 的时候,函数体内部的 this 指向 #f2。

(3) 执行函数体内的代码
就是给 this 添加属性,就相当于给实例添加属性。
(4) 默认返回 this
由于函数体内部的this指向新创建的内存空间,默认返回 this ,就相当于默认返回了该内存空间,也就是上图中的 #f1。此时,#f1的内存空间被变量p1所接受。也就是说 p1 这个变量,保存的内存地址就是 #f1,同时被标记为 Person 的实例。
以上就是构造函数的整个执行过程。

3、用new和不用new调用构造函数,有什么区别?

1、用new调用构造函数,函数内部会发生如下变化:
创建一个this变量,该变量指向一个空对象。并且该对象继承函数的原型;
属性和方法被加入到this引用的对象中;
隐式返回this对象(如果没有显性返回其他对象)
简单的说 用new调用构造函数,最大特点为,this对象指向构造函数生成的对象

2、如果直接调用函数,那么,this对象指向window,并且,不会默认返回任何对象(除非显性声明返回值)。

4、构造函数的返回值
构造函数执行过程的最后一步是默认返回 this 。言外之意,构造函数的返回值还有其它情况。
没有手动添加返回值,默认返回 this。手动添加一个基本数据类型的返回值,最终还是返回 this。

function P() {this.name = '青衣浏阳';
}
var p1 = new P();
console.log(p1)  //Person1 {name: "青衣浏阳"}

手动添加一个复杂数据类型(对象)的返回值,最终返回该对象。

function P2() {this.sex = '男';return { sex: '女' };
}
var p3 = new P2();
console.log(p3.sex);  //女

5、构造函数有什么用?
当你需要大批量的写对象的时候,就需要用到构造函数,它可以方便创建多个对象的实例,并且创建的对象可以被标识为特定的类型,可以通过继承扩展代码

举个例子,我们要录入很多同学的个人信息,那么我们可以创建一些对象,比如:

var p1 = { name: 'zs', age: 6, sex: '男'};
var p2 = { name: 'ls', age: 6, sex: '女'};
var p3 = { name: 'ww', age: 6, sex: '女'};
var p4 = { name: 'zl', age: 6, sex: '男'};

像上面这样,我们可以把每一位同学的信息当做一个对象来处理。但是,我们会发现,我们重复地写了很多无意义的代码。比如 name、age、sex 。如果这个班上有60个学生,我们得重复写60遍。

这个时候,构造函数的优势就体现出来了。我们发现,虽然每位同学都有 name、age、sex这些属性, 但它们都是不同的,那我们就把这些属性当做构造函数的参数传递进去。此时,我们就可以创建以下的函数:

function Person(name,age, sex,) {this.name = name;this.age = age;this.sex= sex;
}

当创建上面的函数以后, 我们就可以通过 new 关键字调用,也就是通过构造函数来创建对象了。

var p1 = new Person('zs', 5,'男');
var p2 = new Person('luci', 5,'女');
var p3 = new Person('jack', 6,'男');
var p4 = new Person('lusi', 6,'女');

此时你会发现,创建对象会变得非常方便。所以,虽然封装构造函数的过程会比较麻烦,但一旦封装成功,我们再创建对象就会变得非常轻松,这也是我们为什么要使用构造函数的原因。
在使用对象字面量创建一系列同一类型的对象时,这些对象可能具有一些相似的特征(属性)和行为(方法),此时会产生很多重复的代码,而使用构造函数就可以实现代码复用。

6、 构造函数和普通函数的区别
1、构造函数也是一个普通函数,创建方式和普通函数一样,但构造函数习惯上首字母大写。
2、调用方式不一样。
普通函数的调用方式:直接调用 person();
构造函数的调用方式:需要使用new关键字来调用 new Person();
3、构造函数的函数名与类名相同:Person( ) 这个构造函数,Person 既是函数名,也是这个对象的类名。(ES6 中 class 与构造函数的关 系,通过class定义的类 和通过构造函数定义的类 二者本质相同。并且在js执行时,会将第一种转会为第二种执行。所以 ES6 class的写法实质就是构造函数)
4、内部用this 来构造属性和方法
5、构造函数的执行流程
A、立刻在堆内存中创建一个新的对象
B、将新建的对象设置为函数中的this
C、逐个执行函数中的代码
D、将新建的对象作为返回值
6、构造函数的返回值默认是this 也有其他情况 。普通函数:因为没有返回值,所以为undefined

写在最后,如有错误欢迎留言指正和补充~

js 中的构造函数,构造函数作用,构造函数和普通函数的区别相关推荐

  1. JS中关键字in的作用

    JS中关键字in的作用 in关键字可以用来检测某个属性是否存在某个对象中,对于对象的属性要用字符串指定属性的名称("属性名") // 举个栗子:console.log(" ...

  2. C语言中的带参宏和带参函数的区别

    C语言中的带参宏和带参函数的区别 (1) 带参函数中的形参是变量,因此有类型检查.而带参宏只是简单的字符串替换. (2) 从程序执行的过程来看,带参宏是在预处理阶段被预处理器处理的.而带参函数是在程序 ...

  3. js中new操作符的作用及原理

    要知道new操作符的作用是什么,得先知道它干了什么事(原理): 它创建了一个新对象 它将构造函数的原型属性和方法挂载到新对象的__proto__(原型指针)上 他执行了构造函数并将构造函数的this指 ...

  4. js中的innerHTML的作用

    js中常常用到innerHTML,其作用就是获取到标签里面的内容,同时也可以为标签添加内容 <div><p id="text">hello world< ...

  5. js最简单的几个特效_高阶函数不会用?教你JS中最实用的几个高阶函数用法

    不废话,先来看下什么是高阶函数 高阶函数 函数可以作为参数传递 函数可以作为返回值输出 函数作为参数传递 回调函数 在ajax异步请求的过程中,回调函数使用的非常频繁 在不确定请求返回的时间时,将ca ...

  6. JS中绑定事件顺序(事件冒泡与事件捕获区别)

    在JS中,绑定的事件默认的执行时间是在冒泡阶段执行,而非在捕获阶段(重要),这也是为什么当父类和子类都绑定了某个事件,会先调用子类绑定的事件,后调用父类的事件.直接看下面实例 <!Doctype ...

  7. frameset嵌套多个html,在一个html的js中调用另一个html的变量和函数(导航栏更新个人图标)

    毕业设计要做注册后更新性别后导航栏的个人图标也随之改变,在frameset中做的两个html互相调用函数怎么都是undefined,终于实验成功了. test1.html <!DOCTYPE h ...

  8. C语言中全局变量和局部变量,内部函数和外部函数的区别

    1.局部变量和全局变量 1.局部变量:即在函数代码块中内部定义的变量名,只在此函数范围内有效.(只在子程序内定义和作用) 在c语言中,局部变量可以和全局变量重名,但是局部变量会覆盖全局变量,从而在引用 ...

  9. js中 replace(/\//g, '') 什么作用. 正则表达式

    replace(/\//g, '') 的作用是把/替换成''. 用法如下: 比如:var aa= "adsdd/sdsd12/"; bb=aa.replace(/\//g, '') ...

  10. Vue.js 中created方法的作用【学习】

    1.这是它的一个生命周期钩子函数,就是一个Vue实例被生成后调用这个函数,一个Vue实例被生成后还要绑定到某个htm元素上,之后还要进行编译,然后再插入到document中.每一个阶段都会有一个钩子函 ...

最新文章

  1. linux看3D实景
  2. 普大喜奔 | Azure 免费送网站SSL证书啦!
  3. the python challenge_The Python Challenge 谜题全解(持续更新)
  4. idea中常用的快捷键以及一些奇淫技巧 , 加快我们的开发效率
  5. Spring Boot笔记-validation的使用及统一异常处理
  6. 自主招生计算机系面试,自主招生笔试和面试,你准备好了吗?
  7. tomcat配置报错解决方法 The jre_home environment variable is not defined correctly
  8. Python 学习笔记 - RabbitMQ
  9. js基础-18-js中创建对象的几种方式
  10. sns.load_dataset报错解决
  11. mysql delete数据怎么恢复_mysql数据delete后的数据恢复
  12. 戴尔修复计算机软件,DELL电脑系统恢复工具(Dell OS Recovery Tool)2019 v2.3.6066官方版...
  13. stm32数据手册boot_stm32f103中文手册.pdf
  14. Wechall Wireup(一)
  15. for(in/of)/forEarch的区别和使用
  16. 收支记录用这个记账本就够了
  17. SVM和Softmax分类器比较
  18. xml文件消除黄色警报_新机器,XML和歧义消除
  19. Go 事件驱动 实现事件的晌应和处理
  20. 主板螺丝是机箱配还是主板配_电脑机箱螺丝规格详解 DIY装机容易忽视的小玩意...

热门文章

  1. CSS学习笔记之浮动布局
  2. Presto 在 Lyft 的实践
  3. Thinkphp 开启字段缓存后,生成字段缓存文件bug修改
  4. 全栈溯源重新定义APM
  5. 重磅!杭州人社部点名,劳动合同网签!
  6. JPG 转PDF?-- 4种在线免费工具,手机和电脑均适用
  7. Python的boss直聘职位信息数据分析系统
  8. 数字化助力生产管理:报工与跟踪管理系统
  9. 深入理解Linux内存管理
  10. python中的if语句的基本知识与实例