写到这篇,我的js系列也快接近尾声了,所以这个系列不会遗留js来实现面向对象的核心——原型,有些人说原型不好理解,其实嘛,要想系统

的理解原型,最便捷的方式就是看看经典的书,少看些博客,博客这东西只是博主自己的个人理解,充其量是些配味的佐料。

 

一:继承

如果你熟悉C#的话,你肯定会知道,所有的类都是继承于Object的,这样我就拥有Object所具有的功能了,如下图中我定义的Person类。

从图中可以看到,在C#中到处都是继承,下一步我要做的就是自定义继承,如下图中我定义的Student类,让它继承Person.Name属性。

这些对于玩C#的人来说都是很司通见惯的,那么下一个问题来了,这些真正的面向对象的东西,在js中该怎么玩呢?当然就要用到大名鼎鼎的

prototype属性了。

二:用JS来模仿C#的继承

1.默认继承Object

 我们都知道在js中的所有引用类型也同样继承于Object,这样也就具有Object的功能了,但是你有没有考虑过,比如下图中的Person到底是怎么继承

了Object的所有属性和方法呢?

看到上图后,你是不是很好奇呢?其实原理真的很简单,用chorme的watch expressions一看你就一清二楚了。

第一眼看到不知道你会不会眼晕?听我慢慢解释,从上面的图中不难看到,其实有这么个原型链的关系:

p.__proto__ =Person.prototype

Person.prototype.__proto__ -> new Object()

不知道你看懂了没?其实这里最重要的就是__proto__属性,首先你要知道,每个实例都具有这么个__proto__属性,因为这是核心,比如你要找

p.toString()方法, js引擎会优先在Person function中找toString()方法,发现没有。。。花擦。。。没辙只能通过p.__proto__属性继续往上

查找,到了Person.prototype,从图中可以看到prototype是一个具有constructor属性的对象,因为只有一个属性,所以也没找到tostirng()方法,

然后沿着Person.prototype._proto__找到了Object,在这里我们就找到了toString()方法。

2.自定义继承

我们知道prototype是个非常重要的属性,为了模仿C#中Student类继承于Person类,这次我需要做的是让Studnet.prototype=new Person()就好了。

从图中可以看到student实例已经含有Name属性了,我们现在已经知道有一个原型链查找的过程,比如我现在通过student.__proto__找到了new Person(),

然后也看到了new Person()具有Name属性,我想你现在也知道,在Person函数中也有一个__proto__属性,它是指向Object的,如果说我在new Person()

中没有找到,那么会继续通过Person.__proto__(Student.prototype.proto__)继续往上找,一直找到顶端为止。

三:详解prototype

1. prototype到底是什么?

从上一章中我想你对prototype应该有了宏观了解,可以看到其实prototype只不过是一个包含constructor属性的Object对象,其中constructor属性是指

向当前function的一个指针,代码还原如下:

 <script type="text/javascript">
function Person() {
this.Name = "ctrip";
} Person.prototype = {
constructor: Person //指向Person的constructor
}; var p = new Person();
</script>

2. prototype上面的属性可以被所有实例共享。

  这个之所以能够共享,是因为每个实例都有__proto__属性,包括function的prototype属性也是有__proto__属性的,这是因为prototype本质上

也是一个对象的实例,所以js在查找某个属性是否存在的时候会通过__proto__属性一直追踪到object。

3. 如果function中的属性与prototype属性冲突了怎么办?

看到答案后,我想你也非常清楚了,毕竟你已经理解了原型链的查找,因为js引擎查找过程是先从本函数查找,如果找到就return,找不到继续通过

__proto__往上找,很好理解的。

