前两天刷到一个公众号里面的js基础面试题,觉得很有用处便做了以下记录,如果想要了解完整版的内容可以去该公众号查看。前端程序员经常忽视的一个JavaScript面试题
//定义了一个叫Foo的函数
function Foo() {
// 函数赋值语句,注意它没有var声明,所以先向当前Foo函数作用域内寻找getName变量,没有。再向当前函数作用域上层,即外层作用域内寻找是否含有getName变量,找到了,也就是第二问中的console.log(4)函数,将此变量的值赋值为function(){console.log(1)}。此处实际上是将外层作用域内的getName函数修改了。
getName = function() {
console.log(1);
};
return this;
}
//为Foo创建了一个叫getName的静态属性存储了一个匿名函数
Foo.getName = function() {
console.log(2);
};
//为Foo的原型对象新创建了一个叫getName的匿名函数
Foo.prototype.getName = function() {
console.log(3);
};
//函数变量表达式:创建了一个getName的函数
var getName = function() {
console.log(4);
}; //用函数表达式创建的函数是在运行时进行赋值,且要等到表达式赋值完成后才能调用,函数表达式此时才开始覆盖函数声明的定义
//函数声明:声明一个叫getName函数————函数声明会被提升到作用域的最前面,即使写代码的时候是写在最后面,也还是会被提升至最前面
function getName() {
console.log(5);
}
//访问Foo函数上存储的静态属性 2
Foo.getName();
//此处其实有两个坑:一是变量声明提升,二是函数表达式和函数声明的区别 4
//可参考**第二段代码**
getName();
//先执行了Foo函数,然后调用Foo函数的返回值对象的getName属性函数 1
Foo().getName();
// 1
getName();
//将getName函数作为了构造函数来执行 2
new Foo.getName();
//如果是function Foo() {this.getName,输出1 3
//可参考**第三段代码**
new Foo().getName();
//如果是function Foo() {this.getName,输出1 3
new new Foo().getName();
var name = "111";
console.log(name); ///111
window.name = "222";
console.log(name); ///222
function getName() {
name = "333";
return function() {
return name;
}
};
console.log(name); ///222
getName();
console.log(name) ///333
function Foo() {
//有无this差别很大
getName = function() {
return 222
};
this.getName = function() {
return 111
};
}
Foo.prototype.name = 'Oaoafly';
Foo.prototype.getName = function() {
return 'Oaoafly'
}
console.log(new Foo().name) //Oaoafly
console.log(new Foo().getName()) //111