- 构造函数
- 引入:使用工厂函数来创造对象时,使用var obj =new Object(),创建后都是object,无法区分
- 创建一个构造函数,专门用来创建特定类型的对象,例如人的对象,动物的对象。构造函数就是一个普通的函数,创建方式和普通函数没有差别,不同的是构造函数习惯上要大写
- 构造函数和普通函数的区别就是调用方式的不同,普通函数直接调用,而构造函数需要使用new关键字来调用
function Person(){
this.name = “孙悟空”;
this.age = 18;
this.sayName = function (){
Console.log(this.name)
}
}
var per = Person() //作为普通函数调用没有返回值,’undefined’
var per = new Person() //作为构造函数调用。’[object,object]’
- 构造函数的执行流程:
- 立刻创建一个新的对象
- 将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对 象
- 逐行执行函数中的代码
- 将新建的对象作为返回值返回
- 使用同一构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类
构造函数 = 类
我们将通过一个构造函数创建的对象,称为是该类的实例
- 使用instanceof可以检查一个对象是否是一个类的实例,值得一提的是所有对象作 instanceof object 都为真
语法:
对象 instanceof 构造函数
为真返回true,反之false
- 函数的prototype属性(我们所创建的每一个函数,解析器都会向函数中添加一个 prototype属性)
- 每个函数都有一个protoytpe属性,他默认指向一个object空对象(即为原型对象)
- 原型对象中有一个属性constructor,它指向函数对象
- 如果函数作为普通函数调用,prototype没有任何作用
- 当函数以构造函数的形式调用时,他所创建的对象中都会有一个隐含的属性
指向该构造函数的原型对象,我们可以通过__proto__来访问该属性
function Person(){
this.name = “孙悟空”;
this.age = 18;
this.sayName = function (){
Console.log(this.name)
}
}
var per1 = new Person()
var per2 = new Person()
per1.__proto__ == per2.__proto__ == Person.prototype//为true
也就是说通过构造函数(类)创建的同一个类下的所有实例的__proto__都指向这个构造函数(类)的原型对象(见下图)
- 给原型对象添加属性(一般都是方法)
作用:函数的所有实例对象自动拥有原型中的属性(方法)
原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中
当我们访问对象的一个属性或方法时:
他会在对象自身中寻找,如果有直接使用
如果没有则会去原型对象中寻找,如果找到则直接使用
如果没有则去原型的原型中寻找,直到找到object对象的原型
Object对象的原型没有原型,如果在object中依然没有找到,则返回undefined(如果找的是原型,就返回的是null),这也就是原型链的原理
函数.prototype.sayName = function(){
Console.log(this.name)
}
per1.sayName()
Per2.sayName()
Per3.sayName()
即使在对象以及构造函数中没有写sayName(),此时也可以调用,虽然在构造函数中写方法,也可以实现,但每创建一个对象就需要创建一个对应的函数方法,不够高效,所以一般来说公用的方法就放在原型对象上
我的理解:通过protoytpe向原型对象上添加方法,这样在通过原型对象来实例化一个新对象时,就可以让这个新对象具有这个方法(有点继承的意思),也有点像vue中的全局事件总线,在给vue原型上添加eventbus,使得每一个组件都具有这个属性并通过$emit,$on来操作数据
显示原型与隐式原型
- 每个函数function都有一个prototype,即显式原型(属性)
- 每个实例对象都有一个_proto_,可称为隐式原型(属性)
- 对象的隐形原型的值为其对应构造函数的显式原型的值
- 如上图
- 总结:
- 函数的prototype属性:在定义函数时自动添加的,默认值是一个空object对象
- 对象的_proto_属性:在创建对象时自动添加的,默认值为构造函数的prototype属性值
- 程序员可以直接操作显式原型但不可以直接操作隐式原型