谈谈js诡异的面向对象设计

         语言是种工具,设计出来的根本还是解决问题。那么软件工程是重中之重,各种框架、类库、设计模式漫天飞舞。

        js是一门新生的语言,最开始在工程问题上没有太深入的运用。但是随着互联网的发展壮大和用户体验变得越来越重要,js的工作量也是指数行上涨。面对日益复杂的前端交换和成千上万的代码管理。软件工程设计就成了一门必修课程。

        如果想要构建大型软件,并且以一种合适的模型来对实际事物建模,那么面向对象编程方式,是一种绝佳的代码组织方式。许多语言都对面向对象编程有不同程度上的支持,比方说:C++、Java、php等。

        而面向对象编程的核心思想就是:把一组数据和它可以进行的操作看作一个整体。这个模式是从开始的结构体演变而来,同时面向对象还提出类的概念:一组有相同属性事物的抽象模板。通过对模板传入数据,来制造一个个具体的实例对象。

        在程序中,对面向对象进行代码实现的基础,就是拷贝操作。将一组数据和操作,原封不动的传给另一个对象,如此便十分快捷方便的创造了一个新对象。

        但是,这种面对对象的设计模式,在js中就难以实现了。因为js中并没有类这个类似版模的概念,js中只有对象:一个无序的键值对而已。既然js只有对象,那么更提不上可以进行的实例化操作了。

        为了支持面向对象,js在函数上做文章,设计出来了原型对象这个概念,用以支持面向对象。但是,这个函数对象只能一定程度上去模拟oo,js不会用向其他语言一样通过类模板进行复制生产对象,相反js所有生成的对象都是引用的同一个对象。

        来看个简单的代码:

    function Car() {this.a=a};
    Car.prototype.cout=function(){alert('原型对象')};
    var mCar=new Car(12);
<pre name="code" class="javascript">    mCar.a;
  mCar.cout();

         当我们看到'.'操作符时,按照以往的编程经验,我们自然而然会联想到,这个变量是对象下的一个属性。mCar.a确实是如此,a是一个在mCar上的属性。但是.cout()却不是这样一回事:它是定义在另外一个原型对象上的属性。这样就出现了一个诡异的现象:构造函数上根本没有这个.cout()函数,但是我们的新对象居然可以去‘无中生有’的去访问它,虽然我们知道这是原型链的功能, 
但是这会极大降低我们代码的可读性。 

     es6新增加的语法糖class,看起来很像常规的面向对象:

     

  //es5
  function Car() {};
  Car.prototype.toString=function(){alert('一个新的原型对象')};
  var mCar=new Car();
  mCar.cout();
  //se6:class
  class Car{
   constructor(a){
     this.a=a;
   }
   toString(){
   alert('一个新的原型对象');
   }
  }
       下class的写法,只不过是对函数的new调用封装了一层语法糖,本质上没有改变:新对象不过是引用原型对象属性的事实,new调用永远不会进行复制操作,一旦你对原型对象的属性进行了改变,那么所有由该方法创造的对象都会收到影响:
  class Car{
   constructor(a){
     this.a=a;
   }
   toString(){
   alert('原来的原型对象');
   }
  }
  var mCar=new Car(5);
  mCar.toString();//原来的原型对象
  Car.prototype.toString=function(){alert('新的原型对象')};
  mCar.toString();//新的原型对象!!
  

  

     

   


          

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值