第一章:JavaScript设计模式--面向对象之封装

JavaScript是一门面向对象的语言,要理解面向对象,就一定要先理解面向对象之前的变成方式——面向过程。

面向过程的代码其实对于小白程序员一点也不陌生,学习一门语言,特别是在学完function之后,每个人都会别写大量的面向过程的代码。面向过程说白了就是按照解决问题 的流程,声明一堆方法,然后调用方法解决问题。

那面向对象呢?面向对象就是/*将你的需求抽象成一个对象那个,然后针对这个对象分析其特征(属性)与动作(方法),以上都是屁话,所以注释掉。*/先创建对象,然后调用对象的方法来解决问题。为啥要这么做?声明函数然后调用不是挺好的吗?先举个简单的例子:你要搬家,你家有1000个东西(衣服袜子内裤拖鞋洗漱用品电子产品书床上用品套套各种卡,你敢说你家没1000件东西?),你会一件一件的搬还是将他们打包后再搬?你搬家这样,写代码也是这样。

下面说正事,先讲讲创建对象的n种方式:直接量、new Object、构造函数(类)。。。。。。

但是用的最多的还是构造函数(类)方式,为啥?第一,因为别的语言都是这么写的。。第二:因为它好用,用好了可以实现封装和继承。

假如你还不会使用构造函数,或者没听说过啥叫封装和继承,请自行离开去百度,然后请过一段时间再回来,因为下面的内容可能不太适合你,会引起的你一些不适。

今天,咱们来好好唠唠封装和继承的高级用法。。。

封装,说白了就是声明构造函数(声明类)

提示:下面构造函数我会用‘类’来代替,为啥?因为类就一个字,我只说一次。。。

先来看看类的私有属性和共有与属性:

    function Book(name){
        //私有属性/方法
        var num=1;

        //共有属性/方法
        this.getName=function(){console.log(name)};

        //特权方法  能够操纵私有属性、方法
        this.getNum=function(){console.log(num)};
        this.setNum=function(n){num=n};
    }
    var b=new Book('html5')
    console.log(b.num);       //undefined
再来看看共有属性和/方法、类静态共有属性/方法:
    function Book(name){
        //私有属性/方法
        var num=1;

        //共有属性/方法
        this.getName=function(){console.log(name)};

        //特权方法  能够操纵私有属性、方法
        this.getNum=function(){console.log(num)};
        this.setNum=function(n){num=n};
    }
    //类静态共有属性 (对象不能访问)
    Book.isChinese=true;
    //类静态共有方法 (对象不能访问)
    Book.resetTime=function(){
        console.log(new Date());
    };
    Book.prototype={
        //共有属性
        isJSBook:true,
        //共有方法
        display:function(){}
    };
    var b=new Book('JavaScript');

    console.log(b.num);       //undefined
    console.log(b.isJSBook);  //true
    console.log(b.isChinese);  //undefined
共有属性/方法用于创建对象后调用。类静态属性和方法对象不能调用,但类可以(类是个函数,函数是个对象,对象就有属性和方法,没听过?那你听说过构造函数的prototype属性吧?)。私有属性/方法一般是不想被修改的,但为了获取他们都留有特权方法。


 接下来,咱们来看看闭包实现私有属性的方式一:

    var Book=(function(){
        //静态私有变量
        var bookNum=0;
        //返回构造函数
        return function(id,name,price){
            //私有变量
            var name,price;
            //特权方法
            this.getName=function(){};
            this.setName=function(){};
            //公有属性/方法
            this.id=id;
            this.copy=function(){};
            //调用 静态私有变量
            bookNum++;
            if(bookNum>100){throw new Error('我们仅出版100本书')}
        }
    })();
    //类静态共有属性 (对象不能访问)
    Book.isChinese=true;
    //类静态共有方法 (对象不能访问)
    Book.resetTime=function(){
        console.log(new Date());
    };
    Book.prototype={
        //共有属性
        isJSBook:true,
        //共有方法
        display:function(){}
    };
    var b=new Book('JavaScript');

    console.log(b.bookNum);   //undefined
    console.log(b.isJSBook);  //true
    console.log(b.isChinese); //undefined

闭包实现私有属性的方式二——直接返回一个完整的类

		var Book=(function(){
			//静态私有变量
			var bookNum=0;
			//返回构造函数
			function _book(id,name,price){
				//私有变量
				var name,price;
				//特权方法
				this.getName=function(){};
				this.setName=function(){};
				//公有属性/方法
				this.id=id;
				this.copy=function(){}
				//调用 静态私有变量
				bookNum++;
				if(bookNum>100){throw new Error('我们仅出版100本书')}
			}
			//类静态共有属性 (对象不能访问)
			_book.isChinese=true;
			//类静态共有方法 (对象不能访问)
			_book.resetTime=function(){
				console.log(new Date());
			};
			_book.prototype={
				//共有属性
				isJSBook:true,
				//共有方法
				display:function(){}
			};
			return _book;
		})();

		var b=new Book('JavaScript');

		console.log(b.bookNum);   //undefined
		console.log(b.isJSBook);  //true
		console.log(b.isChinese); //undefined
最后,因为很多小白用户在实例化对象(挺牛逼是不?其实就是通过new创建对象啦)时老实忘记写new,所以我们来了解一下封装的安全模式:

		function Book(name){
			//判断 执行时 this 是否指向 当前对象
			//如果是 说明是 new 创建的
			if(this instanceof Book){
				this.name=name;
			//否则创建新对象
			}else{
				return new Book(name);
			}
		}
		var h=new Book('html5');
		var j=Book("JavaScript")
		console.log(h.name);
		console.log(j.name);

最最后,是关于向类的原型(构造函数的prototype)中链式添加方法和链式操作的小技巧:

		//在Function 的 prototype 中 添加方法addMethod
		//方法有两个参数  方法名  和  方法
		Function.prototype.addMethod=function(name,fn){

			//将 第二个参数方法  放入 调用本方法  的  对象的 prototype 中  ,名字为第一个参数方法名
			this.prototype[name]=fn;

			return this;//返回this  为了链式添加
		};


		//声明一个构造函数
		var methods=function(){};


		//调用  function  的 addMethod 方法,向 methods 中添加方法
		methods.addMethod('checkName',function(){
			//验证用户名  的代码
			console.log('check 用户名')
			return this;  //返回this  为了能够链式操作
		}).addMethod('checkEmail',function(){
			//验证邮箱   的代码
			console.log('check 密码')
			return this;  //返回this  为了能够链式操作
		});

		//实例化  methods  类
		var a=new methods;
		a.checkName().checkEmail()

关于面向对象中封装的技巧就向大家介绍到这里,下一篇会向大家介绍面向对象中继承的一些小技巧




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值