深入理解JavaScript中的继承:原型链篇
一、何为原型链
原型是一个对象,当我调用一个对象的方法时,如果该方法没有在对象里面,就会从对象的原型去寻找。JavaScript就是通过层层的原型,形成原型链。
二、谁拥有原型
任何对象都可以有原型,当我们创建对象的时候,会自动为对象添加一个属性,这个属性就是原型,我们无法访问到他,但在firefox和chrome中可以通过一个非标准的属性__proto__(双下划线)来访问到原型(或通过Object.getPrototypeOf来访问)。
三、理解原型链
我们先从以下代码入手
var foo = {};
console.log(foo.toString()); // [object Object]
console.log(foo.__proto__); // object { ... } 这里指向Object.prototype
foo里面明明没有toString方法,但我却能调用,这就是原型链的作用。当我调用foo.toString时,由于在里面找不到toString方法,那么我从__proto__属性里面去找,找到后并调用。上面的代码中我们就是从Object.prototype中找到了toString方法。你可能会很困惑,prototype是什么?我们不要被prototype所迷惑,他只是一个存放属性的容器而已,你可以如下这样做来实现继承(但尽量不要这么做)
function Bar() {}
Bar.test = {
say: function () {
console.log('say test');
}
}
var foo = new Bar();
foo.say(); // 报错
// 改变继承的对象
foo.__proto__ = Bar.test;
foo.say() // say test
在上面的代码中我们通过new的形式来创建一个对象,在new的过程中对象会将__proto__指向函数的prototype,由于prototype中是没有say函数的,所以调用会报错,但是之后我们强行改变了继承的对象,将foo的继承对象改为Bar.test,所以我们就能调用say函数了。
我想你已经明白个大概了,prototype事实上并没有什么特殊的,硬要说有什么特殊的话,他只是被JavaScript默认为原型属性的存放点而已,他本质上只是个对象,原型链的重点就在于__proto__,你可以试着把__proto__当作桥梁,当我在对象内部找不到属性时,我就会通过这座桥梁到对面的对象里去寻找属性,直到找到为止或者对象里没有桥梁时才停下来。JavaScript就是通过这样的方式来形成原型链,实现继承的关系。
最后说一下,__proto__只是方便我们查看对象的原型而已,大家不要通过修改__proto__来实现继承的关系,而是要用如构造函数之类的方式来实现继承,这个我会放到以后的文章去说。
(ps:可能有动手能力强的同学会自己去测试,发现__proto__里面也有__proto__,一直循环下去,无穷无尽,但事实上你去获取的时候你会发现Object.__proto__.__proto__.__proto__的值是null,也就是没有原型。)
深入理解JavaScript中的继承:原型链篇的更多相关文章
- 深入理解JavaScript中的继承
1前言 继承是JavaScript中的重要概念,可以说要学好JavaScript,必须搞清楚JavaScript中的继承.我最开始是通过看视频听培训班的老师讲解的JavaScript中的继承,当时看的 ...
- 深入理解Javascript中构造函数和原型对象的区别
在 Javascript中prototype属性的详解 这篇文章中,详细介绍了构造函数的缺点以及原型(prototype),原型链(prototype chain),构造函数(constructor) ...
- 深入理解Javascript中构造函数和原型对象的区别(转存)
Object是构造函数,而Object.prototype是构造函数的原型对象.构造函数自身的属性和方法无法被共享,而原型对象的属性和方法可以被所有实例对象所共享. 首先,我们知道,构造函数是生成对象 ...
- JavaScript中的继承(原型链)
一.原型链 ECMAScript中将原型链作为实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 实例1: function SupType() { this.pro ...
- 深入理解javascript中实现面向对象编程方法
介绍Javascript中面向对象编程思想之前,需要对以下几个概念有了解: 1. 浅拷贝和深拷贝:程序在运行过程中使用的变量有在栈上的变量和在堆上的变量,在对象或者变量的赋值操作过程中,大多数情况先是 ...
- 理解JavaScript中的原型继承(2)
两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...
- JavaScript 中实现继承的方式(列举3种在前一章,我们曾经讲解过创建类的最好方式是用构造函数定义属性,用原型定义方法。)
第一种:对象冒充 function ClassA(sColor) { this.color = sColor; this.sayColor = function () { alert(this.col ...
- 深入理解JavaScript中创建对象模式的演变(原型)
深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...
- 深入理解javascript中执行环境(作用域)与作用域链
深入理解javascript中执行环境(作用域)与作用域链 相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行 ...
随机推荐
- tomcat部署在centos6.8上的乱码问题
web访问经常会莫名其妙的出现各种乱码问题.按照我自己的理解,设置一个charSet的过滤器,代码如下:import java.io.IOException; import javax.servlet ...
- React——组件的生命周期函数
每一个组件都有一些生命周期函数. 当组件实例被创建并且会插入到DOM中,下面这些函数会被调用 constructor componentWillMount render componentDidMou ...
- C++拷贝构造函数专题
C++拷贝构造函数 在定义任何C++类时,拷贝空置操作都是必要部分,类需要控制拷贝.赋值和销毁对象时发生的行为.拷贝构造函数的用途:当创建了一个新对象时,可以用另一个对象的数据初始化这个新建的对象. ...
- css 浮动和清除浮动
在写页面布局的过程中,浮动是大家经常用的属性.在好多的排版布局中都是用的的浮动比如说下面这些地方都是应用到了浮动. 在我学习浮动的时候可是熬坏了脑筋,在这里我分享一下我对浮动这块知识的总结. 一.浮动 ...
- Linux系统centOS7在虚拟机下的安装及XShell软件的配置
前面的话 本文将详细介绍Linux系统centOS7在虚拟机下的安装 准备工作 [系统下载] 在安装centOS7之前,首先在官网下载合适的版本 然后,选择一个链接下载即可 [虚拟机配置] 接下来,需 ...
- Python 获取当前脚本文件路径目录
# -*- coding: cp936 -*- import sys,os # 获取脚本文件的当前路径 def cur_file_dir(): # 获取脚本路径 path = sys.path[0] ...
- Java面向对象 GUI 补录
Java面向对象 GUI 补录 知识概要:(1)GUI和CLI (2)AWT和SWING (3)AWT继承关系图 ...
- 安装Extended WPF Toolkit
Extended WPF Toolkit 可以说是WPF Toolkit 的一个补充,也包含了许多WPF 控件供开发者使用.本篇将介绍Extended WPF Toolkit 1.4.0 中新增的一些 ...
- C++的socket编程学习
前言 不得不承认作为一个前端开发,仍有一个后台开发的梦.从socket通信开始学习,在工作之余补充学习点相关知识,记录下学习的过程. 服务端 服务器代码如下,在设置listen之后,通过accept获 ...
- 对象反序列化时,抛出java.io.StreamCorruptedException: invalid type code: AC异常
问题描述:在使用java.io.ObjectInputStream类的readObject()方法去读取包含有序列化了多个(两个及两个以上)类的文件时,当读取到第二个类时,会抛出题目中提到的异常. 原 ...