JavaScript 原型链、prototype、__proto__详解

简介: 1、背景 Javascript的继承模型、原型链等等概念比较晦涩难懂, 很多人过去在使用Javascript的时候并没有刻意去搞明白其中的原理,今天笔者一步一步分析一下JavaScript中的继承、原型链、prototype、__proto__。

1、背景

Javascript的继承模型、原型链等等概念比较晦涩难懂, 很多人过去在使用Javascript的时候并没有刻意去搞明白其中的原理,今天笔者一步一步分析一下JavaScript中的继承、原型链、prototype、__proto__。 笔者并不打算写过多的文字解释原理,而是希望将原理总结成代码片段更便于理解。

2、JavaScript继承是如何实现的?

     你只需要知道JavaScript 是通过名叫原型链的东西来实现继承的,依托于constructor.prototype属性(构造函数的prototype属性)即可。 你现在并不需要明白原型链是什么东西我会在下面一步一步详解。

3、 javascript通过prototype实现继承

function Animal() {
   this.echo=function () {
       console.log('I am An Animal....')
   };
   this.value=1;
}
function Monkey() {

}
//将构造函数Monkey的prototype属性设置为一个Animal的对象,Monkey就拥有了Animal的所有属性和方法
Monkey.prototype=new Animal();
new Monkey().echo();
console.log(new Monkey().value);

4、prototype、__proto__解析区别

我们知道在JavaScript中我们可以通过new 创建一个对象,我们是根据一个函数模板创建一个对象。也就是说如下代码
Animal函数便是函数模板,类似C++/java等的类的概念,然而 new Animal出来的就是对象的概念。
function Animal() {
   this.echo=function () {
       console.log('I am An Animal....')
   };
   this.value=1;
}
prototype是在构造函数(函数模板),也就是上面的Animal上设置的属性, 通过设置这个属性我们可以实现 继承。
__proto__属性是对象的一个属性,在ECMAScript规范中是不暴露的,但是有些浏览器可以访问到,对象的这个属性值就是函数模板的prototype值,
不知道这样说是不是不容易理解,换一个方式吧 :对象.__proro__===函数模板.prototype,前提这个对象时 这个函数new出来的。 

5、通过设置上下文this的方式实现继承

  我们都知道函数中在可以使用this引用当前上下文, 下面这段代码就是通过设置构造函数的上下文this的方式实现了继承,下面我给出两段代码分别仔细阅读下,琢磨一下代码所表达的意思。

代码1
function Animal() {
    this.echo=function () {
        console.log('I am An Animal....')
    };
    this.value=1;
}
//创建一个字面对象 三个方式都创建了对象
var obj1=new function () {};
var obj2={};
var obj3=[]
//分别将三个对象设置成Animal构造函数的上下文 并且调用Animal函数,那么这个时候Animal函数中的this=obj1,obj2,obj3
Animal.call(obj1);
Animal.call(obj2);
Animal.call(obj3);
obj1.echo();
obj2.echo();
obj3.echo();
代码2
function Animal() {
    this.echo=function () {
        console.log('I am An Animal....')
    };
    this.value=1;
}

function  Monkey() {
    Animal.call(this);
}
new Monkey().echo();

6、什么是原型链?


  这个概念其实比较好理解,如果我们调用一个对象的一个方法,如何这个方法不存在那么就回去他的__proto__寻找,如果找到直接返回,如果没找到那么继续__proto__.__proto__中寻找,就像如下代码这样, B是如何找到value的。

代码1
var A={value:1};
var B={};
B.__proto__=A;
console.log(B.value);

代码2
function A() {
    this.value=1;
}
function B() {
}
B.prototype=new A();
console.log(new B().__proto__.value);

代码3
function A() {
    this.value=1;
}
function B() {
}
B.prototype=new A();
console.log(new B().value);


7、总结一些关于JavaScript 继承、类型判断 、prototype的用法

判断一个字面定义数组的原型的类型,输出是[object Array]
Object.prototype.toString.call([1].__proto__)
下面演示了数组和对象的关系, 原型链 []->Array->Object 下面返回true
Object.prototype===[].__proto__.__proto__
调用字面数组的Object 原型的toString方法输出[object Object]
[].__proto__.__proto__.toString()
直接调用Object原型方法toString 输出[object Object]
Object.prototype.toString([])
通过call调用toString方法并且设置上下文获取真实类型
console.log(Object.prototype.toString.call([]));
console.log(Object.prototype.toString.call(/x/));
console.log(Object.prototype.toString.call(/x/));
console.log([].__proto__.__proto__.toString.call(/x/ig));
console.log([].__proto__.__proto__.toString.call(null));
输出结果
[object Array]
[object RegExp]
[object RegExp]
[object RegExp]
[object Null]


参考文档 
MDN 

目录
相关文章
|
22天前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
2月前
|
JavaScript 前端开发 开发者
理解JavaScript中的原型链:基础与实践
【10月更文挑战第8天】理解JavaScript中的原型链:基础与实践
|
23天前
|
JavaScript 前端开发
JavaScript 原型链的实现原理是什么?
JavaScript 原型链的实现原理是通过构造函数的`prototype`属性、对象的`__proto__`属性以及属性查找机制等相互配合,构建了一个从对象到`Object.prototype`的链式结构,实现了对象之间的继承、属性共享和动态扩展等功能,为 JavaScript 的面向对象编程提供了强大的支持。
|
23天前
|
JavaScript 前端开发
原型链在 JavaScript 中的作用是什么?
原型链是 JavaScript 中实现面向对象编程的重要机制之一,它为代码的组织、复用、扩展和多态性提供了强大的支持,使得 JavaScript 能够以简洁而灵活的方式构建复杂的应用程序。深入理解和熟练运用原型链,对于提升 JavaScript 编程能力和开发高质量的应用具有重要意义。
|
25天前
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。
|
2月前
|
JavaScript 前端开发 开发者
探索JavaScript原型链:深入理解与实战应用
【10月更文挑战第21天】探索JavaScript原型链:深入理解与实战应用
32 1
|
2月前
|
JavaScript 前端开发 开发者
深入理解JavaScript原型链:从基础到进阶
【10月更文挑战第13天】深入理解JavaScript原型链:从基础到进阶
25 0
|
2月前
|
JavaScript 前端开发 开发者
原型链深入解析:JavaScript中的核心机制
【10月更文挑战第13天】原型链深入解析:JavaScript中的核心机制
33 0
|
2月前
|
JavaScript 前端开发 安全
深入理解JavaScript原型链:从基础到进阶
【10月更文挑战第13天】深入理解JavaScript原型链:从基础到进阶
28 0
|
2月前
|
JavaScript 前端开发
JavaScript - 测试 Prototype
JavaScript - 测试 Prototype
12 0