JavaScript_个人笔记1_JavaScript的面向对象是模仿的

    这几天看了一些javascript的资料,有一些想法和疑惑,整理整理放在这里当作一个历史足印。

    今天是第一篇,来点最基础的,说一说js的面向对象特性,总的来说,js的面向对象都是模拟的,跟一般的面向对象语言是有差异的,抓住这一点,所有的东西

    说到OO,无非就是三大特性:封装/继承/多态。这些特性的存在都是基于类和对象的,那么先说说js的类。

    js的类【模拟的类】:

  

//定义一个名为Person的类, function里面的内容就是构造函数了
var Person = function(name){
   //
   this.proname = name;
}

//静态方法
Person.write = function(str){
   document.write(str + "<br/>");
}


var person = new Person("Jim");
//静态方法 classname.StaticFuncName
Person.write(person.proname);

 js类的继承【模拟的类】:

  JS的继承是通过一个叫作prototype的关键字是来实现,只要是挂在prototype上的对象,是的,就是对象,JS里面一切皆对象。看代码:

//定义一个名为Person的类, function里面的内容就是构造函数了
var Person = function(name){
   //
   this.proname = name;
}

//静态方法
Person.write = function(str){
   document.write(str + "<br/>");
}

Person.prototype.walk = function(){
  Person.write("Person.walk");
}

//var person = new Person("Jim");
//静态方法 classname.StaticFuncName
//Person.write(person.proname);

var Student = function(){}
Student.prototype = new Person;
//缓存父类的walk方法
var personWalk = Student.prototype.walk;
//重写walk
Student.prototype.walk = function(){
  //父类的实现
  personWalk.call(this);
  Person.write("Student.walk");
}

var student = new Student;
student.walk();

输出的结果是:

Person.walk
Student.walk

这个例子演示了继承,也有点多态的味道,但是JS里面没有纯正的多态,总的来说所有的元素都是用于构造一种继承的样子。

目前看起来似乎跟一般的语言差不多,但是令我困惑以及有点小感悟的是下面这段

//Person基类?
var Person = function(){
   this.init.call(this, arguments);
}

Person.writeLn = function(str){
   document.write(str + "<br/>");
}

Person.prototype.init = function(){
   Person.writeLn("Person.init");
}

//Student子类?
var Student = function(){}
Student.prototype = new Person;
var personInit = Student.prototype.init;
Student.prototype.init = function(){
   personInit.call(this);
   Person.writeLn("Student.init");
}

var student = new Student;

//输出什么?

这段代码我原先想构造这么一种情况:构造函数中调用一个可以被改写的方法,子类改写了之后,在实例化子类的时候,根据多态,应该会输出子类的实现,但是这个输出的结果竟然是 Person.init。为什么?没有得到预期的结果啊!这个还只是调用基类的实现而已啊?怎么破?

    采用逐步屏蔽代码的方式,把最后一句(var student = new Student;
)屏蔽掉,一运行,竟然还是Person.init。这个结果让我恍然大悟!!!因为这个输出其实是Student.prototype = new Person;
这一句的结果,也就是说,我们的在实例化Student的时候,根本就没有执行walk方法。但是Student不是子类吗?最起码应该跟子类的构造函数一样啊?其实Student跟Person根本没有严格意义上的继承关系

     很明显,仔细看一下,Student的构造函数本身是空的,如果说Student跟Person有几毛钱的关系,也仅仅在于prototype存储的是Person的实例,这样一来,Student就可以使用Person在prototype中共享的方法walk而已!仅此而已!因此,可以说JS中根本就没有面向对象,所有面向对象的感觉都是模拟出来的,同时模拟得如此真切以至于初学者很容易陷进去。

     同时也说明了,prototype中存储的是一个对象,资料上一般说做原型对象。

     其实总结一下就是,Js里面的类与类之间的关系更多是通过 组合的方式来实现的模拟继承,具体来说就是通过prototype来实现的组合,因此说其没有多态也算是OK了。

     Prototype用来存储原型对象,而JS里面方法/属性其实都归属于对象,放在prototype上面就是用来共享的。用下面的一段代码结束:

   

//Person基类?
var Person = function(){
  
}

Person.writeLn = function(str){
   document.write(str + "<br/>");
}

Person.prototype.commonInfo = [];

var p1 = new Person("jim");
p1.commonInfo.push("aaa");
var p2 = new Person("Kate");
p2.commonInfo.push("bbb");
Person.writeLn ("commonInfo.length:" + p2.commonInfo.length);

输出的结果是:commonInfo.length:2

commonInfo算是一个属性了,看起来共享了相同的对象!!!这个对于理解JavaScript很关键也就可见一斑了。


 



 






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值