javascript继承一直很差理解,每次遇到了看了彷佛懂了,可是没有完全研究过并且遇到一次忘记一次,此次想完全的解决掉,用最简单直白的阐述。引入了前辈的一些见解,进行了收集加工整理。
用百度脑图作了整理javascript
javascript出现是为了加强用户和浏览器之间的交互。好比,若是网页上有一栏"用户名"要求填写,浏览器就没法判断访问者是否真的填写了,只有让服务器端判断。若是没有填写,服务器端就返回错误,要求用户从新填写,这太浪费时间和服务器资源了。
当时javascript的做者Brendan Eich受到当时面向对象编程的影响,主要是Java的影响,Javascript里面全部的数据类型都是对象(object)。这时候,他要考虑一个问题,javascript到底需不须要继承?html
javascript中是没有“类”这个概念的,new 后面不是面向对象编程中的“类”,而是构造函数。如例:java
function DOG(name){ this.name = name; } //对这个构造函数使用new,就会生成一个狗对象的实例。var dogA = new DOG('大毛'); alert(dogA.name); // 大毛
用构造函数生成实例对象,有一个缺点,那就是没法共享属性和方法。编程
function DOG(name){ this.name = name; this.species = '犬科'; } //生成两个实例对象:var dogA = new DOG('大毛'); var dogB = new DOG('二毛'); dogA.species = '猫科'; alert(dogB.species); // 显示"犬科",不受dogA的影响
每个实例对象,都有本身的属性和方法的副本。这不只没法作到数据共享,也是极大的资源浪费。数组
考虑到这一点,Brendan Eich决定为构造函数设置一个prototype属性。浏览器
这个属性包含一个对象(如下简称"prototype对象"),全部实例对象须要共享的属性和方法,都放在这个对象里面;那些不须要共享的属性和方法,就放在构造函数里面。服务器
实例对象一旦建立,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分红两种,一种是本地的,另外一种是引用的。ide
如例:函数
function DOG(name){ this.name = name; } DOG.prototype = { species : '犬科' }; var dogA = new DOG('大毛'); var dogB = new DOG('二毛'); alert(dogA.species); // 犬科 alert(dogB.species); // 犬科//只要修改了prototype对象,就会同时影响到两个实例对象。 DOG.prototype.species = '猫科'; alert(dogA.species); // 猫科 alert(dogB.species); // 猫科
因为全部的实例对象共享同一个prototype对象,那么从外界看起来,prototype对象就好像是实例对象的原型,而实例对象则好像"继承"了prototype对象同样。ui
关于第一章节为阮一峰《Javascript继承机制的设计思想》中观点。
构造函数 就是一个普通的函数,一般当函数名 为 大写开头的,咱们认为是构造函数,不然 就是普通的方法。
// 构造函数function A() { this.name = 'A Class instance'; } // 普通方法function m1() { }
JavaScript只有一种结构:对象。每一个对象都有一个内部连接指向另外一个对象,这个对象称为原型 (prototype)。那个原型对象也有本身的原型,如此直到某个对象以null做为其原型。null,根据定义,没有原型,做为这种原型链的最后一环而存在。
尝试用语言去解释
// 假设有个对象o,其原型链以下所示:// var o = {a: 1, b: 2} ---> {b: 3, c: 4} ---> null// 'a'和'b'是o的自有属性。 // 本例中,someObject.[[Prototype]]指定someObject的原型。// 这彻底是一种标记符号(基于ECMAScript标准中所使用的),不可用于脚本中。 console.log(o.a); // 1// o有一个自有属性'a'吗?是的,其值为1 console.log(o.b); // 2// o有自有属性'b'吗?是的,其值为2// o的原型也有一个属性'b',可是这里不会被访问。这被称为“属性隐藏”(property shadowing) console.log(o.c); // 4// o有自有属性'c'吗?没有,检查它的原型// o.[[Prototype]]有自有属性'c'吗?是的,其值为4。 console.log(o.d); // undefined// o有自有属性'd'吗?没有,检查其原型// o.[[Prototype]]有自有属性'd'吗?没有,检查其原型// o.[[Prototype]].[[Prototype]]为null,中止搜索,没有找到属性,返回undefined。
咱们用代码去解释
var o = {a: 1}; // 新建立的对象o有Object.prototype做为其[[Prototype]]// o没有名为'hasOwnProperty'的自有属性// hasOwnProperty是Object.prototype的自有属性。所以o从Object.prototype继承了hasOwnProperty// Object.prototype以null为其prototype。// o ---> Object.prototype ---> null var a = ["yo", "whadup", "?"]; // 数组继承自Array.prototype(它具备indexOf, forEach等方法)。// 该原型链以下所示:// a ---> Array.prototype ---> Object.prototype ---> null function f() { return 2; } // 函数继承自Function.prototype(它具备call,bind等方法):// f ---> Function.prototype ---> Object.prototype ---> null
四,参考的资料和笔记: