一、Object 构造函数 - 模式
缺点:创建时语句太多
let obj = new Object();obj.name = '张三';obj.age = 11;
二、对象字面量 - 模式
优点:创建时,语句只有一行
缺点:多次创建时,存在代码冗余
let obj1 = {name: '张三',age: 11}// 多次创建,代码冗余let obj1 = {name: '李四',age: 12}
三、工厂模式
优点:重复创建时,避免代码冗余
缺点:无法区分类型
function Student() {let obj = {name: '张三',age: 12}return obj;}function Teacher() {let obj2 = {name: '王老五',school: '数据学院'}return obj2;}let stu = Student();let tea = Teacher();console.log(stu instanceof Student); // falseconsole.log(stu instanceof Teacher); // false
如上,显然 stu理应属于 Student,然而输出却为 false
四、自定义构造函数模式
优点:可以区分类型
function Student() {
this.name = '张三',
this.age = 12
}
function Teacher() {
this.name = '王老五',
this.school = '数据学院'
}
let stu = new Student();
let tea = new Teacher();
console.log(stu instanceof Student); // true
console.log(stu instanceof Teacher); // false
缺点:存在函数重复,例如
function Student(name, age) {
this.name = name,
this.age = age
this.setName = name => {
this.name = name;
}
}
let stu1 = new Student('张三', 12);
let stu2 = new Student('李四', 14);
console.log(stu1, stu2);
输出结果如下
注意:prototype实际上是 __proto__,只是浏览器将其叫成了前者,若输出 stu2.prototype仍然为 undefined
console.log(stu1.prototype); // undefined
console.log(stu1.__proto__); // 输出与图中的 prototype 相同
显然 setName()在两个实例中,都是一样的,所以应该让其存储到原型链中去(实例的__proto__)
五、构造函数 + 原型链组合
优点:重复的函数放到原型中,减少了内存的使用
function Student(name, age) {
this.name = name,
this.age = age
}
Student.prototype.setName = function() { // 此处用箭头函数会导致 this 异常
this.name = name;
}
let stu1 = new Student('张三', 12);
let stu2 = new Student('李四', 14);
stu1.setName('王老五');
console.log(stu1, stu2);
输出结果如下
