内置构造函数创建
我们可以直接通过 new Object()
创建:
//在js中,对象有动态特性,可以随时的给一个对象增加属性或者删除属性。
var person = new Object()
person.name = 'Jack'
person.age = 18
person.sayName = function () {
console.log(this.name)
}
缺点:麻烦,每个属性都需要添加。
对象字面量创建
var person = {
name: 'Jack',
age: 18,
sayName: function () {
console.log(this.name)
}
}
缺点:如果要批量生成多个对象,应该怎么办?代码很冗余
简单改进:工厂函数
我们可以写一个函数,解决代码重复问题:
function createPerson (name, age) {
return {
name: name,
age: age,
sayName: function () {
console.log(this.name)
}
}
}
然后生成实例对象:
var p1 = createPerson('Jack', 18)
var p2 = createPerson('Mike', 18)
缺点:但却没有解决对象识别的问题,创建出来的对象都是Object类型的。
继续改进:构造函数
构造函数是一个函数,用于实例化对象,需要配合new操作符使用。
function Person (name, age) {
this.name = name
this.age = age
this.sayName = function () {
console.log(this.name)
}
}
var p1 = new Person('Jack', 18)
p1.sayName() // => Jack
var p2 = new Person('Mike', 23)
p2.sayName() // => Mike
而要创建 Person
实例,则必须使用 new
操作符。
以这种方式调用构造函数会经历以下 4 个步骤:
- 创建一个新对象
- 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象)
- 执行构造函数中的代码
- 返回新对象
构造函数需要配合new操作符使用才有意义,构造函数首字母一般为大写
构造函数的缺点
使用构造函数带来的最大的好处就是创建对象更方便了,但是其本身也存在一个浪费内存的问题:
function Person (name, age) {
this.name = name
this.age = age
this.type = 'human'
this.say = function () {
console.log('hello ' + this.name)
}
}
var person1 = new Person('lpz', 18)
var person2 = new Person('Jack', 16)
console.log(person1.say === person2.say) // => false
解决:提取同一个 say
方法
- 解决了浪费内存的弊端
- 但是造成了
污染全局变量
的问题
// 提前将say 声明好
function say() {
console.log(this.name);
}
function createStudent(name, age) {
this.name = name;
this.age = age;
this.say = say
}
const obj = new createStudent("悟能", 83);
const obj1 = new createStudent("悟能1", 84);
console.log(obj.say === obj1.say); // true