Javascript原型链研究

前言:如果想深入理解Javascript的面向对象编程思想,那么对于原型链的理解将十分重要,由于看了李战老师的<悟透Javascript>,产生了很多疑问,于是带着疑问在网络上查找答案,也翻出了Ecma-262来看了,总算明白了一些东西。

 

一.类别和对象


在Javascript没有所谓的其他高级语言中的”类”的概念,

 

所有的”数据”除了基本“类型” 便是对象Object(普通对象object和函数对象function) .

如果从集合论的角度在思考问题,我们可以将所有的这些数据进行分类,那么可以得到如下几类:

Undefined,Null,Boolean,Number,String还有Object

所有的基本数据类型必定属于前面五种类型(Type)之一,而复杂的数据类型只有Object一种.

我们可以举例说明一下,


Undefine={undefined}

Null={null}

Boolean={true,false}

Number={0,1,2,0.1……}

String={’a',’b',’123′,…}

Object={{a:1},function f(){},…}

以上的只是简单的说明,并不严谨.

有了以上的说明我们再来看typeof这个运算符

其实typeof就是根据上面的这些类型来判断并返回结果的



 

二.内建对象(Build-in Object)


在Javascript语言中有一些内建对象(他们的typeof值为function),其中有Global,Object,Function,Array,String,Boolean,Number,Math,Date,RegExp(注意这里和上面所讲的“类别”是两码事)还有一些其他的错误类,这里暂不一一列举.这些内建对象其实都是构造器,或者说它们都是函数.这里我们可以通过new运算符创建相应的对象.如

 

var s = new String(’string’);这样得到的是一个字符串对象 ,typeof s 是”object”

 

而如果没有使用new而是var s=String(’string’);得到的是一个基本类型字符串 ,typeof s得到的是”string”

 

 

 

三.原型Prototype


由于Javascript中没有类,那通过什么来实现面向对象中的继承呢,对,就是原型,原型本身也是对象.

每一个对象都有一个隐式的原型(父原型),而函数对象除了隐式的原型引用外,还有一个显式的原型引用。

在一般情况下,对象的隐式原型是不可以访问的,而函数对象的显式原型可以通过 FunctionName.prototype进行访问,

但在Firefox中你可以通过对象的__proto__属性访问对象的隐式原型。

说了这么多,你可以还是对这两种原型没有理解,我们举个例子吧。

Js代码   收藏代码
  1. function Person(name){  
  2. this.name=name;  
  3. }  
  4. alert(Person.prototype);  
  5. alert(Person.prototype.constructor);  
  6. alert(Person.__proto__===Function.prototype);  
  7. alert(Person.constructor);  
  8.    
  9. var p = new Person('Luke');  
  10. alert(p.prototype);  
  11. alert(p.__proto__===Person.prototype);  
  12. alert(p.constructor);  
 

 

运行上面的代码我们可以知道,Person这个函数他的显式原型是一个object对象,而这个原型对象的构造器就是Person自己。

我们又可以知道这个函数的哦隐式原型是内置对象Function的显式原型,且我们可以知道Person的构造器是Function函数。

接着我又创建了一个对象p,可以知道如果直接使用prototype是无法访问的,结果为undefined,因为p是一个普通对象,只能在Firefox中通过__proto__来访问其隐式的原型,可以知道其隐式的原型为Person的显式原型。

我这里就很武断的得出一个结论来,当然不一定正确。

一个创建的对象,如果不主动的修改其隐式的原型(当然我们无法修改),那么默认的隐式原型为其constructor的显式原型。

 

四.原型链

在原型链中Javascript内置的两个初始化函数对象尤为重要,一个就是Function,一个是Object。

 

 

 

 

写道
Function.__proto__===Function.prototype(其值都是一个匿名的空函数 function(){},我们暂称之为f)
f.__proto__为一普通object  f.__proto__.__proto__===Object.prototype
f.prototype 也为一普通object  f.prototype .__proto__===Object.prototype
Object.prototype为原型链的终点   Object.prototype.__proto__ ===null
Object是一个初始化函数对象 Object.__proto__===Function.prototype

 

下面是一个内建对象原型链的大概图示。


 

ECMA262规定了一些既定的规则,没有原因,只是为了实现某种目的且自圆其说。

转载自:http://lukejin.iteye.com/blog/588117

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值