js创建对象的方式

创建对象的方式

  1. 对象字面量
  2. 构造函数
  3. 工厂模式
  4. 构造函数模式
  5. 原型模式
  6. 组合模式
  7. 动态原型模式
  8. 寄生构造函数模式
  9. 稳妥构造函数模式

逐项说明

一、对象字面量
var obj = {};
复制代码

实例特性:对象之间相互独立

  • 优势:代码简洁
  • 劣势:使用同一个接口创建多个对象会产生很多重复代码
二、构造函数
var obj = new Object();
复制代码

实例特性:对象之间相互独立

  • 优势:代码简洁
  • 劣势:使用同一个接口创建多个对象会产生很多重复代码
三、工厂模式
function createObj(name, list) {
    var o = new Object();
    o.name = name;
    o.list = list;
    o.sayName = function() {
        alert(this.name);
    }
    return o;
}
var obj1 = createObj('obj1Name', [1]);
var obj2 = createObj('obj2Name', [1, 2]);
obj2.list.push(3);
console.log(obj1.list, obj2.list);      // [1] [1, 2, 3]
console.log(obj1.sayName === obj2.sayName);     // false
复制代码

实例特征:对象之间相互独立,不共享属性和方法

  • 优势:抽象创建对象的流程
  • 劣势:无法识别对象的类型
四、构造函数模式
function Obj(name, list) {
    this.name = name;
    this.list = list;
    this.sayName = sayName;
}
function sayName() {
    alert(this.name);
}
var obj1 = new Obj('obj1Name', [1]);
var obj2 = new Obj('obj2Name', [1, 2]);
obj2.list.push(3);
console.log(obj1.list, obj2.list);      // [1] [1, 2, 3]
console.log(obj1.sayName === obj2.sayName);     // true
复制代码

实例特征:对象之间相互独立,但可有共享的方法(全局中)

  • 优势:避免显式地创建对象,直接将属性和方法赋给this对象,避免了return
  • 劣势:全局作用域下定义多个对象的函数并不合理
构造函数与函数的区别:
构造函数:大写字母开头,new操作符调用
普通函数:小写字母开头,正常调用(this对象指向当前作用域所属的对象)
复制代码
使用new操作符创建特定类型的对象:
1. 创建一个新对象
2. 将构造函数的作用域赋给新对象(this指向的新对象)
3. 执行构造函数中的代码(添加属性)
4. 返回新对象
复制代码
五、原型模式(所有原生的引用类型均采用此模式创建的)
function Obj() {}
Obj.prototype = {
    constructor: Obj,
    name: 'obj1Name',
    list: [1, 2],
    sayName: function() {
        alert(this.name);
    }
}
var obj1 = new Obj();
var obj2 = new Obj();
obj2.list.push(3);
console.log(obj1.list, obj2.list);      // [1, 2, 3] [1, 2, 3]
console.log(obj1.sayName === obj2.sayName);     // true
复制代码

实例特性:对象间共享属性和方法,失去独立性

  • 优势:原型中所有属性和方法均共享,不必在构造函数中定义对象信息
  • 劣势:属性共享造成对象间失去独立性
六、组合模式(构造函数模式+原型模式,创建自定义类型最常见的方式)
function Obj(name) {
    this.name = name;
    this.list = [1, 2];
}
Obj.prototype = {
    constructor: Obj,
    sayName: function() {
        alert(this.name);
    }
}
var obj1 = new Obj('obj1Name');
var obj2 = new Obj('obj2Name');
obj2.list.push(3);
console.log(obj1.list, obj2.list);      // [1, 2] [1, 2, 3]
console.log(obj1.sayName === obj2.sayName);     // true
复制代码

实例特性:对象间既有共享的方法或属性,又有独立的方法或属性。

  • 优势:利用构造函数模式定义属性(支持传参),利用原型模式定义共享的方法和属性
  • 劣势:每次创建对象都要初始化原型对象,缺乏封装性
七、动态原型模式(个人认为最佳)
function Obj(name) {
    this.name = name;
    this.list = [1, 2];
    if(typeof this.sayName !== 'function') {
        Obj.prototype.sayName = function() {
            alert(this.name);
        }
    }
}
var obj1 = new Obj('obj1Name');
var obj2 = new Obj('obj2Name');
obj2.list.push(3);
console.log(obj1.list, obj2.list);      //  [1, 2] [1, 2, 3]
console.log(obj1.sayName === obj2.sayName);     // true
复制代码

实例特性:对象间既有共享的方法或属性,又有独立的方法或属性。

  • 优势:代码封装性较好,同时避免多次初始化原型对象
八、寄生构造函数模式(不推荐)
function Obj(name) {
    var o = new Object();
    o.name = name;
    o.sayName = function() {
        alert(this.name);
    };
    return o;
}
var obj1 = new Obj('obj1Name');
var obj2 = new Obj('obj2Name');
console.log(obj1.sayName === obj2.sayName);     // false
console.log(obj1 instanceof Obj);       // false
复制代码

实例特性:对象间相互独立,没有共享方法或属性

  • 优势:可在特殊情况下为对象创建构造函数(如创建一个具有特殊方法的数组,由于不能直接修改Array构造函数,则可使用此模式)
  • 劣势:不能通过instanceof来确定对象的类型
九、稳妥构造函数模式(在安全环境下)
function Obj(name) {
    var o = new Object();
    o.sayName = function() {
        alert(name);
    }
}
var obj1 = Obj('obj1Name');
obj1.sayName();
复制代码
  • 优势:适合在某些安全执行环境中(禁止使用this、new)或防止被其他应用程序改动时使用,只能通过特定的方法访问属性。

转载于:https://juejin.im/post/5afa8f186fb9a07acd4de01d

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值