`

解析JS的prototype继承机制

    博客分类:
  • js
阅读更多

许多人一直对JS的prototype继承机制不明了,到底在创建一个类的实例的时候,解析器为我们做了些什么呢?
首先,我们来看一个例子:

function class1() { 
this.name = "my name"; 
} 

function class2() { 
this.age = 123; 
} 

class2.prototype = new class1(); 
var obj = new class2(); 
alert(obj.name); 
alert(class2.prototype.name); 
delete class2.prototype; 
alert(obj.name); 
alert(class2.prototype); 
alert(class2.prototype.name); 

结果将是 
firefox "my name" "my name" "my name" "[object object]" undefined
IE       "my name" "my name" "my name" undefined 出错

从最后两个结果来看,Firefox下的prototype是可以删除的,但它却是一定会存在的,在做delete(class2.prototype)的时候,Firefox将prototype变成一个普通的Object。
而IE对此的处理方式有所不同,当删除class2.prototype的时候,它就真真正正被删掉了,所以会得到undefined,并且最后一行会出错。
可能就有人会有疑问了,我们都已经把class2.prototype给删除了,虽然Firefox和IE处理方式不同,但确确实实肯定不会存在class2.prototype.name这个变量了,但为什么在删除之后,class2的实例obj的name值会存在?这就是我们要说的重点之一了。

 

接着看下边几行代码,请使用Firefox来运行。

function class1() { 
this.name = "my name"; 
} 

function class2() { 
this.age = 123; 
} 

class2.prototype = new class1(); 
var obj = new class2(); 

alert(obj.name); 
alert(obj.__proto__.name); 

delete class2.prototype; 

alert(obj.name); 
alert(obj.__proto__.name); 

obj.name = "new name"; 

alert(obj.name); 
alert(obj.__proto__.name); 

delete obj.name 

alert(obj.name); 
alert(obj.__proto__.name);

 

  在我们指定的firefox下运行结果是: "my name" "my name" "my name" "my name" "new name" "my name" "my name" "my name"
是不是觉得结果好奇怪?__proto__这又是什么变量呢?为什么在delete(obj.name)之后,原先这个值为"new name"的属性没消失,但却随着这行代码变成了"my name"
稍加分析,其实这个__proto__对象,就是原先那个class2.prototype,而且尽管class2.prototype被清掉了,这个obj.__proto__对象却依然存在!
我们立刻就可以想到,JS里一个类的实例在实例化完毕之后,就与原先的类的关系断开了。当它在本身找不着一个属性的时候,会尝试去__proto__里找,如果找着就把它当成本身的属性了。
这是根据Firefox提供出来的这个__proto__对象推断出来的,那IE又是怎么样的呢?我们继续看下边简化了的代码:

function class1() {
  this.name = "my name";
}

function class2() {
  this.age = 123;
}

class2.prototype = new class1(); 
var obj = new class2();

alert(obj.name);
alert(obj.__proto__);
delete class2.prototype;

alert(obj.name);

obj.name = "new name";

alert(obj.name);

delete obj.name

alert(obj.name);

 在看过Firefox下的运行结果后,我们可以很欣喜地看到IE其实处理方式应该是一致的,在删除obj.name之后,它的值确实像Firefox一样,"new name"变成了"my name",但它并没有给我们提供__proto__这样的对象。

于是,我很肯定但有点武断地得出了以下推论:

在运行"new xxx()"的时候,解析器会创建一个空的Object,然后为它创建了一个名字可能为__proto__(为什么要用可能二字?因为IE不知道起的是什么名,但Firefox确实用了这个名字)的属性,然后将xxx类的prototype赋值给它。接下来,进入类本身,相当于xxx.call(obj)的方式把新的对象当成this一行一行执行下去,然后返回该对象。
从这里也可以看出JS里根本没有类这种东西,或者说没有真正的类,它纯属模拟出来的,这也是为什么类的定义跟函数的定义都用了function这个关键词,事实上类的定义就是一个函数,它负责将传进来的this对象根据函数的逻辑给它增加了属性以及方法,跟其它高级语言里的类的定义是完全不一样的。

 

原文:http://bbs.51js.com/thread-83874-1-1.html

分享到:
评论

相关推荐

    javascript中类和继承(代码示例+prototype.js)

    JavaScript的类和继承机制是其面向对象特性的重要组成部分。通过函数构造器、原型链以及`prototype.js`文件中可能提供的类和继承工具,我们可以创建复杂的对象结构和组织代码。理解并掌握这些概念有助于提升...

    浅析javascript原型继承机制

    ### 浅析JavaScript原型继承机制 #### 一、引言 JavaScript作为一种动态语言,其对象模型与传统的面向对象编程语言有所不同。在JavaScript中,并没有直接提供类的概念,而是通过原型来实现继承。本文将深入探讨...

    javascript类库prototype.js

    6. **Class与Object继承**:Prototype.js 引入了面向对象的概念,实现了类(Class)和对象继承,使得JavaScript具备了更接近传统面向对象语言的编程模式。 7. **JSON支持**:随着JSON成为数据交换的主流格式,...

    prototype.js简介

    通过阅读源码,我们可以学习如何利用JavaScript实现面向对象编程,理解其内部的类继承机制,以及它是如何优化DOM操作的。 2. **1.4.chm** - 这可能是一个帮助文件,通常用于提供API参考和库的详细文档。在prototype...

    prototype.js 1.6

    《Prototype.js 1.6:JavaScript 动态对象增强库的深度解析》 Prototype.js 是一个广泛使用的 JavaScript 库,它为浏览器环境提供了许多实用的功能,尤其是在对象操作和事件处理方面。1.6 版本是该库的一个重要里程...

    prototype_PrototypeJS1.6_

    标题"prototype_PrototypeJS1.6_"中提到的"Prototype"是一个JavaScript库,它为JavaScript编程提供了一套丰富的工具集,主要用于简化DOM操作、创建Ajax应用以及实现对象的继承机制。"1.6版本"表明这是该库的一个特定...

    prototype.js

    Prototype.js与jQuery、Dojo等其他JavaScript库相比,虽然在某些方面功能可能稍显逊色,但它更注重于提高代码的可读性和可维护性,特别是对于熟悉JavaScript原型机制的开发者来说,Prototype.js的API设计更为直观。...

    Prototype-1.6.0 中文版\英文版\Prototype.js

    6. **JSON支持**:Prototype包含了JSON(JavaScript Object Notation)解析和序列化功能,使得JavaScript对象与服务器端的数据交换变得更加便捷。 7. **动画效果**:Prototype还提供了简单的动画功能,如`Effect`...

    javascript关于继承解析_.docx

    JavaScript中的继承机制是面向对象编程的关键部分,它允许创建基于现有对象的新对象,同时保留原有的属性和方法。这里我们将深入探讨几种主要的继承方式:原型式继承、寄生式继承和寄生组合式继承。 ### 原型式继承...

    prototype 开发应用手册,笔记,prototype.js文件下载

    《Prototype开发应用手册:深入解析与实践》 Prototype是一个强大的JavaScript库,由Sam Stephenson创建,旨在提升JavaScript的开发效率,提供丰富的类和函数扩展,为JavaScript编程带来面向对象的特性。在本手册中...

    prototype.js 1.6中文手册、prototype.js 1.6英文手册、

    Prototype.js 1.6改进了事件处理机制。`Event.observe()`和`Event.stopObserving()`用于添加和移除事件监听器,`Event.stop()`则用于阻止事件的默认行为。此外,还有`Element.simulate()`,它允许模拟触发指定的DOM...

    理解Javascript原型继承原理

    通过以上分析,我们可以看到,在JavaScript中,通过`prototype`和`[[Prototype]]`实现了非常灵活的继承机制。这种机制允许我们轻松地扩展和重用现有对象的功能,同时也使得JavaScript成为一种非常适合面向对象编程的...

    prototype-1.4.0源码解读.js

    Prototype 提供了诸如`String.prototype.parseColor`、`Function.prototype.bind`等工具,前者用于解析颜色字符串,后者实现函数绑定,确保函数的`this`值始终指向预期的对象。 通过分析Prototype 1.4.0的源码,...

    JS继承.txtJS继承.txt

    JavaScript支持多种继承机制,包括原型链继承、构造函数继承、组合继承、寄生式继承以及寄生组合继承等。接下来,我们将详细探讨这些继承方式。 ### 1. 原型链继承 原型链继承是通过将一个对象设置为另一个对象的...

    prototype.js开发者手册

    《prototype.js开发者手册》是针对JavaScript库Prototype的一份详尽指南,旨在帮助开发者深入理解和有效利用这个强大的工具。Prototype.js是开源的JavaScript框架,它扩展了JavaScript的基本对象,提供了类和面向...

    prototypejs

    要充分利用PrototypeJS,你需要理解其核心机制,如对象的扩展、类的继承和实例化,以及如何使用提供的DOM和Ajax工具。阅读`prototype.pdf`文档会是很好的起点,其中详细介绍了 PrototypeJS 的使用方法和示例代码。 ...

    prototype学习笔记

    在JavaScript中,`prototype`是一个核心...总的来说,这篇"prototype学习笔记"深入讲解了JavaScript中的原型和继承机制,结合源码分析和实用工具,帮助开发者更全面地掌握这一核心概念,并能够在实际项目中灵活运用。

    js继承实现示例代码

    通过上述示例代码,我们了解了如何在JavaScript中实现简单的继承机制。虽然这段代码提供了一种实现方式,但在实际项目中,更推荐使用ES6的类语法来实现继承,因为它更简洁且易于理解。此外,也可以考虑使用现有的库...

    js继承 Base类的源码解析

    在JavaScript中,继承是一种核心机制,它允许创建新的对象类型并重用已存在的代码。`Base`类在JavaScript中被广泛使用,作为一个优秀的继承封装,它简化了对象间的继承关系。这里我们将深入解析`Base`类的部分源码,...

    javascript prototype原型操作笔记.docx

    ### JavaScript Prototype原型操作...通过以上分析可以看出,JavaScript 中的原型机制是实现继承的关键,同时也是理解面向对象编程的基础。掌握原型和原型链的概念对于编写高质量、可维护的 JavaScript 代码至关重要。

Global site tag (gtag.js) - Google Analytics