前言
**本节您将学会**什么是构造函数
执行过程分析
如何使用构造函数
构造函数问题
一、什么是构造函数
构造函数是普通函数,使用时用new操作符来调用,创建特定类型的对象。
理解:
1.构造函数是一个普通函数
2.使用构造函数需用new 关键字
3.每次new 创建一个新的相同类型对象
4.新建的对象新开一块空间
5.新建的对象设置为函数的this (c# java 就是类的一个实例指向this)
6.对象创建后并做为返回值返回
代码示例:
<script>
function Student(name,age,bookName){//构造函数一般首字母大写(一种惯例,非构造函数小写字母开头)
this.name = name;
this.age = age;
this.bookName=bookName;
this.readBook=function(){
console.log('大家好,我是'+this.name,'我现在年龄是'+this.age,'我还在读:'+this.bookName);
}
}
var s=new Student("marshal",40,"javascript");//new 关键字
s.readBook();//输出:大家好,我是marshal 我现在年龄是40 我还在读:javascript
</script>
以上代码等价于:
function Student(name,age,bookName){
var obj=new Object();
obj.name = name;
obj.age = age;
obj.bookName=bookName;
obj.readBook=function(){
console.log('大家好,我是'+obj.name,'我现在年龄是'+obj.age,'我还在读:'+obj.bookName);
}
return obj;
}
var s=Student("marshal",40,"javascript");//无new
s.readBook();//大家好,我是marshal 我现在年龄是40 我还在读:javascript
使用new操作符分析
构造函数被new操作符调用时,构造函数的this对象赋值给new返回的对象。
var s=new Student(“marshal”,40,“javascript”);
将构造函数的this 赋值给s,我们可以使用s.name,s.readBook(), 这样就能调用构造函数的属性或方法。
使用new操作符也等价于如下代码:
var s={
name:'marshal',
age:40,
bookName:'javascript'
}
二、执行过程分析
构造函数就是创建对象的函数,要创建一个实例,就需使用new操作符。
构造函数执行过程分析:
1)内存中创建一个新对象
2)这个新对象内部的prototype特性被赋值为构造函数的prototype属性
3) 构造函数内部的this 被赋值为这个新对象,this 指向新对象
4)执行构造函数内部的代码,给新对象添加属性和方法
5)如果构造函数返回非空对象,则返回该对象,否则返回刚创建的新对象
三、如何使用构造函数
只要使用new操作符调用的就是构造函数,没有使用new操作符调用的就是普通函数。<script>
function Student(name,age,bookName){
this.name = name;
this.age = age;
this.bookName=bookName;
this.readBook=function(){
console.log('大家好,我是'+this.name,'我现在年龄是'+this.age,'我还在读:'+this.bookName);
}
}
//作为构造函数调用,s 为Student()内部的this值
var s=new Student("marshal",40,"javascript");
s.readBook();//输出:大家好,我是marshal 我现在年龄是40 我还在读:javascript
//作为函数调用,如果没有使用call,apply,将履性和方法添加到window对象,this指向window
var w=Student("marshal",40,"javascript");
console.log(window.name);// marshal
</script>
四、构造函数问题
构造函数的主要问题是,其定义的方法会在每个实例上都重复创建一遍。
function Student(name,age,bookName){
this.name = name;
this.age = age;
this.bookName=bookName;
this.readBook=new Function("console.log(this.name)");//逻辑等价
}
var s1=new Student("marshal",40,"javascript");
var s2=new Student("marshal",40,"javascript");
//创建的实例机制一样,实现的功能都一样,没必要定义两个不同的Function实例,并且是在运行时阶段。
//解决方法可将readBook函数定义转移到外部
function readBook(){
console.log(this.name);
}
//这样s1 s2 共享了定义在全局作用域上的readBook函数,
//解决了相同逻辑函数重复定义的问题,但这样会污染了全局代码
//向外界暴露函数。这可以通过原型来解决该问题,后续将会讲解到。