js采用原型继承来实现类的派生,但是原型链再深入点,我们又知道多少呢,现在不妨往下看:

先来一个原型继承:

var M1 = function() {
this.param = "m1's param";
this.showParam = function() {
alert(this.param);}
this.insideObj = {
"name" : "stefan",
"age" : 15
};
  this.arr = ["arr1", "arr2"];
}; var M2= function() {
this.clone = function() {
return this;
}
}; var m1 =new M1();
M2.prototype = m1;

  好吧,现在M2的原型是m1,也就是说m2继承了m1对象所有共有属性,这样一来,我们的探索开始,第一个测试

1.先尝试改变m2.param属性,输出m2.param,再删除m2.param,再输出m2.param,

m2.param = "m2's param";  //改变m2.param
m2.showParam(); //输出 m2's param
delete m2.param; //删除m2.param
m2.showParam(); //输出 m1's param

一般人会认为因为原型的机制,在子作用域中对原型(即m1)的属性param进行修改,是不可能实现修改的作用的。一旦对m2.param赋值,m2会在它的作用域内(子作用域内)创建一个param属性,并赋值“m2's param”,其中对m2.param作的任何改动都不会影响到原型中的param属性,这就是原型的安全机制体现。 将m2.param删除后,因为m2作用域不含param属性,此时将进入m2的原型链中查找param属性,若原型链中有多个子作用域,并且在该作用域中含有param属性,则将返回最近的子作用域的param属性值,若都没有,将返回m1作用域的param值。比如,

 function M3(){
this.param = "m3's param";
} M3.prototype = m1;
var m3 = new M3();
M2.prototype = m3;
delete m2.param; //删除m2作用域的独立属性param
m2.showParam(); //输出 "m3's param"
delete m3.param; //删除m3作用域的独立属性param
m2.showParam(); //输出 'm1's param'

2.以上的都是对一个基本类型的属性,比如"int ,float,string,boolean"讨论,如果是 “数组(其实数组本身就是对象,只不过特殊一点),一般对象 ”类型的属性呢?会是怎么样的一个结果,现在我们修改以下insideObj这个“对象类型”的属性,重新赋予一个新的对象或者数组,

m2.arr = ["m2 arr1", "m2 arr2"];
delete m2.arr;
alert(m2.arr); //毫无疑问是 ["m2 arr1", "m2 arr2"];
m2.insideObj = {
name : "john",
age : 153
}; delete m2.insideObj;
alert(m2.insideObj.name) //输出是 "stefan"

以上的结果毫无争议可言是吧,原因跟上面所阐述的一样,看看接下来再改动一下arr或者insideObj里面的变量,看下会发生什么事,  

m2.arr[0] = "m2's arr1";
alert(m1.arr[0]); //此时“居然”输出是, “m2's arr1"
delete m2.arr[0]; //数组arr的第一个数组元素
alert(m1.arr); //输出是 ["arr2"],第一个元素不见了
m2.insideObj["name"] = "m2";
alert(m1.insideObj["name"]); //输出是 "m2"

  这个是怎么一回事呢?我们居然直接对原型中的数组arr和内部对象进行了修改,这也说明了一个现象:m2没有在它的独立作用域中创建arr和insideObj这两个属性

现在来理清以下,大家请注意,以上我们并没有对属性的引用进行任何改动    也就是说,我们一直持有的是原型m1的arr和insideObj这两个对象的引用,所谓的“牵一发而动全身”,就是这样啦。而我们之前为什么没有对原型m1的属性造成任何改动,是因为我们都是赋值上了新的引用,再仔细回顾以下:

m2.arr = ["m2 arr1", "m2 arr2"];              

m2.insideObj = {
name : "john",
age : 153
};

 没错,就是这样。非常浅显易懂,这个就不多解释了。

3.在这里,也顺便介绍以下一些对象的原型相关的特性,

(1)hasOwnProperty(propertyname)

它是用于判断某个属性是否原型继承而来,比如

for (var field in m2)
document.write(field);
//当然输出是param,insideObj,arr,showParam,clone //使用hasOwnProperty判断以下
for (var field in m2)
if(m2.hasOwnProperty(field))
document.write(field);
//只会输出clone,因为这是在m2内部定义的,而其他的属性都是从m1继承来的

(2)isPrototypeOf(obj)

它是用于判断该对象是否是obj对象的原型,像

if(m1.isPrototype(m2))
alert("true");
//m1是m2的原型,当时是true啦

  

ok,小弟不才,对原型就只研究到这地步,再深入点就要花时间去慢慢琢磨探究啦。有什么错误,欢迎指出

