this的分析分支

时间:2024-01-01 20:08:45

最近看到这个题目,开始不太理解,但是仔细的看完this之后,觉得懂了一些

function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);} //请写出以下输出结果:
Foo.getName(); //2
getName(); //4
Foo().getName();     //1
getName();         //1
new Foo.getName();    //2
new Foo().getName();    //3
new new Foo().getName(); //3

详细分析请看http://www.cnblogs.com/xxcanghai/p/5189353.html#3493461 

我主要说的是前四个:

首先我要说一下我们声明一个对象最常用的几种方式:

var person = new Object();
person.name = "bob";
person.sayName = function(){
console.info(this.name);
}
person.sayName ();//bob

  

var person = {
name:'bob',
sayName:function(){
console.info(this.name);
}
}
person.sayName();//bob

 

function Person(){
this.name="bob",
this.sayName=function(){
console.info(this.name);
}
}
var person1 = new Person();
person1.sayName();//bob

上面三种方法是很常用的,但是在总结之前我有点混淆了一个问题,就是增加实例属性的时候第一个位置是在函数里面通过this加,this.name= 'bob';或者通过对象实例来加,比如person1.old=12;在Person上直接声明没作用,比如Person.grade=3,这样没什么作用,只是相当于写了一个函数表达式,不影响这个对象。

第1问:就是执行一个函数表达式,与其他无关,所以是2;

第2问:这里执行了一个函数,但是我们会发现函数声明了一次,函数表达式又写了一次,这时候就涉及到函数声明提升的问题了,当不执行代码的时候就会把函数声明的放到最开始,这时候在后面表达式覆盖了一次,所以就执行了函数表达式的4

第3问:这里首先执行了一个函数,我们会发现这里的getName是全局变量,重新赋值了一次,return中的this是window,就相当于window.getName(),所以执行了覆盖后的getName,结果是1

var a= 1;
function aa(){
a=10,
console.info(this)
};
console.info(a); //1
aa(); //window
console.info(a); //10

上面这段小代码更简单的解释了这个关系。 

第4问:和3一模一样

第5问:和第一个一样,只是new了一个对象,

第6问:相当于(new Foo()).getName(),构造函数中的return this;其实就是new出来的对象,所以就是执行对象上的方法,在实例上找不到,就到原型上去找,结果是3

这块也有一个知识点,很容易被忘记,构造函数中没有返回值,实例化后则相当于返回实例化对象,如果返回值是非引用类型,则返回的还是实例化对象;返回值是引用对象则返回那个对象。本题中返回的是this,就是那个实例对象的引用,所以返回实例对象。

第7问:new ((new Foo()).getName)();