最近看到这个题目,开始不太理解,但是仔细的看完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)();