js原型继承深入的更多相关文章

  1. 【09-23】js原型继承学习笔记

    js原型继承学习笔记 function funcA(){ this.a="prototype a"; } var b=new funcA(); b.a="object a ...

  2. JS原型继承与类的继承

    我们先看JS类的继承 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...

  3. js原型继承四步曲及原型继承图

    一:js原型继承四步曲 //js模拟类的创建以及继承 //动物(Animal),有头这个属性,eat方法 //名字这个属性 //猫有名字属性,继承Animal,抓老鼠方法 //第一步:创建父类 fun ...

  4. JS原型继承和类式继承

    前言 一个多月前,卤煮读了一篇翻译过来的外国人写的技术博客.此君在博客中将js中的类(构造)继承和原型继承做了一些比较,并且得出了结论:建议诸位在开发是用原型继承.文中提到了各种原型继承的优点,详细的 ...

  5. 关于js原型继承

    js的每个类都有一个prototype对象 访问对象的属性时,会先访问到对象自身是否有定义这个属性 如果没有定义,就会去访问对象所属类型的prototype对象是否有此属性 原型继承就是把类型的pro ...

  6. js原型继承

    原型链: Object(构造函数) object(类型(对象)) var o = {}; alert(typeof o); //结果是object alert(typeof Object); //结果 ...

  7. 前端面试题总结二(js原型继承)

    今天这篇文章整理了JS原型和继承的一些知识点,面试的时候  基!本!都!会!问!还不快认真阅读下文,看看你还有哪些知识点需要掌握吧~ 1.原型链 基本思想:利用原型让一个引用类型继承另外一个引用类型的 ...

  8. JS 原型继承的几种方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. JS 原型 & 继承

    理解原型链 先看看http://www.ituring.com.cn/article/56184和http://www.cavabiao.com/prototype-and-inherit-of-ja ...

随机推荐

  1. 经典C面试题

    12个有趣的C语言面试题 面试题C 摘要:12个C语言面试题,涉及指针.进程.运算.结构体.函数.内存,看看你能做出几个! 1.gets()函数 问:请找出以下代码里的问题: #include< ...

  2. lvs keepalived 安装配置详解【转】

    lvs keepalived 安装配置详解 张映 发表于 2012-06-20 分类目录: 服务器相关 前段时间看了一篇文章,lvs做负载均衡根F5差不多,说实话不怎么相信,因为F5没玩过,也无法比较 ...

  3. [ES6] Converting an array-like object into an Array with Array.from()

    Array.from() lets you convert an "iterable" object (AKA an array-like object) to an array. ...

  4. VS2010 使用TeeChart画图控件 - 之二 - 绘制图形(折线图,柱状图)

    1.前期准备 详细可见VS2010 使用TeeChart画图控件 - 之中的一个 控件和类的导入 1. 1 加入TeeChart控件,给控件加入变量m_TeeChart 加入TeeChart控件,右击 ...

  5. Tinyxml 操作XML

    对于xml文件,目前的工作只是集中在配置文件和作为简单的信息文件来用,因此我不太喜欢使用msxml这种重量级的xml解析器,特别是使用msxml解析xml涉及到复杂的com类型转换,更是令人感觉繁琐. ...

  6. struts2,hibernate,spring整合笔记(1)

    今天终于配置好了ssh框架的整合,记录下过程供参考 环境:window8.1,jdk1.7 ,带有javaee的eclipse,也就是说要能发布web项目,TOMCAT服务器,tomcat配置涉及到环 ...

  7. Eclipse、MyEclipse使用git插件(egit)

    在开发Java.JavaEE等相关程序时,我们会用到Eclipse或者MyEclipse,同时使用到git作为版本控制软件,所以我们需要在这些IDE上集成git插件,而egit正是Eclipse基金会 ...

  8. 第三章:真正弄清楚一个Mod的组织结构

    <基于1.8 Forge的Minecraft mod制作经验分享> 首先看看一个mod的文件结构,懂Java的应该都看得懂: src/main/ --java/com.xxxxxxxx.x ...

  9. Html.RenderAction简单用法

    一 Html.ActionLink("actionName") 调用页与当前页位于同一个控制器,可直接调用,显示对应的视图 二 Html.ActionLink("acti ...

  10. ZOJ3161

    朴素动态规划 ZOJ3161 题意:(严重标题党)老板不想让客人走,客人不想留,客人按顺序排好,老板抽8g(书上翻译成八卦,神翻译),抽到的 如果相邻,其中一个人由客人决定离开,求最后黑心的老板最多能 ...