对原型对象中this的一个认知--(转自张鑫旭)
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
等于这个对象本身①。
//zxx: ① 实际上this
并不能完全等同于story
。如下例子:
结果就是”unknown
“. //zxx: 此时window.progress为”start”;
story.progress = "start";
的结果则依然是:”start
“.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
也是这么个套路~~
原来,
var myArray = new Array();
也是这个套路,原本:
Array.prototype = { ... }
Array
原型方法中的this
实际上就是指的myArray
啦,与上面的myStory
一个套路。所以明白了,
Array.prototype.slice.call(arguments);
是个怎么回事了,arguments
被call
为this
,指代为类似myArray
的数组被返回,哈哈,明白啦,明白啦!
这就是我“邯郸学步”学出的一点东西。现在的我感觉就像是知道了张妹子其实就是个普通的妹子,不温不火,有时候生活可能比自己还苦逼,且圈子太复杂,很难遇到俺们这些根正苗红、品性纯良的好男人,唉,只能祝福了!
原文地址:http://www.zhangxinxu.com/wordpress/?p=2976