javaScript基础面试题 ---this指向+原型的考题

function Foo() { 
	getName = function () {
		console.log(1) 
	}
	return this;
}

Foo.getName = function(){console.log(2)}
Foo.prototype.getName = function () { console.log(3)}
var getName = function () { console.log(4) }
function getName() { 
	console.log(5)
}

Foo().getName();//1
getName();//1

结果为1,1

我一开始也觉得离谱,懂了之后就恍然大悟

解析:
1、首先是Foo().getName();这句
拆开来看,先执行Foo()
Foo干了什么事呢?
getName = function () {console.log(1) }
注意这个getName前面没有var,所以这是个全局变量,window下的
然后Foo return了this,这个普通函数的this指向的是window
所以这句话也可以是window.getName()
window.getName()原来是打印4,但是被Foo的1覆盖了,所以是1
2、getName();这句
还是window下的getName,还是1


把题稍微改下,还是上面那个题,最后调用函数那两句换成一下:

Foo.getName();//2
getName();//4

输出就是2,4

分析:
Foo.getName()在上面定义好了就是2,也没有被覆盖,因为Foo没有小括号,所以Foo没被调用
下面的getName直接就是4,也没有被覆盖


再把题目稍微改下,还是上面的题,最后调用函数改成:

new Foo().getName();//3

分析:
原型链查找顺序:现在自身查找 -> 构造函数上找 -> 对象原型中找 -> 对象的上一层原型中找
Foo()函数里面的getName = function () {console.log(1)}前面没有this,所以它还是个全局变量,没有挂的元素构造函数Foo()上,所以要去函数原型上找,原型上的是3,所以输出3


接下来看一个新的题:

var o = {
    a:10,
    b:{
        fn:function () { 
            console.log( this.a )
            console.log( this )
         }
    }
}
o.b.fn()

输出为:
undefined
{ fn: [Function: fn] }

分析:
1、 console.log( this.a )分析
b是一个对象,fn是b里面的函数
fn里面的函数是指向拥有它的对象的,也就是b
但是b里面没有a,所以是undefined
如果b里面有a,那么就打印b里面的a
2、console.log( this )分析
this指向的就是b,b里面就是{ fn: [Function: fn] }


function Foo(){
  getName = function(){
      console.log(1);
  };      
  return this;
}                                          
Foo.getName = function(){
  console.log(2);
};  
Foo.prototype.getName = function(){
  console.log(3);
};          
var getName = function(){
  console.log(4);
};              
function getName(){
  console.log(5);
}
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();

这个题的答案是: 2 4 1 1 2 3 3

,1、首先是Foo.getName();
答案是2,第二个函数,后面也没有什么能覆盖它的,就是2了

2、getName();
不是4就是5,最后一个函数使用的是函数声明的方式,倒数第二个函数使用的是声明变量的方式,声明变量>函数声明,所以两者共存的时候,优先使用声明变量,所以不是5而是4

3、Foo().getName();
注意第一个函数里面的getName前面没有var ,所以是window下的getName,普通函数内部的this指向的就说window,所以这个调用也等同于window.getName(),刚好是1。还有个疑问,window下的,那为什么不是4或者5呢?本来全局作用域下的应该是4的,不是5,说了变量声明>函数声明,但是调用了this.getName()之后,全局getName就被覆盖成1了

4、getName();
这里还是1,刚刚说被覆盖了

5、new Foo.getName();
实际上是new (Foo).getName(),在new Foo的时候,Foo没有getName方法,所以直接调用Foo上的静态方法,结果为2

6、new Foo().getName();
带()的会继承原型链上的方法,5中不带括号的不继承原型链,所以直接输出2,这里直接输出3
new Foo.getName();
这个表达式等同于 (new Foo).getName();。这里,new Foo 创建了一个新的 Foo 实例,但是,我们并没有调用该实例上的 getName 方法。实际上,我们正在访问 Foo 函数上的静态方法 getName,因此我们直接调用了 Foo.getName,输出 2。
new Foo().getName();
在这个表达式中,我们首先使用 new Foo() 创建了一个新的 Foo 实例。这个实例从 Foo.prototype 继承了 getName 方法。因此,当我们调用 new Foo().getName(); 时,我们实际上调用了从 Foo.prototype 继承的 getName 方法,输出 3。

你可能感兴趣的:(前端JS面试题,javascript,前端,开发语言)