面试题目
考点:变量,函数提升,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()
getName()
Foo().getName()
getName()
new Foo.getName()
new Foo().getName()
new new Foo().getName()
打印结果:
2
4
1
1
2
3
3
进行变量,函数提升
变量提升文章参见GO
- 变量提升GOgetName = undefined
- 函数提升,与变量同名,替换掉变量的 即GOgetName = undefined function getName(){ console.log(5) }
- 执行到下面代码时候,又会替换GO内的getName
var getName = function () {
console.log(4)
}
GO
getName =undefined
function getName(){ console.log(5) }
function () { console.log(4) }
变量提升分析结束
开始执行
按顺序一句一句分析
Foo.getName() //2
不要与原型上的方法概念混淆,原型上的方法是实例对象的,这里是构造函数,后面会涉及原型
getName() //4
此时执行全局的getName,打印4
Foo().getName() //1
执行Foo,发现里面有变量getName,没有经过var声明的变量,暗示全局变量,通过原型链查找得知,全局上有个getName函数,此时又替换全局上的function ,如下 GO
getName =undefined
function getName(){ console.log(5) }
function () { console.log(4) }
function (){ console.log(1) }
替换结束后,又return this,此处的this指的是window,此时Foo().getName()等同于window.getName(),结果打印1
如果Foo这个构造函数里面的getName有通过 var 定义,则此时打印的结果为4,即没有替换全局下的方法,并通过window调用
getName() //1
经过上述变化,全局的getName现在已经变成1了
new Foo.getName() // 2
执行顺序,.
号优先级最高,然后(),最后new,所以 new (Foo.getName)() 执行Foo.getName()方法打印2,并创建实例对象,不过没有使用
new Foo().getName() //3
虽然.
的优先级更高,但是前面的()无法使.调用,所有会先执行new,结果供给.去调用 (new Foo()).getName() --> 实例对象.getName()
实例对象会顺着原型链(__porto__
)向上进行查找,找到Foo.prototype.getName,所以打印3
new new Foo().getName()//3
执行顺序:new ((new Foo()).getName)() ,与上面同理,(new Foo()).getName() --> 实例对象.getName()
最后再一次new是创建一个实例对象,没有使用
总结
涉及到的考点有:变量,函数提升,this指向,原型,优先级
题目及解释参考自某学习视频,欢迎勘误,不胜感激
更多学习内容,可以关注我的个人公众号
![ccc814eac0f33bc96bc19277faef6ed8.png](https://i-blog.csdnimg.cn/blog_migrate/37662c61161e6dc6f9464af74d83c53a.png)