Javascript 原型继承(续)—从函数到构造器的角色转换
对于每一个声明的函数,里边都会带有一个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 原型继承(续)—从函数到构造器的角色转换的更多相关文章
- 再谈javascript原型继承
Javascript原型继承是一个被说烂掉了的话题,但是自己对于这个问题一直没有彻底理解,今天花了点时间又看了一遍<Javascript模式>中关于原型实现继承的几种方法,下面来一一说明下 ...
- 彻底理解Javascript原型继承
彻底理解Javascript原型继承 之前写过一篇Javascript继承主题的文章,这篇文章作为一篇读书笔记,分析的不够深入. 本文试图进一步思考,争取彻底理解Javascript继承原理 实例成员 ...
- [转]Javascript原型继承
真正意义上来说Javascript并不是一门面向对象的语言,没有提供传统的继承方式,但是它提供了一种原型继承的方式,利用自身提供的原型属性来实现继承.Javascript原型继承是一个被说烂掉了的话题 ...
- JavaScript原型继承工作原理
原型继承的定义 当你阅读关于JS原型继承的解释时,你时常会看到以下这段文字: 当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止.——出自JavaScript秘 ...
- 【读书笔记】读《编写高质量代码—Web前端开发修炼之道》 - JavaScript原型继承与面向对象
JavaScript是基于原型的语言,通过new实例化出来的对象,其属性和行为来自于两部分,一部分来自于构造函数,另一部分是来自于原型.构造函数中定义的属性和行为的优先级比原型中定义的属性和优先级高, ...
- 浅析Javascript原型继承(转)
引自: http://blog.csdn.net/kittyjie/article/details/4380918 原作者解释的浅显易懂,非常不错的JavaScript prototype总结 JS没 ...
- JavaScript 原型继承开端
1.原型继承本质 就javascript对象系统的实现来讲,对象并没有原型,而构造器有原型(构造器.prototype指向其原型).对象只有构造自某个原型的说法,并没有持有某个原型的说法. ...
- Javascript原型继承容易忽略的错误
编写Javascript的开发者都知道,JS虽然没有类(ES6添加了class语法),但是可以模拟出OOP语言的类和面向对象的概念,比如我们都知道的一句话,Javascript中处处是对象,而面向对象 ...
- javascript原型继承
在传统的基于Class的语言如Java.C++中,继承的本质是扩展一个已有的Class,并生成新的Subclass. 由于这类语言严格区分类和实例,继承实际上是类型的扩展.但是,JavaScript由 ...
随机推荐
- asp.net实现文件解压和压缩
C#解压RAR压缩文件(--转载--测试通过) using System; using System.Collections.Generic; using System.Text; using Sys ...
- 漫谈 polling 和 Websocket
Http被设计成了一个单向的通信的协议,即客户端发起一个request,然后服务器回应一个response.这让服务器很为恼火:我特么才是老大,我居然不能给小弟发消息... 轮询 老大发火了,小弟们自 ...
- BZOJ 3573 米特运输
语文题... 原来除了hash还可以取对数啊orz #include<iostream> #include<cstdio> #include<cstring> #i ...
- android开发调用c++共享库so文件
1.编写libaab.cpp #include <stdio.h>#include <stdlib.h> #ifdef __cplusplusextern "C&qu ...
- CSS的伪元素(二)
随便聊聊CSS的伪元素,虽然它们在项目开发中用的并不多,但确实很有用,在项目中不用它,是因为大家不能了解它们,下面是一个工作场景,如有四个按钮,分别是建立,编辑,删除和修改,而我们要求这在前台显示的汉 ...
- java 中的Exception RuntimeException 区别
在java的异常类体系中: 1.Error和RuntimeException是非检查型异常,其他的都是检查型异常; 2.所有方法都可以在不声明throws的情况下抛出RuntimeException及 ...
- mysql 自旋锁
自旋(spin)是一种通过不间断地测试来查看一个资源是否变为可用状态的等待操作,用于仅需要等待很短的时间等待所需资源的场景.使用自旋这种“空闲循环(busy-loop)”来完成资源等待的方式要比通过上 ...
- 【Android】以BaseAdapter做适配器的ListView及其性能优化
适配器的Java类 package com.app.adapter; import org.json.JSONArray; import org.json.JSONObject; import and ...
- visio 改变画布大小
按住键盘Ctrl键,将鼠标箭头移动到画布边界处就可以自由拖动画布大小了.
- Delphi 操作word 表格
var wordApp, WordDoc, WrdSelection, wrdtable: variant; strAdd: string; wdPar,wdRange:OleVariant; iCo ...