对于每一个声明的函数,里边都会带有一个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. buildroot linux filesystem 初探

    /****************************************************************************** * buildroot linux fi ...

  2. Android Configuration change引发的问题及解决方法(转)

    之前在学习Fragment和总结Android异步操作的时候会在很多blog中看到对Configuration Change的讨论,以前做的项目都是固定竖屏的,所以对横竖屏切换以及横竖屏切换对程序有什 ...

  3. 学习PHP C扩展之面向对象开发方式 (转)

    PHP OOP面向对象之C语言开发方式 学习PHP C扩展有一段时间了,PHP手册里大部分讲的PHP的函数开发方式,网上找OOP资料比较少,想起上个月测试redis 的时候,下载PHP扩展redis源 ...

  4. windows下MySql没有setup.exe时的安装方法

    01.把 mysql-advanced-5.6.17-winx64.zip 解压到自定义 D:\mysql-5.6.17-W64 或 D:\mysql-advanced-5.6.17-winx64 目 ...

  5. javaScript的函数(Function)对象的声明(@包括函数声明和函数表达式)

    写作缘由: 平时再用js写函数的时候,一般都是以惯例 function fn () {} 的方式来声明一个函数,在阅读一些优秀插件的时候又不免见到 var fn = function () {} 这种 ...

  6. HDU 5407 CRB and Candies

    题意:给一个正整数k,求lcm((k, 0), (k, 1), ..., (k, k)) 解法:在oeis上查了这个序列,得知答案即为lcm(1, 2, ..., k + 1) / (k + 1),而 ...

  7. C#中嵌入互操作类型的含义

    首先说一下它的含义: 1. ”嵌入互操作类型”中的嵌入就是引进.导入的意思,类似于c#中using,c中include的作用,目的是告诉编译器是否要把互操作类型引入. 2. “互操作类型”实际是指一系 ...

  8. IOS 弹出式 POPMenuView

    //MenuView.h   // //  MenuView.h //  RockPopMenu // //  Created by zhuang chaoxiao on 14-6-26. //  C ...

  9. CSS、CSS2和CSS3选择器总结(全部选择器种类及其优先级)

    选择器种类罗列: 1.基础的选择器 选择器 含义 示例 * 通用元素选择器,匹配任何元素 * { margin:0; padding:0; } E 标签选择器,匹配所有使用E标签的元素 p { fon ...

  10. OpenGL超级宝典第5版&&GLSL法线变换

    在GLSL中,有一些情况需要把局部坐标系下的向量或点转换到视点坐标系下,如光照计算时,需要把法向转化到视点坐标系.如果是模型上一点p 转化到视点坐标系下,直接(model-view matrix )* ...