1. 创建空对象 new Object()
var obj = new Object()
缺点: 每个属性方法都要重新单独设置。
2. 字面量{}
var obj = {}
缺点: 多个一个的对象不能复用
3. 工厂函数方式
缺点: 本质还是new Object(),无法根据对象的原型对象准确判断对象的类型
function createUser(name, age) {
var o = new Object();
o.name = name;
o.age = age;
o.say = function () {
alert(this.name);
}
return o;
}
var p1 = createUser("jason ",18);
4. 构造函数方式
- 先用构造函数定义一类对象的统一属性结构和方法,
- 再用new调用构造函数反复创建相同属性结构, 不同属性值的多个对象
缺点: 如果构造函数中包含方法, 则重复创建, 浪费内存
function User(name, age) {
this.name = name;
this.age = age;
this.info = function () {//这里每次new 都会重复创建 info 对象
}
}
var user = new User("jason", 11)
5. 原型对象prototype
先创建空的对象, 再给对象的原型上添加个性的属性和方法。
缺点:
- 所有父对象属性方法不能聚合在一起
- 所有属性引用同一个,会互相干扰
function Person() {}
Person.prototype.name = "jason";
Person.prototype.age = 18;
Person.prototype.say = function () {
console.log(this.name);
};
var p1 = new Person(); //创建一个实例p1
p1.name = "jason" //由于js 禁止修改原型上的属性,当失败时,会自动给子对象添加改属性。
var p2 = new Person(); //创建实例p2
p2.name = "jason2"; //同上
console.log(p1);
console.log(p2);
6. 混合/组合模式 (构造函数+prototype)
目前比较多人使用的方法
先用构造函数创建对象, 再用原型添加定制的属性和方法。
优点:
- 属性统一聚合
- 方法共用一个
缺点:
- 属性和方法被分离
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function () {//这里定义的原型方法say ,所有实例不会重复创建方法对象
console.log(this.name);
}
var p1 = new Person("jason", 11);
var p2 = new Person("jason2", 12);
p1.say()
p2.say()
7. 动态混合 (构造函数+ prototype放在构造函数if判断)
只用一个构造函数创建,把原型的方法通过判断放入构造函数里。
缺点: 虽然已经把构造函数里的变量和方法合并在一起。但是整体可编写性和可读性差
function Person(name, age) {
this.name = name;
this.age = age;
if (Person.prototype.say === "undefined") { //为了避免重复创建say对象方法,所以添加判断,使得智能执行一次。
Person.prototype.say = function () {
console.log(this.name);
};
}
}
var p1 = new Person("jason", 11);
var p2 = new Person("jason2", 12);
console.log(p1);
console.log(p2);
8. 寄生构造函数 (子构造函数里调父构造函数)
缺点: 可读性差,逻辑有点交叉混乱。
function Person(name, age) {
this.name = name;
this.age = age;
}
function Student(name, age, className) {
var p = new Person(name, age); //
p.className = className //这里可以新增属性
return p;
}
var p1 = new Student("jason", 11, "初一");
var p2 = new Student("jason2", 12, "初二");
console.log(p1.className);
console.log(p2.className);
9. ES6 class:
class User2 {
constructor(name,age){
this.name = name
this.age = age
}
info(){
console.log("name:",this.name)
console.log("age:",this.age)
}
}
var user2 = new User2("jason",18)
user2.info()
10. 闭包
优点
- 不用this和new
- 并且是一个独立的沙盒空间 缺点
- 容易造成内存泄漏
- 所有属性也要通过方法的方式定义,代码冗余
function Person(name, age) {
var p = {};
p.getName = function () {
return name
};
p.setName = function (value) {
name = value
};
p.getAge = function () {
return age
}
return p;
}
var p1 = Student("jason", 11);
var p2 = Student("jason2", 12);
console.log(p1.getName());
console.log(p1.getAge());
console.log(p2.getName());
console.log(p2.getAge());