`
ljzforever
  • 浏览: 114775 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

javascript原型继承学习笔记

阅读更多

在谈Js之前,首先需要明确几个概念:

1.某一对象的原型仍是一个对象.

2.js原型继承的实质是复制,但也不是完全复制,而是子对象更改了什么数据,就复制什么数据.具体做法为创建一张成员维护表.如:

function Parent(b)
{
    this.a = "a";
    this.b = b==null ? "b" : b;
};
function Child(b)
{
    Parent.call(this,b);
};
Child.prototype = new Parent();
var c = new Child();
alert(c.b)

 

 

3.当需要查找某个属性时,首先读对象实例自己维护的表.如果没有找到指定的成员,就要遍历整个原型链,直到原型为空的对象({}),或者到找到该成员为止。
4.每个函数都有一个prototype属性指向其原型对象,默认为{},即空对象.
5.每个对象都有一个constructor属性,默认指向本对象的构造函数(这句话没有讲完,请接看往下看)
6.Objcet对象的prototype属性是空对象{},空对象的constructor属性指向Object函数构造,所以所有对象的总原型都是Object(参见第4条)
7.对于new操作符,比如:
 
function Parent(b)
{
    this.a = "a";
    this.b = b==null ? "b" : b;
};
 
对于:
var p = new Person("c");
其实可以写成这样:
var p = {};
Person.call(p,"c");
 这就很明白了,其实首先是创建了一个空对象,然后将这个对象以this参数传入构造函数Person,于是Person对象就new出来了.
 
好了,下面来说正题.上图:
 
其实这是别人画的一张图,画的很好,我就拿来主义了,呵呵.代码如下:

 

function MyObject() 
{ 
    this.constructor = arguments.callee; //正确维护constructor,以便回溯外部原型链 
} 
MyObject.prototype = new Object(); //人为构建外部原型链 
function MyObjectEx() 
{ 
    this.constructor = arguments.callee; //正确维护constructor,以便回溯外部原型链 
} 
MyObjectEx.prototype = new MyObject(); //人为构建外部原型链 
obj1 = new MyObjectEx(); 
obj2 = new MyObjectEx(); 
alert(obj1.constructor === MyObjectEx); //true 
alert(MyObjectEx.prototype instanceof MyObject); //true 
alert(MyObjectEx.prototype.constructor === MyObject); //true 
alert(MyObject.prototype instanceof Object); //true 
alert(MyObject.prototype.constructor === Object); //true 
alert(obj1.constructor.prototype.constructor.prototype.constructor === Object); //true,完成了所有的回溯

 

 学习JS的原型继承,最重要的就是搞清楚JS的原型链.

所谓原型链,就是一条记录了JS对象继承过程的链表,而其组成部分就是每个对象的constructor属性与函数的prototype属性.通过对象的constructor属性可以找到本对象的构造构数,通过构造构数prototype属性又可以找到其上一级的对象.就这样一级一级的回溯,直到Object.
还有一条隐藏的原型链,通过.proto属性维护,不过这是系统自行维护的,不需要人为参与,也不可见,虽然firefox浏览可以访问,但还是不推荐.
看似简单,但是陷阱很多,如下:
function Parent(){};
function Child(){};
Child.prototype = new Parent();
var p = new Parent();
var c = new Child();
alert(p.constructor == c.constructor)   //true
 p与c明明一个是基对象,一个是子对象,怎么会p.constructor == c.constructor呢?
当你alert(p.constructor),显示的是Person(),但当你alert(c.constructor)时,打印的还是Person(),这就奇怪了,c的constructor不是Child()吗?
原因就是第三行代码:
Child.prototype = new Parent();
 文章开始时的第5条说过:每个对象都有一个constructor属性,默认指向本对象的构造函数,其实这句话没有说完:每个对象的prototype对象的constructor属性默认也指向本构造函数,但是,当你改变了其prototype所指对象后,情况就有点不同了,如上例,当指向Parent后,原型对象的constructor会指向Person,这是对的,然而,由于原型继承的本质是复制,会把这个属性值复制过来,会改变本对象的constructor属性,让其也指向Person.
 
但是,如果代码这样写,结果就不同了:
function Parent(){};
function Child(){};
var p = new Parent();
var c = new Child();
Child.prototype = new Parent();
alert(p.constructor == c.constructor)   //false
我把它从第三行放到第五行.结果就是false了,原因是我先new对象,再更改原型.其实在对象被new出来之后,就与构造函数无关了,更改构造函数不会影响到已new出来的对象.
但是这样写的很少,因为这不符合面向对象的原则.回到刚才的话题,怎么才能在先设置原型再new对象的情况下让原型链记录正确呢?答案就是重新设置子对象的constructor属性:
function Parent(){};
function Child()
{
    this.constructor = arguments.callee
};
Child.prototype = new Parent();
var p = new Parent();
var c = new Child();
 通过这样的设置,就能达到那张图里所描绘的一条完整的原型链了.


参考的文章:
Javascript对象真经
悟透JavaScript
《悟透JavaScript》之 甘露模型(新)
分享到:
评论

相关推荐

    javascript学习笔记.docx

    f) 继承:只是在查询一个属性时自动发生,而不会在写属性时发生,就是说单写一个父类的属性时,JavaScript环境会为对象本身创建一个同名的属性,从此该属性就覆盖了父类中的属性。 12) 创建一个数组可用 new Array()...

    关于JavaScript继承的学习笔记

    ①了解js继承方法之前要了解js的原型和原型链,可以参考关于JavaScript原型的学习笔记 ②call和apply方法的运用 function Person(name,age) { this.name = name; this.age = age; } function Pp(name,age,sex) ...

    javascript原型链学习记录之继承实现方式分析

    本文实例讲述了javascript原型链学习记录之继承实现方式。分享给大家供大家参考,具体如下: 在慕课网学习继承的笔记: 继承的几种方式: ① 使用构造函数实现继承 function Parent(){ this.name = 'parent'; } ...

    JavaScript-学习笔记.docx

    自己学习笔记。视频:腾讯课堂:渡一教育 内容大纲: 预编译: 函数 闭包问题 对象 原型、原型链、call、apply 继承模式 对象克隆 数组 类数组 数组去重 自定义type方法(类似于typeof) try-catch es5.0严格模式 ...

    JavaScript继承学习笔记【新手必看】

    JavaScript作为一个面向对象语言(JS是基于对象的),可以实现继承是必不可少的,但是由于本身并没有类的概念,所以不会像真正的面向对象编程语言通过类实现继承,但可以通过其他方法实现继承。实现继承的方法很多,...

    javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式

    而原型正是实现javascript继承的很重要的一种方法! 我们首先来看以下代码: 代码如下: function person(name, age) { this.name = name; this.age = age; } person.prototype.getInfo = function() { alert(...

    JS学习笔记之原型链和利用原型实现继承详解

    主要介绍了JS学习笔记之原型链和利用原型实现继承,结合实例形式详细分析了javascript原型链以及利用原型实现继承的相关操作技巧与注意事项,需要的朋友可以参考下

    JavaScript函数、闭包、原型、面向对象学习笔记

    给大家分享了一篇关于JavaScript函数、闭包、原型、面向对象的知识点学习笔记内容,有兴趣的朋友参考下。

    《javascript设计模式》学习笔记二:Javascript面向对象程序设计继承用法分析

    本文实例讲述了Javascript面向对象程序设计继承用法。...原型继承 c.原型赋值(遍历)继承(寄生式继承) 2.构造函数继承 所谓的构造函数继承,就是通过创建一个新对象,调用父类构造函数实现的一种继承

    Javascript 读书笔记索引贴

    一. 基础篇 Javascript学习笔记1 数据类型 Javascript学习笔记2 函数 Javascript学习笔记3 作用域 Javascript学习笔记4 Eval函数 ... 实战篇Javascript学习笔记8 用JSON做原型 Javascript学习笔记9 prototype封装继承

    Javascript 学习笔记之 对象篇(二) : 原型对象

    Javascript 并没有类继承模型,而是使用原型对象 prototype 进行原型式继承。尽管人们经常将此看做是 Javascript 的一个缺点,然而事实上,原型式继承比传统的类继承模型要更加强大。举个例子,在原型式继承顶端构建...

    player-prototypes:JavaScript原型简介

    通过理解,以其他面向对象的语言学习“类” 使用“继承”概念设计模块目标听众: 初学者学习javascript或具有另一种面向对象语言的经验的开发人员,学习javascript并习惯于使用“类”来实现继承希望将一些javascript...

    Ruffy javascript 学习笔记

    1,javascript的原型模型:prototype 在实现面向对象,(像是定义一个类的时候)需要一个构造函数来定义对象的成员,而方法去依附在该构造函数的原型上. 2,javascript中,为了实现继承,必须将子类构造函数的...

    作为前端,你需要懂得javascript实现继承的方法

    现在我们可以利用ES6的extends方法实现继承,如果想了解更多有关ES6实现的继承请查看《ES6学习笔记(二):教你玩转类的继承和类的对象》,在这里不再做更多的介绍。 文章目录1. call()2. 借用构造函数继承父类型...

    javascript学习笔记(十) js对象 继承

    1.原型链 //很少单独使用 代码如下: View Code //定义 SuperClass类,有一个属性property和一个方法getSuperValue function SuperClass() { this.property = true; } SuperClass.prototype.getSuperValue = function...

    Javascript学习笔记之 对象篇(三) : hasOwnProperty

    // Poisoning Object.prototype Object.prototype.bar = 1; var foo = {goo: undefined}; foo.bar;...Javascript 中没有其他方法能判断一个属性是定义在对象本身还是继承自原型链。 hasOwnProperty 作为

    JavaScript高级整理

    谷粒学院学习笔记,内容包括 原型与原型链、执行上下文、执行上下文栈、变量提升、函数提升、作用域、作用域链、闭包、对象的多种创建模式、对象的继承模式、JavaScript事件循环机制等。

Global site tag (gtag.js) - Google Analytics