博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我的认知中关于原型(链)和this的错误
阅读量:5279 次
发布时间:2019-06-14

本文共 2097 字,大约阅读时间需要 6 分钟。

在Mozilla的mdn上关于Javascript是这样描述的

JavaScript 是一种基于原型的面向对象语言,而不是基于类的

所以指针的引用访问如果没有搞清楚,就很容易混淆其访问顺序,特别是当你的认识一支半截的时候(本文不会特别阐述原型链和作用域等问题,但会提及)。

回到原型上来!.

从ECMAScript的描述中我们得知,创建一个函数时会自动带有一个prototype的属性,该属性是指向函数原型对象的指针,每个原型对象都会有一个constructor属性(从传统的编程语言上,我们可以认为这个是该对象的构造函数,传统高级编程语言一般都需要显示的申明其构造函数)

当我们创建一个实例时,会自动带有一个__proto__的属性(可以理解为private),该属性指向其原型对象

Javascript中对象的prototype属性的解释是:返回对象类型原型的引用

所以每一个对象都有他的原型,这个原型有他自己的原型,直到最顶层的原生类型最后会返回(Null);那么在外部调用时,会首先去找自身属性,看其是否有,如果没有,就去找原型中是否有该属性,如果原型中没有,就会再往上层找原型的原型所具有的属性,找不到则返回undefined.

简单点来讲这就是原型链。举个例子:

假如你是一个10岁儿童,你要买糖,先摸下口袋里有没有钱,发现没有,就去找你老娘要,你老娘发现包里也没钱,让你去奶奶那里要要看。

如果你有呢?同时你老妈也有呢!你当然会先找自己包里的钱,因为你已经等不及要去买糖了(你真伟大,是我,就去老娘那里抠一点过来再说!) 。这种情况叫"属性遮盖"


当然,如果你对this理解不清楚,如果理解了上面的部分反而更容易犯错(挺纠结的,爱恨交织!)

放一段代码来看看

1 function Base() {2   this.desc = "Javis";        3 }4 5 Base.prototype.desc = "I'm not Jarvis! ";6 7 //xxoo8 console.log(new Base().desc);

猜一猜再去检验!

之前我的认识this指向name是Base的静态属性,通过new 创建的实例本身不具有该属性,但是他的原型属性中定义了name的值。那么它应该是”I'm not Jarvis“

> Jarvis

哦。no!!! 那I'm not Jarvis被覆盖了。我靠?,找一找

> console.log(new Base().__proto__.desc);

> I'm not Jarvis

改下代码:

1 function Base() { 2   this.desc = "我是真的Jarvis"; 3 } 4 Base.prototype = { 5   desc: "我是Jarvis", 6   addDesc: function(desc) { 7     this.desc= desc; 8   }   9 }10 11 var myInstance = new Base();12 myInstance.addDesc("你是假的");13 console.log(myInstance.desc);14 console.log(Base.hasOwnProperty('desc'));

哦!false!Base没有该属性..this 指向的是上下文。

也许你到这里都是轻松过关。。那么如果把Base换成Object类型呢?

var Base = {  desc: "我是真的Jarvis",  updateDesc: function() {    this.desc = "你是假的";  }  }Base.updateDesc();console.log(Base.desc);console.log(Base.hasOwnProperty('desc'));

//想到答案了吗?哇靠这还不简单。

把this换成Base.

Base.desc = "你是假的";

答案也一样!

不行,不行我还得换一换!

var Base = {  desc: "我是真的Jarvis",  updateDesc: function() {     this.desc = "你是假的";   }};var Child = function () {  this.desc = "哈哈,我是来看戏的!";  this.updateDesc = function() {    this.desc = "靠!越演越有爱了!";  };}Child.prototype.updateDesc = Base.updateDesc;var b = new Child();console.log(b.desc);b.updateDesc();console.log(b.desc);

好了。到了这里属性遮盖也出现了。。

转载于:https://www.cnblogs.com/sir-jarvis/p/3235867.html

你可能感兴趣的文章
TYVJ.1864.[Poetize I]守卫者的挑战(概率DP)
查看>>
0925 韩顺平java视频
查看>>
iOS-程序启动原理和UIApplication
查看>>
mysql 8.0 zip包安装
查看>>
awk 统计
查看>>
模板设计模式的应用
查看>>
实训第五天
查看>>
平台维护流程
查看>>
2012暑期川西旅游之总结
查看>>
12010 解密QQ号(队列)
查看>>
2014年辛星完全解读Javascript第一节
查看>>
装配SpringBean(一)--依赖注入
查看>>
java选择文件时提供图像缩略图[转]
查看>>
方维分享系统二次开发, 给评论、主题、回复、活动 加审核的功能
查看>>
Matlab parfor-loop并行运算
查看>>
string与stringbuilder的区别
查看>>
2012-01-12 16:01 hibernate注解以及简单实例
查看>>
iOS8统一的系统提示控件——UIAlertController
查看>>
PAT甲级——1101 Quick Sort (快速排序)
查看>>
python创建进程的两种方式
查看>>