JavaScript学习总结三:js基于原型面向对象

JavaScript原型概念说不好理解其实没那么难,说好理解其实也没那么简单,关键是你有没有找到一个合适自己的理解方法。

预备知识:

我想研究js原型的人肯定对js有一定了解,所以基础的知识不再赘述。但是我还要强调一些变态的知识点:

l JavaScript没有类的概念,是基于原型的面向对象。

l function这个关键字一定要理解正确!这不是传统意义上的定义函数的关键字,而是类!一定要把function理解成类!所以,在function a(){}时,其实你是在创建一个functio的实例,a不是函数,而是对象!这正好符合一句真理:“一切皆对象”。

l new关键字也不是传统的new。后边加的是对象,而不是类。

l JavaScript中没有方法,只有属性。

l .表示访问(获取成员属性),()表示执行。比如fun.x()可以理解为:fun这个对象访问了x属性,并执行这个属性。

概念描述(部分内容来自于网络):

在说原型之前,还要先说点别的知识。上边提到function实际上是在创建对象,这时候它充当了两个角色:创建对象、构造函数。JavaScript就是这么规定的,所有的对象在创建时都要有构造函数。还有需要注意的就是new关键字后边接的全是对象,并不是类,new的功能和传统的语言也不一样,因为JavaScript是基于原型的,没有类,所以new不可能完成传统new的功能,那它做什么了呢?我就简单的说一句:new其实就实现了原型机制(具体怎么做的网上资料有的是)。

究竟什么是原型,下边是来自网络的一段话:

“javascript原型是一个对象。 javascript中所有的构造函数都有一个属性,叫prototype,这个属性存放的就是原型对象;访问这个属性通过:函数名.prototype ,从而可以访问到这个原型对象,也可以为这个原型赋值。在原型对象中有一个属性叫constructor,这个constructor指向函数本身。我们可以访问到原型中的这个属性:函数名.prototype.constructor;我们可以为原型对象添加属性并赋值:函数名.prototype.属性名=值;为函数原型添加的属性,都会成为构造函数的属性,从而成为对象的属性。既然对象具有了原型内的属性,说明对象中的这些属性是从原型中继承来的。所以javascript是基于原型的继承的。”

其实原型就是对象的prototype属性指向的对象。对象通过prototype属性继承了“父类”的特性,甚至包括构造函数在内。证明继承了构造函数的例子:

<script type="text/javascript">
	function fun1(){alert("我爱中国");}//fun1的构造函数
	fun2 = new fun1();//通过fun1创建fun2
	fun3 = new fun2();//我们并没有定义fun2的构造函数,但是成功的创建了fun3,说明构造方法也会继承
	fun3();//输出“我爱中国”
</script>

现在再回过头来看new和function,我们可以通过function和new两种方式创建对象,但两者都要求必须有构造函数,只不过function同时承担了创建对象和构造函数两个职责,而new却要找“父类”的构造函数(系统内部的对象比如Array也有构造函数,这样我们才可以顺利的new,只不过隐藏了)。此时,应该不难理解new实际上是把“父类”作为原型给“子类”的prototype属性。而function是新建,以自己为原型给自己的prototype属性。

这差不多就是JavaScript的原型继承机制了!继续深入,上文提到JavaScript没有方法,只有属性。实际上所有的对象都可以理解为一个属性包,或者说散列数组(key,value),对象只有访问成员的操作。通过“.”指定要访问的属性,通过“()”执行属性(可以理解为方法),JavaScript并不管我们要执行的属性是什么,只负责通过key(属性名)找到相应的value(属性值),所以对象的属性值可以是对象,也可以是数值,是对象的话我们可以用“()”执行,是数值型的话就直接“.”+属性名访问。

原型链:

我们可以自行更改prototype属性,也就是自行设置对象的原型对象。同时,原型继承是链式的。比如,b继承了a,c又继承了b,那么c也继承了a,这样就构成了原型链。原型链的特性是:读的时候从原型链上读,写的时候向自己里面写。大致意思就是:在刚刚abc的例子中,如果在c中访问了一个属性,但是c中没有,会自动去b、a中寻找;但是如果向c中添加属性,那么就直接写在c中。

示例代码:

<script type="text/javascript">
	function fun1(){}//创建fun1对象,原型为自身
	function fun2(){}//创建fun2对象,原型为自身
	fun1.prototype = new Object();//设对象fun1的原型为最底层的系统的Object对象
	fun2.prototype = new fun1();//设对象fun2的原型为fun1
	Object.prototype.a="a";//给对象Object的原型添加一个数值型a属性
	fun = new fun2();//创建一个fun2的对象,继承fun2的所有属性
	alert(fun.a);//调用fun2继承来的a属性,实际上调用的Object原型中的a。打印出“a”
	fun1.prototype.a = "a1";//给fun1的原型(即Object)对象添加一个数值型a属性
	alert(fun.a);//调用fun2继承来的a属性,实际上调用的fun1原型(即Object)中的a。打印出“a1”
</script>

图解:




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值