JS中的面向对象

面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式

什么是面向对象?面向对象是一种思想!(废话)。
  面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法。这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作。接下来将为大家讲解在JS中面向对象的实现。
  一.工厂模式
  工厂模式是软件工程领域一种广为人知的设计模式,而由于在ECMAScript中无法创建类,因此用函数封装以特定接口创建对象。其实现方法非常简单,也就是**在函数内创建一个对象,给对象赋予属性及方法再将对象返回即可。**

  //工厂模式
    function createStudent(no,name,age,grade){
        var obj=new Object();//创建一个对象
        //添加属性
        obj.no=no;
        obj.name=name;
        obj.age=age;
        obj.grade=grade;
        //添加方法
        obj.test=function(){
            console.log(this.name+"在考试......");
        };
        return obj;
    }

    var s1=createStudent('1000','李四',20,'一年级');
    var s2=createStudent('1001','王五',30,'二年级');

    s1.test();
    s2.test();
    console.log(s1);
    console.log(s2);
    console.log(s1.test==s2.test);//false

可以看到工厂模式的实现方法非常简单,解决了创建多个相似对象的问题,但是**工厂模式却无从识别对象的类型**,因为全部都是Object,不像Date、Array等,因此出现了构造函数模式。

二.构造函数模式

ECMAScript中构造函数可以创建特定类型的对象,类似于Array、Date等原生JS的对象。

 // var arr=new Array();//构造函数
        // var date=new Date();
        //当构造函数被new关键字调用时,系统会自动的创建一个Object对象,为该对象绑定舒心和方法
        //并且调用结束时,将改对象返回
        //构造函数
        function Student(no,name,age){
            //新增属性
            this.no=no;
            this.age=age;
            this.name=name;
            //新增方法
            this.run=function(){
                console.log(this.name+" is running.........");
            };
        }

        //构造函数需要使用new来调用
        var s=new Student('2000','李四',22);//创建学生对象
        console.log(s);

        var s1=new Student('2001','Jack',23);
        console.log(s1);

        console.log(s1.run==s.run);//false

这个例子与工厂模式中除了函数名不同以外,细心的童鞋应该发现许多不同之处:

1.函数名首写字母为大写  (虽然标准没有严格规定首写字母为大写,但按照惯例,构造函数的首写字母用大写
2.没有显示的创建对象
3.直接将属性和方法赋值给了this对象
4.没有return语句
5.使用new创建对象
6.能够识别对象(这正是构造函数模式胜于工厂模式的地方)

  构造函数虽然好用,但也并非没有缺点,使用构造函数的最大的问题在于每次创建实例的时候都要重新创建一次方法(理论上每次创建对象的时候对象的属性均不同,而对象的方法是相同的),然而创建两次完全相同的方法是没有必要的,因此,我们可以将函数移到对象外面。
 三.原型模式
  **我们创建的每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。**使用原型对象的好处就是可以让所有对象实例共享它所包含的属性及方法。

function Person() {

}
// 虽然写在注释里,但是你要注意:
// prototype是函数才会有的属性
Person.prototype.name = 'Kevin';
var person1 = new Person();
var person2 = new Person();
console.log(person1.name) // Kevin
console.log(person2.name) // Kevin

原型模式也不是没有缺点,首先,它省略了构造函数传递初始化参数这一环节,结果所有实例在默认情况下都取得了相同的属性值,这样非常不方便,但这还是不是原型的最大问题,原型模式的最大问题在于共享的本性所导致的,由于共享,因此因此一个实例修改了引用,另一个也随之更改了引用。因此我们通常不单独使用原型,而是结合原型模式与构造函数模式。
三.混合模式(原型模式 + 构造函数模式)
将属性的声明在构造函数中完成, 将方法的声明放入原型中


        function Person(no,name){
            //属性
            this.no=no;
            this.name=name;
        }

        //将方法放入原型中
        Person.prototype.say=function(){
            console.log(this.name+" 在说话..........");
        };

        Person.prototype.walk=function(){
            console.log(this.name+" 在走路。。。。。。。。。");
        };

        // console.log(Person);
        var p=new Person('54413241','Jack');
        var p1=new Person('42342342','Tom');
        p.say();

        p1.walk();


        console.log(p.say==p1.say);//true

        console.log(p);

混合模式中构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性。每个实例都会有自己的一份实例属性,但同时又共享着方法,最大限度的节省了内存。另外这种模式还支持传递初始参数。优点甚多。这种模式在ECMAScript中是使用最广泛、认同度最高的一种创建自定义对象的方法。

四. 动态原型模式

动态原型模式将所有信息封装在了构造函数中,而通过构造函数中初始化原型**(仅第一个对象实例化时初始化原型)**,这个可以通过判断该方法是否有效而选择是否需要初始化原型。

function Blog(name, url) {
    this.name = name;
    this.url = url;

    if (typeof this.alertInfo != 'function') {
        // 这段代码只执行了一次
        alert('exe time');
        Blog.prototype.alertInfo = function() {
            alert(thia.name + this.url);
        }
    }
}

var blog = new Blog('Rampage_w', 'https://blog.csdn.net/Rampage_w/article/details/100597522'),
    blog2 = new Blog('Rampage_w', 'http:***.com');

可以看到上面的例子中只弹出一次窗,'exe time',即当blog初始化时,这样做blog2就不在需要初始化原型,对于使用这种模式创建对象,可以算是perfect了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值