对于每一个声明的函数,里边都会带有一个prototype成员,prototype会指向一个对象,现在我们来聚焦prototype指向的这个对象,首先我们会认为,这个对象是一个该函数对应的一个实例对象,因为我们在new一个对象的时候,通常都会继承该原型prototype对象的属性和方法。比如:

 <html>
<head>
<meta http-equiv="content-type" charset="utf-8"/>
<script type="text/javascript">
function person()
{
this.name = "istone";
this.age = 10;
this.address = "shenzhen";
}
var tt = new person();
alert("name : "+tt.name+"\nage : "+tt.age+"\naddress : " +tt.address);
</script>
</head>
<body>
</body>
</html>

由以上代码我们发现由于原型对象继承机制的存在,对象tt在创建后便拥有的原型对象的相关属性,在这里是否我们可以认为原型对象是一个拥有某些属性和方法的一个对象,若是这样,我们每声明一个函数,其prototype成员对象一开始便拥有了一些属性和方法。显然这是不经济的。所以我们可以这样认为,当我们在声明一个函数时,其prototype对象是一个空的对象。但为什么我们在用new操作符创建一个新对象后(比如tt)便已经拥有了一些属性和方法呢,这不是明显与空对象的概念相矛盾麽?下面我们来解决这个问题,先看如下代码:

 var _proto = null;
function GetPrototype()
{
if(!_proto)
{
_proto = new Object();
_proto.constructor = this;//构造函数
}
return _proto;
}

以上代码是推断出来的prototype的可能实现逻辑,函数原型在一开始便是一个内置的Object构造器的实例,并且constructor属性被赋值为当前函数,此时的函数就充当了构造器的作用了。当函数的prototype有意义后,就从普通函数摇身变成了构造器。这时当用户用new产生实例,只要该实例的原型链接向这个prototype属性就可以了。

附:Jquery对象的构建分析

step 1:一般我们都建对象的方式就是采用new运算符来实现。

  function iQuery()
{ this.name = "istone";
this.age = function(){
alert("I'm 10 years old!");
};
}
var IStone = new iQuery();
IStone.age();

step 2:显然Jquery不是这么玩的,它并没有想step 1一样用new来构建对象,而是直接调用函数。比如:

$().ready(obj);

$().isFunction(obj);

要达到这样的效果我们必须在调用’$()’的时候得到一个实例对象。

function iQuery()

{

return new iQuery();

}

iQuery.prototype.name= "istone";

iQuery.prototype.age = function()

{

alert("I'm 10 years old!");

};

很明显这样会有一个问题,就是死循环了。

step 3:为了解决这个问题,Jquery将实例对象的获得转移到了prototype中。

 function iQuery()
{
return iQuery.prototype.init();
}
iQuery.prototype={
init:function()
{
return this;
},
name: "istone",
age : function()
{
alert("I'm 10 years old!"); }
}

在这里返回this关键字是极其关键的一步,此时的this上下文为init.prototype,代表着init函数的原型。因此这样还是达不到效果。但Jquery通过巧妙的将init的原型替换为Jquery的原型,此时瞬间就解决了这个问题。此时this上下文就转为了Jquery的原型了。

iQuery.prototype.init.prototype = iQuery.prototype;

PS:下面是JQuery对象构建的部分源码,通过上面的分析,咱们就能清楚地了解这一构建过程。

 jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
}, jQuery.fn = jQuery.prototype = {
init: function( selector, context, rootjQuery ) { return this;
}
}
jQuery.fn.init.prototype = jQuery.fn;

