对原型对象中this的一个认知--(转自张鑫旭)

来源:互联网 发布:数据库结构的数据模型 编辑:程序博客网 时间:2024/06/11 18:00

1. 事情的起因
平时接触的都是下面的故事:

var story = {    progress: "unknown",    start: function() {        this.progress = "start";    }};

然后如下执行的时候,结果就是:

story.start();console.log(story.progress);

结果

将故事中标红的this改成story,结果也是一样的:

var story = {    progress: "unknown",    start: function() {        story.progress = "start";    }};story.start();console.log(story.progress);

结果

因此,很自然而然的,在理解上,我就会将this等同于story,也就是this等于这个对象本身
this与字面量对象的理解

//zxx: ① 实际上this并不能完全等同于story。如下例子:
不同调用不同的this含义
结果就是”unknown“. //zxx: 此时window.progress为”start”;

而执行story.progress = "start";的结果则依然是:”start“.

使用story.progress的结果


2. 事情的经过
如下,很简单的几行原型相关的代码:

var Story = function() {};Story.prototype = {    progress: "unknown",    start: function() {        this.progress = "doing";    }};var myStory = new Story();myStory.start();console.log(myStory.progress); // doing

结果是doing不难知道,关键在认识上。

prototype这东西有点像屌丝过滤器,不解释。
我刚接触原型概念的时候,被一堆解释搅得就像被抛弃在北京的雾霾天气里,不仅看不见方向,还胸闷!那种感觉就像是在步行街上遇到还没参加超女的张含韵,我不认识她,她也不认识我。

后来,生搬硬套,囫囵吞枣,也能用用:搞些扩展啊,继承啊什么的。然而多浮于表面,虽专门花了功夫去深入理透,但因大雾过于磅礴,依然理不清啊!这种感觉就像是张妹子参加超女红了,我认识她,她却不认识我,但是我仍能感受其表面的风采。

如果以上面这种状态理解为何结果为”doing“,可能自己那个未经深入思考的理解就是错误的。

我的错误理解
我以为,当执行了myStory.start();的时候,相当于这个:

progress: "unknown", → this.progress = "doing";↓progress: "unknown" "doing",↓myStory.progress = "doing"; 
图片示意就是:


骚年,不要开小差啊,上面的示意是错误的.错误的..错误的…..

错误的理解源于“故事的开始” – 普通对象字面量中的this这样理解很说得通的;以及对原型浮于表面的肤浅认知(有很多的感性成分)。

如何发现错误的?
所谓“实践出真知”,一点不假。如果整天睡在冻床上不知冷热,你则会——————变成小龙女!

我着手构建一个通过new构造的哈希方法(Hash)(本文part2),其中,有个很方法,叫做has, 用来检测对象是否有某关键字(键值对中的键)(不包括原型中的)。其实本质上就是hasOwnProperty方法。

例如上面那个myStory实例,继续下面的检测代码:

console.log(myStory.hasOwnProperty("progress")); console.log(myStory.hasOwnProperty("start")); 

测试代码

结果是什么呢?请选择




按照我之前的错误认识,结果应该是两个false. 而实际上,结果是true, false.

显然,自己的理解是有错误的,而且现在看来,这种错误的理解是很低级与SB的。

错误在哪里?
一句话:原型中的this不是指的原型对象,而是调用对象。

换个通俗的解释。Story是个儿子模板,Story.prototype是共同的爸爸。爸爸中的this并不是指的爸爸本人,而是未来某个new出来的儿子。

套上myStory相关代码解释就是:
myStory是个复制的儿子,老爸中的this指的就是这个儿子,因此当myStory.start();执行后,myStory多了个值为"doing"progress属性。 老爸还是老爸那个样子。

this.progress = "doing"; → myStory.progress = "doing";

想想也是这样啊:老爸肯定是不能变的,否则,复制出来的其他儿子岂不都跟着基因突变,残疾弱智之类。何来继承!

三、故事的结果

就跟电影电视剧一样,需要一点波折才好看(韩剧那种揪心来揪心去的就算了)。故事的结果是什么呢?一个小白,冲破了一道门槛,前方之路立马变得平坦。哈哈,喜剧,鼓掌鼓掌

所谓“平坦”指的是?
1. this的解释确实是那样
例如,对String原型扩展的一个过滤HTML代码方法:

String.prototype.stripHTML = function() {    return this.replace(/<(?:.|\s)*?>/g, "");};

显然,this指的是字符串本身的啦,怎么可能是原型呢!哈哈~~

2. 以前的一些迷糊开朗了
哦,原来jQuery中的继承以及包装器this也是这么个套路~~
jQuery继承以及this

原来,

var myArray = new Array();

也是这个套路,原本:

Array.prototype = { ... }

Array原型方法中的this实际上就是指的myArray啦,与上面的myStory一个套路。所以明白了,

Array.prototype.slice.call(arguments);

是个怎么回事了,argumentscallthis,指代为类似myArray的数组被返回,哈哈,明白啦,明白啦!

这就是我“邯郸学步”学出的一点东西。现在的我感觉就像是知道了张妹子其实就是个普通的妹子,不温不火,有时候生活可能比自己还苦逼,且圈子太复杂,很难遇到俺们这些根正苗红、品性纯良的好男人,唉,只能祝福了!


原文地址:http://www.zhangxinxu.com/wordpress/?p=2976





0 0
原创粉丝点击