Javascript之旅——第十一站:原型也不好理解?的更多相关文章

  1. Javascript之旅——第十站:为什么都说闭包难理解呢?

    研究过js的朋友大多会说,理解了js的原型和闭包就可以了,然后又说这些都是js的高级内容,然后就又扯到了各种神马的作用域...然后不少 人就会被忽悠的云里雾里...下面我也试着来说说闭包,看我说的这个 ...

  2. Javascript之旅——第八站:说说instanceof踩了一个坑

    前些天写js遇到了一个instanceof的坑,我们的页面中有一个iframe,我在index页面中计算得到了一个array,然后需要传递到Flight页面 这个嵌套的iframe中的一个函数(Sea ...

  3. Javascript之旅——第七站:说说js的调试

    最近比较吐槽,大家都知道,现在web前端相对几年前来说已经变得很重了,各种js框架,各种面对对象,而且项目多了,就会提取公共模块, 这些模块的UI展示都一样,不一样的就是后台逻辑,举个例子吧,我们做企 ...

  4. Javascript之旅——第五站:说说那些所谓的包装类型

    最近不看犀牛书了,那本翻译的特烂而且好拗口,尤其是原型那块说的乱七八糟,后来经同事介绍,买了本js高级程序设计,然后就继续 苦逼的看,不吐槽了,继续说说js中有新鲜感的包装类型. 一:String 说 ...

  5. Javascript之旅——第四站:parseInt中要注意的坑

    前些天信用卡站点要接入一个新功能,不过还真比较坑爹,asp站点,大家都知道信用卡的背面是有一个有效期的,在对接银行中这个信息 一定是要传给银行做数据校验,用户在语音输入信用卡有效期后,系统会做一个有效 ...

  6. Sql Server之旅——第十一站 简单说说sqlserver的执行计划

    我们知道sql在底层的执行给我们上层人员开了一个窗口,那就是执行计划,有了执行计划之后,我们就清楚了那些烂sql是怎么执行的,这样 就可以方便的找到sql的缺陷和优化点. 一:执行计划生成过程 说到执 ...

  7. Javascript之旅——第六站:看看writable特性

    说起js中的那些特性标记,总觉得有些怪怪的,那为什么要说到这个attribute,起源于对一个问题的疑问,我们都知道window对象其实就是 浏览器窗口的一个实例,既然是一个实例,那这个实例就应该有“ ...

  8. Javascript之旅——第三站:几个需要注意的运算符

    平时写惯了C#,所以会觉得什么样的运算符就应该做什么样的运算,但是有一天你的习惯被其他语言颠覆了,不知道是不是有一股强大的好奇 心,刚好在js中,我的这种习惯就被颠覆了,下面就看看哪些运算符颠覆了我的 ...

  9. 对JavaScript中的静态属性和原型属性的理解

    首先是在访问上的区别,当访问实例对象的某个属性但它本身没有时,它就会到原型中去查找,但不会去查找静态属性. // 实例对象不会去查找静态属性 function Foo(){} Foo.a = 1; v ...

随机推荐

  1. C# IDisposable接口

    public class MyClass : IDisposable { public int a; public MyClass() { //构造 } public void Dispose() { ...

  2. TabHost的使用

    Android中的选项卡是用TabHost实现的. 首先,定义TabHost的布局文件: <?xml version="1.0" encoding="utf-8&q ...

  3. 【Linux_Fedora_应用系列】_1_如何安装音乐播放器和mp3解码

    因为安装环境的不同,Fedora在安装后会安装不同的软件包.通常在安装的时候有多种选择: 1.桌面环境: 适合个人日常使用,安装包含办公软件(Fedora 默认安装Open Office).娱乐影音软 ...

  4. 三层架构与MVC之间的区别

    文章转发自:http://www.admin10000.com/document/535.html 我们平时总是将三层架构与MVC混为一谈,殊不知它俩并不是一个概念.下面我来为大家揭晓我所知道的一些真 ...

  5. python 函数小实例

    1.判断一个数字是否为素数: import math # -----------------判断一个数是否是素数------------------ def sushu(a): i=1 for i i ...

  6. 三星s4刷机教程(卡刷)

    ···············使用到的工具···················手机助手(--推荐91助手).root精灵.Odin3 v3.07.recovery包.rom包 1.首先在电脑上安装9 ...

  7. maven 跳过测试 打包 及上传命令

    [main] ERROR org.apache.maven.cli.MavenCli - Failed to execute goal org.apache.maven.plugins:maven-s ...

  8. get()和post()方法编码的区别

    在做ssh搭建的框架中,在后台条件查询的时候,组合查询传到后台的值一直是乱码,其中在form表单中必须要加上method,这一点是肯定的,但是加上了提交的方式之后,会出现如下问题: 如果使用get方法 ...

  9. js的动态加载、缓存、更新以及复用(四)

    本来想一气呵成,把加载的过程都写了,但是卡着呢,所以只好在分成两份了. 1.页面里使用<script>来加载 boot.js . 2.然后在boot.js里面动态加载 bootLoad.j ...

  10. jQuery Pjax – 页面无刷新加载,优化用户体验

    pjax 是 HTML5 pushState 以及 Ajax 两项技术的简称,综合这两个技术可以实现在不刷新页面的情况下载入 HTML 到当前网页,带给你超快速的浏览器体验,而且有固定链接.标题以及后 ...