在es6之前,对象不是基于类创建的,而是用一种称为构造函数的特殊函数来定义对象和它们的特征。
当需要很多很多对象时,而这些对象又有相同的属性和方法。这时需要把它抽离出来,再大量的生成对象,这时候就需要构造函数。
创建对象可以通过以下三种方式:
1.对象字面量
var obj1 = {}
2.new Object()
var obj1 = new Object()
3.自定义构造函数
function Student(name, age) {
this.name = name
this.age = age
this.study = function() {
console.log(this.name + '在学习')
}
}
var zs = new Student('张三', 18)
console.log(zs) // Student {name: "张三", age: 18, study: ƒ}
zs.study() // 张三在学习
var ls = new Student('李四', 19)
console.log(ls) // Student {name: "李四", age: 19, study: ƒ}
ls.study() // 李四在学习
// 实例成员就是构造函数内部通过this添加的成员 name age study就是实例成员
// 实例成员只能通过实例化的对象来访问
console.log(zs.name) // 张三
console.log(Student.name) // undefined 或 Student
每当需要一个新的对象,就new一个新的对象。
构造函数是一个特殊的函数,主要用来初始化对象,即为成员变量赋初始值,它总与new一起使用。我们可以把对象中的一些公共的属性和方法抽取出来,然后封装到这个函数里。
new 在执行时会做四件事情:
1.在内存中创建一个新的空对象。
2.让this指向这个对象。
3.执行构造函数中的代码,给这个对象添加属性和方法。
4.返回这个新对象(所以构造函数不需要return)。
构造函数存在的问题:浪费内存
当有多个对象实例化时,构造函数里的方法会开辟多个新的内存空间,既浪费时间又浪费内存
解决方法:构造函数原型对象 :prototype
构造函数通过原型分配的函数是所有对象所共享的。
原型是什么?原型是一个对象,我们也称为prototype为原型对象。
原型的作用是什么?共享方法
每一个构造函数都有一个prototype属性,指向另一个对象,这个prototype就是一个对象,这个对象的所有的属性和方法都会被构造函数所拥有。
我们可以把那些不变的方法,直接定义在prototype对象上,这样所有的对象的实例都可以使用这些方法。
用法:Student.prototype.study = function() {
console.log("在学习")
}
console.log(zs.study === ls.study) // true
这些i对象实例化都指向同一个地址,实现方法的共享。
那么关于构造函数的this指向是怎样的呢?
前面已经说过了
构造函数的this指向的是对象实例本身,那么构造函数的原型对象的this指向的又是谁呢?
function Student(name, age) {
this.name = name
this.age = age
}
var that
Student.prototype.study = function() {
console.log('在学习')
that = this
}
var zs = new Student('张三', 18)
zs.study()
console.log(that === zs)输出的是true,那么证明构造函数的原型对象指向的也是zs对象