# 构造函数
构造函数是原型和原型链的基础
# 什么是构造函数
在 JavaScript
中,用 new 关键字来调用的函数,称为构造函数。
TIP
与普通唯一的区别是构造函数名应该首字母大写
- 根据需要,构造函数可以接受参数
function Person(age){
this.age = age;
}
var person = new Person(20);
console.log(person.age);// 20
- 如果没有参数,可以省略括号
function Person(){
this.age = 20;
}
//等价于var person = new Person()
var person = new Person;
console.log(person.age);// 20
- 如果不使用new操作符,则this将代表全局对象window
function Person(){
this.age = 20;
}
var person = Person();
//Uncaught TypeError: Cannot read property 'age' of undefined
console.log(person.age);
- 如果希望构造函数只能以new方式调用
function Person(name){
// 验证this指向 // 只能通过new关键字调用
if(!(this instanceof Person)){
throw new TypeError("Class constructor Person connot be invoked without 'new'")
};
this.name = name;
}
// 注意原型上的方法是不可枚举的且不能通过作为构造函数。
Person.prototype.func = function(){
console.log(this.name)
}
// 原型上的方法是不可枚举的【注意点3】
Object.defineProperty(Person.prototype,'func',{
value:function(){
// 不可通过new调用 【注意点4】
if(!(this instanceof Person)){
throw new TypeError("func is not a constructor")
};
console.log(this.name)
},
enumerable:false
})
# 构造函数的作用
TIP
在使用对象字面量创建一系列同一类型的对象时,这些对象可能具有一些相似的特征(属性)和行为(方法),此时会产生很多重复的代码,而使用构造函数就可以实现代码的复用。
function Person(name,sex,age){
this.name=name;
this.sex=sex;
this.age=age
}
var p1=new Person("张三","女",18)
var p2=new Person("李四","男",25)
# 构造函数的执行过程
TIP
构造函数的执行过程,也就是以 new
关键字来调用的情况。
function Person(name,sex,age){
this.name=name;
this.sex=sex;
this.age=age
}
var p1=new Person("张三","女",18)
# (1)、当以new关键字调用时,会创建一个新的内存空间 (空对象),标记为Person的实例
# (2)、函数体内部的 this 指向该内存
设置空对象的原型 -> 即构造函数的原型
# 结论
var p1=new Person("张三","女",18) // 创建一个新的内存:m1
var p2=new Person("李四","男",25) // 创建一个新的内存:m2
每当创建一个实例的时候,就会创建一个新的内存空间,例如(#m1, #m2),
- 创建
#m1
的时候,函数体内部的 this 指向#m1
, - 创建
#m2
的时候,函数体内部的 this 指向#m2
。
# (3)、执行函数体内的代码
- 执行构造函数方法,把相关属性何方法添加到实例对象中
- 给 this 添加属性,就相当于给实例添加属性
# (4)、默认返回this
由于函数体内部的 this 指向新创建的内存空间,默认返回 this ,就相当于默认返回了该内存空间 也就是上述说的 p1 指向 m1 内存空间
# 构造函数的返回值
WARNING
构造函数执行过程的最后一步是默认返回 this 。言外之意,构造函数的返回值还有其它情况。
# (1)、没有手动添加返回值,默认返回 this
function Person1() {
this.name = 'zhangsan';
}
var p1 = new Person1();
# (2)、手动添加一个基本数据类型的返回值,最终还是返回 this
function Person() {
this.age = 30;
return 50;
}
var p = new Person(); // 如果上面是一个普通函数的调用,那么返回值就是 50 ; p = 50
console.log(p.age); // 30
// p2: {
// age: 28
// }
# (3)、手动添加一个复杂数据类型(对象)的返回值,最终返回该对象
function Person() {
this.gender = '男';
return { gender: '男娃儿' };
}
var p = new Person();
console.log(p.gender); // '男娃儿'