第86题 下面这道题输出什么
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()
```**答案**
不要去读代码内部的东西,只是定义而已,而是要模拟执行代码(把自己当成`JS`引擎去执行)执行到再去看函数内部的东西
```js
2
4
1
1
2
3
3
解析

本题考察:
- 声明提前,
function(){}整体提前,var 变量 = xx仅var 变量声明提前,= xx函数执行在赋值 - 任何函数都是普通对象,都可以添加自己的属性
- 任何函数都可以当做构造函数被
new调用,且任何函数都有原型对象prototype属性,只不过大部分函数不是标准的构造函数内容而已
function Foo(){
// getName没有声明会在window全局自动创建getName变量
getName = function(){
console.log(1)
}
// new Foo的过程中如果返回了对象,则以返回的对象为准
/**new的实现过程
* function myNew(fn, ...args) {
// 基于原型链 创建一个新对象,继承构造函数的原型对象(Person.prototype)上的属性
let newObj = Object.create(fn.prototype);
// 添加属性到新对象上 并获取obj函数的结果
// 调用构造函数,将this调换为新对象,通过强行赋值的方式为新对象添加属性
let res = fn.apply(newObj, args); // 改变this指向新创建的对象
// 如果函数的执行结果有返回值并且是一个对象, 返回执行的结果, 否则, 返回新创建的对象地址
return typeof res === 'object' ? res: newObj;
}
*/
return this
}
// 函数也是对象,也可以在对象上添加属性getName
Foo.getName = function(){
console.log(2)
}
Foo.prototype.getName = function(){
console.log(3)
}
// var getName变量会被function声明给覆盖,函数执行的时候getName会重新赋值为{console.log(4)}
var getName = function(){
console.log(4)
}
// 声明会提前,函数声明优先于变量声明
function getName(){
console.log(5)
}
Foo.getName() // 调用Foo上的方法,返回2
getName() // 4
Foo().getName() // getName={console.log(1)} 此时Foo内部this指向window,调用全局的getName方法,返回1
getName() // 1
// new 函数() 任何函数都可以放到new后面,new要找到离它最近的一个()
new Foo.getName() // 调用Foo上的方法,返回2
new Foo().getName() // 调用Foo()返回值是this,在调用this上的getName() 调用Foo原型上的方法 ,返回3
new new Foo().getName() // 返回3
