javascript的继承机制和原型链是非常重要的概念。一直以来都觉得掌握的不够深入彻底,如果有那么几个月不写不用就总是会忘记。所有把平时在项目中对这些机制的理解都记录下来供自己未来查阅和同行们指正。
先看一个简单的例子,这个例子我把输出的结果都放到注释里面方便查看.
function l(l) {//这是方便在浏览器里面查看结果的一个log函数. console.log(l) } function D(ufo) { this.ufo = ufo; } var d1 = new D("d1"); l("来看看类的情况:") l(typeof D.prototype)//这是一个object.所以大家才可以随便往里面新增方法和属性. l(D.prototype)//如果没有手动修改.默认就是D{}这个object.也就是一个空的D对象. l(D.__proto__)//这个返回的是function Empty() {} .好像类或者任意function的__proto__总是返回Empty这个function.这个到底是做什么的呢?我现在还没搞明白.希望有同行指教. l(typeof D.constructor)//return function. l(D.constructor);//所有类的constructor都是function Function() { [native code] } .也就是Function.这个是本地方法.或许是c语言或者c++写的. l("来看看实例的情况:") l(d1.prototype);//return undefined .实例是没有prototype的. l(d1.__proto__)//看下面的代码你会发现他和类的prototype是一个东西. l(typeof d1.constructor)//return function l(d1.constructor)//实例的function就有点意思了也就是D这个function的定义本身.也就是构造器本省.去new的时候就会执行这个构造器. //我们看看这这两个属性是否一样 l(D.prototype==d1.__proto__)//return true:类D的prototype指针和实例d1的__proto__指针指向同一个object
通过上面大概能对prototype和__proto__还有constructor有一点点印象.但是实际情况有时候根据复杂一些.比如加入继承机制以后.他们就发生了明显的变化.再看看一个更加复杂的例子.里面加入了3层继承:
function l(l) { console.log(l) }//这里是为了在浏览器里面的调试封装的一个log函数.后面的l调用均代表此function function A(){ this.a="a" } function B() { this.b = "b" } B.prototype=new A() function C(name, age) { this.name = name; var _age = age; this.get1 = function() { console.log(name + " " + age) }; this.get2 = function() { console.log("ufo:" + name + age + "--" + _age) } } C.prototype = new B() function D(ufo) { C.call(this, "ufo", 1000) this.ufo = ufo; } D.prototype = new C(); var d1 = new D("d1"); var d2= new D("d2");
代码的继承轨迹: D>C>B>A.使用类D实例化了d1和d2,我们仔细查看d1和d2的内存数据结构:
可以看到类C相对于类D都是依照原型链存在的.方法get1和get2都是在__proto__原型的C层级.因此如果我们运行:
l(d1.get1==d2.get1)//这里的结果是true.
不难理解.因为原型的内存是共享的.所以结果是true.
那我们修改代码如下:
function l(l) {
console.log(l)
}
function A(){
this.a="a"
}
function B() {
this.b = "b"
}
B.prototype=new A()
function C(name, age) {
this.name = name;
var _age = age;
this.get1 = function() {
console.log(name + " " + age)
};
this.get2 = function() {
console.log("ufo:" + name + age + "--" + _age)
}
}
C.prototype = new B()
function D(ufo) {
C.call(this, "ufo", 1000);//我们增加了这一句
this.ufo = ufo;
}
D.prototype = new C();
var d1 = new D("d1");
var d2= new D("d2");
l(d1.get1==d2.get1);//现在变成了false
现在在D的构造器里面我们去运行了C的构造器.并且传入了this.这样的就提升了C内部的get1和get2方法的位置.我们再一次看看内存数据结构.
内存数据显示.原型链的get1和get2还在那里.因为function在javascript里面是独立存在的.她不属于任何一个class或者object.完全不像java c#.所有通过call或者apply可以在任何你希望的地方去运行function.并且在第一个参数传入你希望的object.他就会修改运行的上下文环境.比如这里传入this.那么构造器function C就被作为D的一个内存函数被运行了一遍.里面的逻辑也会像普通函数一样作用于D.这样D的内部也就产生了get1和get2.当你调用get1和get2的时候就不会去去调用原型链的get1和get2了.这个时候实例化的d1和d2都是独立的object.在内存里面分别各自维护了一份get1和get2的内存区域.所有上面的程序返回结果为false.
相关推荐
分析javascript中 prototype __proto__ constructor之间的关系
JavaScript中的`prototype`、`__proto__`和`constructor`是理解JavaScript面向对象编程的关键概念。这篇文章通过图解的方式深入浅出地解析了这三个概念之间的关系。 首先,`__proto__`属性是对象独有的,它指向对象...
在JavaScript中,`prototype`和`__proto__`都是与对象继承和原型链紧密相关的概念,但它们在用途和性质上有所不同。以下是这两者的主要区别和详细解释: 1. **prototype(原型)** - `prototype`是函数特有的属性...
在继承链中,每个对象都有自己的`__proto__`,而函数的`prototype`则为创建它的对象提供了继承的基础。例如,`Function.prototype`是一个对象,它也有`__proto__`,这个`__proto__`指向`Object.prototype`。`Object....
当我们访问person1.name的时候,由于person1自身并没有name属性,JavaScript引擎就会沿着原型链向上查找,通过person1的__proto__属性找到Person.prototype,最后找到了name属性并返回'Jack'。 现在我们来区分一下...
JavaScript中的`prototype`、`__proto__`和`constructor`是理解JavaScript面向对象编程的关键概念。这篇文章将通过图解的方式帮助读者深入理解这三个属性的关系。 首先,`__proto__`属性,它存在于每个对象中,表示...
在JavaScript中,对象可以直接从另一个对象继承属性和方法,这主要是通过原型链(prototype chain)来实现的。 首先,每个函数都有一个`prototype`属性,这个属性是一个对象,当通过该函数创建新对象时,新对象会...
__proto__属性可以追溯到JavaScript的早期版本,那时候JavaScript的继承机制主要是通过原型链来实现的。原型链是一系列对象通过__proto__属性链接在一起的链条,这个链条的最顶端是Object.prototype。这个原型链可以...
它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(可以理解为父对象)里找,如果父对象也不存
本文将深入探讨JavaScript原型链的工作原理及其可能导致的安全问题——原型链污染。 首先,JavaScript 中的对象继承并不像传统面向对象语言那样基于类,而是通过原型链机制。每个对象都有一个内部属性`[[Prototype]...
JavaScript原型链是JavaScript实现继承和共享属性的一种机制。在JavaScript中,每个对象都有一个内部属性`[[proto]]`,这个属性通常通过`__proto__`访问,它指向创建该对象的函数的`prototype`属性。原型链的主要...
JavaScript 是一种广泛应用于Web开发的动态编程语言,其核心特性之一就是原型链和作用域链。这两个概念是理解和掌握JavaScript高级特性的基础。 首先,我们来深入探讨一下**作用域链**。作用域决定了变量在何处可以...
总结一下,__proto__属性与prototype属性是JavaScript原型继承中的两个关键点,它们共同支撑起JavaScript的原型链继承机制。通过__proto__属性,我们可以追踪到对象的原型链,而通过prototype属性,函数可以将其属性...
1. **继承机制**:JavaScript的继承是基于原型链实现的。当试图访问一个对象的属性时,如果该对象自身没有这个属性,JavaScript会向上查找其`__proto__`,直到找到该属性或者到达原型链的顶端(即`null`)。 2. **...
JavaScript中的原型继承是一种基于原型(Prototype)的继承机制,它不同于传统的类继承,而是通过对象之间的关联来实现对象间的共享属性和方法。在JavaScript中,每个函数都有一个`prototype`属性,这个属性是一个...
### JavaScript原型与原型链详解 JavaScript作为一门基于原型的语言,其原型和原型链的概念是理解和掌握JS继承机制的关键。接下来将详细阐述这些概念。 #### 普通对象与函数对象 在JavaScript中,一切皆为对象,...
在JavaScript中,理解原型(Prototype)与原型链(Prototype Chain)是至关重要的。这两个概念是语言的核心部分,对于深入理解对象的属性查找机制、继承等方面有着不可替代的作用。 #### 原型(Prototype) 在...
总结一下,理解JavaScript的原型对象和原型链,关键在于把握`prototype`和`__proto__`的关系以及它们在对象继承中的作用。通过清晰地描绘出原型链,可以帮助我们更好地掌握JavaScript的继承机制,并解决实际编程中的...
JavaScript中的`prototype`是理解面向对象编程的关键概念之一。它是一种机制,允许对象共享属性和方法,从而实现代码复用。...理解`prototype`以及相关的原型链、继承和对象创建方式,对于深入学习JavaScript至关重要。