Javascript 原型继承(续)—从函数到构造器的角色转换的更多相关文章

  1. 再谈javascript原型继承

    Javascript原型继承是一个被说烂掉了的话题,但是自己对于这个问题一直没有彻底理解,今天花了点时间又看了一遍<Javascript模式>中关于原型实现继承的几种方法,下面来一一说明下 ...

  2. 彻底理解Javascript原型继承

    彻底理解Javascript原型继承 之前写过一篇Javascript继承主题的文章,这篇文章作为一篇读书笔记,分析的不够深入. 本文试图进一步思考,争取彻底理解Javascript继承原理 实例成员 ...

  3. [转]Javascript原型继承

    真正意义上来说Javascript并不是一门面向对象的语言,没有提供传统的继承方式,但是它提供了一种原型继承的方式,利用自身提供的原型属性来实现继承.Javascript原型继承是一个被说烂掉了的话题 ...

  4. JavaScript原型继承工作原理

    原型继承的定义 当你阅读关于JS原型继承的解释时,你时常会看到以下这段文字: 当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止.——出自JavaScript秘 ...

  5. 【读书笔记】读《编写高质量代码—Web前端开发修炼之道》 - JavaScript原型继承与面向对象

    JavaScript是基于原型的语言,通过new实例化出来的对象,其属性和行为来自于两部分,一部分来自于构造函数,另一部分是来自于原型.构造函数中定义的属性和行为的优先级比原型中定义的属性和优先级高, ...

  6. 浅析Javascript原型继承(转)

    引自: http://blog.csdn.net/kittyjie/article/details/4380918 原作者解释的浅显易懂,非常不错的JavaScript prototype总结 JS没 ...

  7. JavaScript 原型继承开端

    1.原型继承本质       就javascript对象系统的实现来讲,对象并没有原型,而构造器有原型(构造器.prototype指向其原型).对象只有构造自某个原型的说法,并没有持有某个原型的说法. ...

  8. Javascript原型继承容易忽略的错误

    编写Javascript的开发者都知道,JS虽然没有类(ES6添加了class语法),但是可以模拟出OOP语言的类和面向对象的概念,比如我们都知道的一句话,Javascript中处处是对象,而面向对象 ...

  9. javascript原型继承

    在传统的基于Class的语言如Java.C++中,继承的本质是扩展一个已有的Class,并生成新的Subclass. 由于这类语言严格区分类和实例,继承实际上是类型的扩展.但是,JavaScript由 ...

随机推荐

  1. ORACLE之手动注册监听listener。alter system set local_listener="XXX"

    记录下刚刚做的一个为一个数据库(t02)配置多个监听(listener)的实验,过程有点小曲折. (1)新增两个测试的监听,listener.ora的配置内容(可纯手动编辑该文件或使用netca)如下 ...

  2. 安装服务Memcached+Nginx+Php linux下安装

    Memcached安装 1.      源码安装libevent(下载地址:http://monkey.org/~provos/libevent/) 2.      源码安装memcached(下载地 ...

  3. SpringMVC——实现拦截器

    1. SpringMVC拦截器的概念与Struts2相同 2. 实现拦截器 (1) 项目结构 (2) 实现HandlerInterceptor接口 package com.zhengbin.contr ...

  4. Jquery插件写法及extentd函数

    JQuery插件写法 JQuery插件又分为类扩展方法和对象扩展方法两种,类插件是定义在JQuery命令空间的全局函数,直接通过可调用,如可调用,如可调用,如.ajax():对象插件是扩展JQuery ...

  5. HDU 5430 Reflect

    题意:问在一个圆形的镜面里,从任意一点发出一个光源,经n次反射回到起点的情况数是多少. 解法:直接贴题解吧…… 求1至N+1中与N+1互质的个数,即欧拉函数. 代码: #include<stdi ...

  6. POJ 2549 Sumsets

    Sumsets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10593   Accepted: 2890 Descript ...

  7. kettle连接hadoop&hdfs图文详解

    1 引言: 项目最近要引入大数据技术,使用其处理加工日上网话单数据,需要kettle把源系统的文本数据load到hadoop环境中 2 准备工作: 1 首先 要了解支持hadoop的Kettle版本情 ...

  8. TOAD FOR MYSQL 进行数据插入时乱码的解决办法---MariaDB 5.5

    最近使用mysql是发现插入的数据乱码,几经周折终于找到的解决方法,特作备忘. 开始有将mysql的字符集全部设置成utf8,如下: SHOW VARIABLES LIKE 'character_se ...

  9. ASIHttpRequest 使用过程中,中文编码的问题

    遇到过几个中文编码的情况,不知道是服务器原因还是本身方法上有区别 ,今天遇到的问题是使用1的方法行不通,但是使用2的方法就可以. 1. NSString *urlString= [NSString s ...

  10. Android FragmentActivity+viewpager的使用

    使用场景,打算设计一个“底部菜单栏+其余可滑动的页面”的简单的功能. package com.lanyuweng.mibaby; import android.content.Intent; impo ...