javascript一道小题

版权声明:本文为博主原创文章,未经博主允许不得转载。

 

前言

刚刚有个小伙伴发了一个js小题,很有意思,下面我们一起来看一下,研究研究:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var A = (function classA() {
var self;
function A(name) {
if (!self) {
self = this;
}
self.name = name;
}
A.prototype.say = function() {
document.write(this.name + ":" + name + "<br>");
}
return A;
})();
var a = new A("A");
var b = new A("B");
a.say();
b.say();
console.log(a == b);

如上代码,现在让我们来分析一下代码运行步骤,上面的声明就不一一赘述了:
首先这个自执行函数执行后,此时的A就是函数A,下面运行分别实例化A传入“A”,“B”,我们先看看传入“A”都执行什么。

内部判断self由于上面声明了一个self,这时的self就是undefined,这是一个闭包,所以非就是true进入判断self = this 之后给对象添加属性name,值为传入的值“A”。第一步完毕。

我们再来看第二步,第二步实例化A传入“B”,判断self这时的self的指针已经指向了第一步实例化的a(很重要),所以此时的name属性不是给b赋值而是覆盖刚刚传入的值,此时self.name = "B"

第三步,这时a开始调用构造函数的say方法输出this.name与name,this.name上面有叙述此时的值为B,name呢?大家觉得name应该是什么值呢!“A”或者“B”?如果你是这么想的,那你就错了,此时的name可和传入的值没有关系,可能很多人都不知道window有一个属相叫name,是一个空值。对,没错,这里的name就是window的属性值name,window.name是一个空值所以此时得到的就是 B:

1
p.s这里小小的科普一下window.name可以用于跨域,之后会写篇文章,讲解一下。

第四步,这是b又调用了say方法同样的输出应该输出什么呢?刚才我们提到两次实例化其实都是给a的name属性赋值,并没有b,都是这个self搞得鬼,把this的自动指向保存起来了(不清楚的可以看看前面的文章call apply),所以这时b的name属性并没有任何值,b的name属性为undefined,name依然是window.name空值,所以此时得到的就是undefined:

第五步 console.log(a == b) //false 这个在我前面的文章值得传递引用有讲,两个不同空间的对象不相等,就算是属性,值都相等也是fasle

好了就到这里吧,本文仅表个人简介,如有错误,请大神不吝赐教!