现在,我们学习一种新的函数调用方式:new 函数()
你可能知道 new 操作符和 “面向对象” 息息相关,但是现在我们先不探讨它的 “面向对象” 意义,而是先把用 new 调用函数的执行步骤和它上下文弄清楚。
JS 规定,使用 new 操作符调用函数会进行 “四步走”:
function fun() {
this.a = 3;
this.b = 5;
}
var obj = new fun();
console.log(obj); // fun { a: 3, b: 5 }
【第一步:函数体内会自动创建出一个空白对象】

【第二步:函数的上下文(this)会指向这个对象】

【第三步:执行函数体中的语句】
之后这个对象就不再是空对象了。

【第四步:函数会自动返回上下文对象,即使函数没有 return 语句】
执行结果为:{a: 3, b: 5}

【案例】
function fun() {
this.a = 3;
this.b = 6;
var m = 34;
if (this.a > this.b) {
this.c = m;
} else {
this.c = m + 2;
}
}
var obj = new fun();
console.log(obj);
// fun { a: 3, b: 6, c: 36 }
| 规则 | 上下文 |
|---|---|
对象.函数() |
对象 |
函数() |
window |
数组[下标]() |
数组 |
IIFE |
window |
定时器 |
window |
DOM事件处理函数 |
绑定 DOM 的元素 |
call和apply |
任意指定 |
用new调用函数 |
秘密创建出的对象 |

构造函数是专门用来创建对象的函数
一个构造函数我们也可以称为一个类
通过一个构造函数创建的对象,我们称该对象时这个构造函数的实例
通过同一个构造函数创建的对象,我们称为一类对象
构造函数就是一个普通的函数,只是他的调用方式不同,
如果直接调用,它就是一个普通函数
如果使用new来调用,则它就是一个构造函数
我们将之前书写的函数进行一下小改进:
// 书写规范:构造函数首字母大写
// 接收三个参数
function People(name, age, sex) {
// this上绑定三个参数的同名属性
this.name = name;
this.age = age;
this.sex = sex;
}
// 传入三个参数
var xiaoming = new People('小明', 12, '男');
var xiaohong = new People('小红', 10, '女');
var xiaogang = new People('小刚', 13, '男');
console.log(xiaoming); // People { name: '小明', age: 12, sex: '男' }
console.log(xiaohong); // People { name: '小红', age: 10, sex: '女' }
console.log(xiaogang); // People { name: '小刚', age: 13, sex: '男' }
注意:一个函数是不是构造函数,要看它是否用 new 调用,而至于名称首字母大写,完全是开发者的习惯约定。
function People(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
People('小明', 12, '男');
People('小红', 10, '女');
People('小刚', 13, '男');
/* 此时的 this 为 windown 对象,所以下面三条语句会依次给 windown 的三个属性(全局变量)赋值又相互覆盖 */
function People(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
// 添加方法
this.sayHello = function() {
console.log('我是' + this.name + ',我' + this.age + '岁了');
};
}
var xiaoming = new People('小明', 12, '男');
var xiaohong = new People('小红', 10, '女');
var xiaogang = new People('小刚', 13, '男');
xiaoming.sayHello();
xiaohong.sayHello();
xiaogang.sayHello();
var say = xiaoming.sayHello;
say();
/*
我是小明,我12岁了
我是小红,我10岁了
我是小刚,我13岁了
我是undefined,我undefined岁了(上下文为 window)
*/
注意:直接将方法写在构造函数中的方式是不妥的,后面会讲解原因。

【类好比是 “蓝图”】
如同 “蓝图” 一样,类只描述对象会拥有哪些属性和方法,但是并不具体指明属性的值。
【实例是具体的对象】

【构造函数和 “类”】
JS 构造函数 ≈ OO 语言 “类”
JS 构造函数可以看做是面向对象语言中的 “类”

new出来的实例对象就是构造函数内部的this
实例成员就是this后面的属性和方法

<script type="text/javascript">
function Person(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sex =