创建对象的方法,理解各个方法的好处和缺点,为什么要改进

1. new Object或字面量

虽然Object构造函数或字面量都可以创建单个对象,可是其明显的缺点在于,使用同一个接口创建很多个对象,会产生很多重复性代码。

  obj = {
            name: 'liujie',
            age: 12
        }

2. 工厂模式

为解决上面问题,考虑采取工厂模式,考虑到ECMAacript中无法创建类,开发人员发明了一种函数,用函数来封装特定接口创建对象的细节。
函数Person根据接受的参数来构建所有必要信息的Person对象,可无数次调用,但有一个缺点,无法直到对象的类型,在这种情况下都是Object类型,如何创建一个可定义类型的方法呢。

function Person(name, age) {
            var obj = new Object();
            obj.name = name;
            obj.age = age;
            obj.sayName = function() {
                alert(this.name)
            }
            obj.sayName();
            return obj
        }
        var person1 = Person('孙悟空', 1);
        var person1 = Person('liuuu', 22);
        console.log(person1);
 function Dog(name, age) {
            var obj = new Object();
            obj.name = name;
            obj.age = age;
            obj.sayName = function() {
                alert(this.name)
            }
            obj.sayName();
            return obj
        }
		var dog1 = Person('旺财', 1);
        console.log(dog1 instanceof Object);//true

3. 构造函数模式

构造函数可创建特定类型的对象,像Object和Array这样的原生构造函数,在运行时自动出现在执行环境中,也可创建自定义的构造函数,从而为其定义对象的属性和方法。

        function Person(name, age) {
            this.name = name;
            this.age = age;
            this.sayName = function() {
                alert(this.name);
            }
        }
        var person1 = new Person('孙悟空', 11);
        var person1 = new Person('刘洁', 12);
        console.log(person1 instanceof Person);//true

可以看出,构造函数与工厂模式创建函数的不同之处可归纳为以下几点:
1.没有显示创建对象;2. 直接将属性和方法赋给this对象 3. 没有return

要创建Person的实例,必须使用new操作符,以上面例子来说,这种方法调用构造函数会经历以下4个步骤:
(1)创建新对象person1=new Person();
(2)将构造函数的作用域赋给新对象,因此this可指向这个新对象person1;
(3)执行构造函数的代码;
(4)返回新对象。

上面的person1和person2分别保存着Person的不同实例,这两个对象均有一个constructor属性,该属性指向Person,可以用instanceof检测其归属的实例。

console.log(person1 instanceof Person)//true

构造函数的缺点:
每个方法都有在每个实例上重新创建一遍。如果person1和person2都有一个sayName()的方法,但两个方法不是同一个Function实例。不同实例上的同名函数是不相等的。

console.log(person1.sayName == person2.sayName);//false

创建两个完成同样任务的Function实例没有必要,而且还有this对象在,不需要在执行代码前就把函数绑定在特定对象上,可以像下面这样。

        function Person(name, age) {
            this.name = name;
            this.age = age;
            this.sayName = sayName;
        }

        function sayName() {
            alert(this.name);
        }

可是,在全局作用域中定义的函数只能被某个对象调用这个引用类型完全没有封装性可言。可通过原型函数来解决。

4. 原型模式

我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向对象,这个对象的用途包括一些共享的属性和方法。这个好处在于:
共享:也就是说不必在构造函数中定义对象实例的信息,而将这些信息直接添加到其原型对象中

 function Person() {

        }
Person.prototype.name = "liujie";
Person.prototype.sayName = function() {
    alert(this.name);
        };
var person1 = new Person();
var person2 = new Person();
console.log(person1);

这种方式创建的sayName则是所有对象实例共享的方法,而不必在构造函数中定义(而为每个实例创建一个相同的方法),完全可写在原型对象中。

console.log(person1.sayName == person2.sayName);//true

可见perosn1和person2访问的是同一个sayName函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值