js中的(prototype,constronctor)与JAVA中的(继承,Class)有什么相似之处

不废话,直接进入主题。

function Father(){

this.name="123";

}

function Son(){
}

1.js的实例对象没有prototype属性,     

var son=new Son();

son是没有这个属性的。

2.prototype是该类型(除了Function)的父类型实例,

Son.prototype=new Father();

var son=new Son();

son.name 打印的就是123

因为
Function.prototype=function(){

[native code]

}

由var fun=new Function("")
          consloe.log(fun.toString())

打印的function  anonymous(){}
可得 Function继承一个匿名函数实例对象(这个匿名函数是native code类型的),
Function的例子对象获取不到Object.prototype对toString的修改,
是因为自身已经重写了toString,

Function的实例对象的调用的toString方法是自己重写,要想使用Object的toString除非删除自己的toString,方法使用delete function.toString然后继承Object.prototype
Function实例对象都无法获取一般类型原型修改的Object对象的结果)

可以理解java中父类是一个类型,而js中的父类是一个对象



3.实例对象的constructor是该实例对象的类型

var son =new Son();

son.constronctor打印的就是 function Son(){}

4.所有类型的constructor都是Function   包括Function 自己

Son.constronctor打印的就是function Fonction(){}

类比一下java
比如Java中声明一个类A
public class A{
}

A a=new A();
就等价于 Calss A=new Class();
A a=new A();

因为Class是类的类可以声明类
这个时候我们再来看看Function
var  functionAdd=new Function("a","b","return a+b");

functionAdd(1,2);

上边这段代码是没问题的,是不是看出一点门道

是的,Function有点像Class

function functionAdd(a,b){

return a+b;

}

functionAdd(1,2);

等价于  

var  functionAdd=new Function(a,b,"return a+b");

functionAdd(1,2);

Function是函数的函数。

5.所有类型(包括Object自身,除了Function)的最顶层父类的prototype 引用不同的Object实列(new Object()),这个new Object()实列真我们创建的是js创建的。

代码:

        function f(){
               // this.name="456"
            }
            
            function M(){}
            alert(f.prototype===M.prototype)

弹出的是false

继续验证:

       function f(){
               // this.name="456"
            }
            
            function M(){}
            Object.prototype.name="9999"
            var fx=new f();
            alert(fx.name)
            var mx=new M();
            alert(mx.name)

两次弹出的都是9999

解释:因为Object类继承了属性name,所以所有实例都会拥有改类继承的属性,因此fx和mx实列都会打印 9999

所以我们使用 
Son.prototype.show=function(){
 alert("123");
}
和
Object.prototypr.show=function(){
 alert("123")
}
是等价的。
son.show()都能弹出123

下面我们来解释一下Son.prototype.show什么意思  
这是给最顶层的父类(在js中中是一个Object实列对象)添加一个实列特性(方法是特性prototype,成员变量是属性attribute)。

 为什么说是顶层的父类添加show方法呢?举个小例子

 function  Father(){
}

function  Son(){

}

 Father.prototype=new Object()
Son.prototype=new Object()

Object.prototype=new Object();
这三个应该很容易清楚,
Object.prototype.name="我是一个属性"等价于(new Object()).name="我是一个属性"
Son和Father的实例都能访问name。
这个怎么理解那?
(new Object()).name="我是一个属性"相当于给Object实列添加了一个实例之间不共享的变量,只有当前实例和子类使用能访问到的变量。
讲到这里,还需要再延伸一下多种变量

public变量:

function M(){
  this.name="我是一个变量";
}
这里的变量name是一个public变量,即创建的每一个实例都会拥有该变量,类似Java
 class M(){
  public String M="我是一个变量";
}

静态变量:
js的静态变量很奇怪的不能被实例对象调用,Java中的静态变量可以被实例对象调用,实例方法不能被类直接调用。下面看代码
function  M(){
}
M.name="我是一个静态变量";
这就相当于给该类添加了一个静态变量;
只能通过M.name获取不能通过实例获取
这也是和Java代码理解有点区别的地方
var m=new M()
m.name这样会报undefine

私有变量:
私有变量Java中也介绍过只能在改类内部自己调用不能在该类外部调用
function M(){
  var name="我是一个私有变量";
}
所以
var m=new M();
m.name //undefine
M.name //undefine

好的,讲到这里会规正传,回到原来的位置
(new Object()).name就是一个仅供当前实例对象和子类使用的一个变量,如果再new Object()无法访问刚name;
又因为 Object类继承了这样一个实例所以拥有name属性
就像相当于
var object=new Object();
object.name="";
Object.prototyoe=object;
再简化就相当于
function Object(){
 this.name;
} 

这个name就是我们刚才所说的public类型的
因此每个Object实例都会拥有它
所以Son,Father也会拥有该属性

此时我们会有一个疑问,那如果修改Son.prototype.name会不会也修改Father的那,答案是否定的

因为他们修改的都是各自的Object实例 ,
而Object.prototype修改的虽然也是自己的实例但是别忘了,Object可是所有类的父类类型,Object变了相当于所有类的继承实例发生了改变,这个改变的过程是动态变化的。只要Object发生变法,所有创建的Object实列跟着变化。

这也给我们提供了一个比较方便的方法,比如你想让所有的类都拥有同一个方法或者同一个变量,我们可以通过操作Object.prototype来快速实现。
  

以上纯属个人理解,如有误或者不同看法可以留言。
 

发布了28 篇原创文章 · 获赞 16 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/sunboylife/article/details/103759781
今日推荐