JavaScript原型与原型链以及实例
来源:互联网 发布:网络诈骗多少钱才算 编辑:程序博客网 时间:2024/06/06 01:27
谈到JavaScript的原型链,需要思考的几个问题:
1,什么是原型链?
2,原型链有什么作用?
在JavaScript中不像其他语言有类的概念,提到JavaScript,想到的都是函数,函数无非两个用途:
1,像一般函数一样去调用它。
2,作为函数原型的构造函数去new它。
JavaScript原型
什么是JavaScript原型?
JavaScript每声明一个function,都附带着prototype原型,prototype原型是函数的一个默认属性,在函数的创建过程中由JavaScript编译器自动添加。
简言之:每当创建一个function对象的时候,就有一个原型prototype。
栗子:
那么,创建一个函数这个过程到底发生了些什么呢?
再看一个栗子:
function a(){ this.name="a";}
过程:
1、它会创建一个函数对象 也就是a 本身(一个构造函数)。
2、它会创建一个原型对象A(用A来表示)。
3、函数对象会有一个prototype指针,它指向了对应的原型对象,这里就指向了A。
4、原型对象A中有一个construtor指针,指向它的构造函数,这里就指向了函数a。
这个构造函数a有什么作用呢?或者说怎么去使用它呢?
答案就是 —– new。
比如:
function a(){ this.name = 'a'; } var a1 = new a();
这里,a1就是调用原型对象(通过prototype指针)里面构造函数(constructor)创建一个新的对象实例。
如果去修改原型对象中的属性,那么以它为“蒙版”实例化出来的a1又会怎么样呢?
看一个栗子:
function a(){ this.name = 'a'; } var a1 = new a(); a.prototype.age = 18;console.log(a1.age); // 18
为什么a1对象里明明没有定义age属性,确得到了18这个值呢?
原因是新实例化的对象a1内部有一个看不见的 _proto_ 指针,指向原型对象A。
在访问属性的时候,会先在a1对象内部中寻找,如果没有,就会顺着 _proto_ 指向的对象里面去寻找,这里会到原型对象A中寻找,找到就返回值,没有找到就返回undefined,反正就是逐级向上查找。到这里,就可以看到 原型链 的影子了。
附上另外说明:
1、一个没有继承操作的函数的 _proto_ 都会指向Object.prototype,而Object.prototype都会指向null。
2、所以,也可以很明显知道,为何null是原型链的终端。
再来看个栗子:
function a(){ this.name="a";}a.prototype.age = 18;function b(){ this.apple="5s";}b.prototype = new a(); // b 继承 ab.prototype.foot = "fish";function c(){ this.computer = "MAC";}c.prototype = new b(); // c 继承 b , b 继承 a var d = new c(); console.log(d.apple); // 5sconsole.log(d.name); // aconsole.log(d.foot); // fishconsole.log(d.age); // 18
从这个栗子就能很形象的看出来“一层层往上找”的思想了吧!c继承b , b继承a ,无形之中就连成了一条“线”,这条线就是“原型链”。
代码延伸一下:
function b(){ this.apple="5s";}b.prototype.foot = "fish";function c(){ this.computer = "MAC";}c.prototype.c1=function(){ console.log("c1存在");}c.prototype = new b(); // c 继承 bc.prototype.c2=function(){ console.log("c2存在");}var d = new c(); console.log(d.apple); // 5sconsole.log(d.foot); // fishconsole.log(d.computer); // MACd.c2(); // "c2存在"d.c1(); // Uncaught TypeError: d.c1 is not a function
可以看到,构造函数c的实例d调用 c1() 报错了,很明显 c1() 已经不存在于原型对象C中了。这是为什么呢?
原因是 “c.prototype = new b(); // c 继承 b” ,这使得原型对象C的指向发生了变化,原来装有 c1() 的原型对象被抛弃了。
继续升级,探究一下c继承b之后还发生了哪些变化:
栗子:
function b(){ this.apple="5s";}b.prototype.foot = "fish";function c(){ this.computer = "MAC";}c.prototype.c1=function(){ console.log("c1存在");}c.prototype = new b(); // c 继承 bc.prototype.c2=function(){ console.log("c2存在");}console.log(c.prototype.constructor); // 新增代码 c.prototype.constructor = c; // 新增代码 console.log(c.prototype.constructor); // 新增代码 var d = new c(); console.log(d.apple); // 5sconsole.log(d.foot); // fishconsole.log(d.computer); // MACd.c2(); // "c2存在"d.c1(); // Uncaught TypeError: d.c1 is not a function
可以看出,c继承了原型对象B的实例化之后,原型对象C 的构造函数指针指向了 构造函数b 。
这是不是说 var d = new c(); 在构造c的实例化d 的时候指向的是 构造函数b呢?答案是否定的。因为d.computer打印出来的值依然是”MAC”,所以仍然是调用的构造函数b进行的实例化。虽然不影响d的实例化,但是影响到了d.constructor的指向,d.constructor也指向了构造函数b。
所以,建议在c继承b之后,对原型对象C 的构造函数指针进行修正操作:c.prototype.constructor = c;,修正之后的指向:
描述不对的地方,多包涵。
- JavaScript原型与原型链以及实例
- JavaScript原型以及原型链
- JavaScript 原型与实例
- javascript原型与原型链
- JavaScript原型与原型链
- javascript原型与原型链
- 原型以及原型链
- 【javascript基础】原型与原型链
- javascript原型链与原型继承
- JavaScript原型与原型链分析
- javascript原型与原型链终极详解
- JavaScript 原型、原型链与继承
- JavaScript原型与原型链分析
- javascript原型对象与原型链
- JavaScript原型与原型链学习总结
- JavaScript原型与原型链分析
- JavaScript原型与原型链分析
- javascript的原型与原型链
- vue2.0开发环境的搭建详解
- struts2文件上传大小限制问题解决记录
- hadoop集群搭建
- Spring 学习笔记之IOC
- 计蒜之道(阿里的新游戏)第一题 解题报告
- JavaScript原型与原型链以及实例
- POJ 1269 Intersecting Lines 笔记
- 如何Android studio 的布局XML时预览界面弹出的Rendering Problems?
- [leetcode]: 405. Convert a Number to Hexadecimal
- Jieba中文分词说明
- gdb 带参数调试
- AST 抽象语法树学习
- 计蒜客 阿里天池的新任务(简单)KMP轻松水过
- 状态栏背景颜色和状态栏图标icon颜色修改