前端面试宝典

1、

//考是否细心的题
const res = [];
for(var i = 0 ; i < 5; i++);{
     
	res.push(i+1);
}
console.log(res); // 3

/*
	解析:
	在上面代码中,for循环语句之后添加了一个分号,在js中,会判定这个语句已结束,因此可以知道for循环执行了四次空的语句,当退出循环时,
	此时的i值为5,然后执行 {res.push(i+1);},因此最终输出为 6
*/

2、可参考MDN的运算符优先级

/*包含变量提升,this指向,运算符优先级,原型,继承,全局变量污染、对象属性、原型属性优先级*/
 function Foo() {
     
     getName = function() {
     
         alert(1);
     };
     return this;  //此处this指向了window对象,this指向window对象,Foo函数返回的是window对象,相当于执行window.getName()
 }
 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
 console.log(Foo())
 Foo().getName(); //1
 getName(); //1 
 
 new Foo.getName(); //2  //将getName函数作为了构造函数来执行,执行之后弹出2
 new Foo().getName(); //3
 new new Foo().getName(); //3  初始化Foo函数的实例化对象,之后将其原型上的getName函数作为构造函数再一次new,所以最终结果为3
 
 /*
 解析:
     第一问:Foo.getName 访问的是 Foo 函数存储的静态属性。所以弹出 2

     第二问:直接调用,就会访问当前上文的作用域当中,名为 getName的函数,而在上面代码中,
     存在一个函数声明和一个函数表达式,函数声明存在函数提升
     而函数表达式在这里将函数声明给覆盖了,所以弹出 4
     
     第三问:首先执行了 Foo 函数,然后调用其返回值对象的 getName 属性函数,无 var 声明,所以先向当前 Foo 函数作用域内寻找 getName 变量但并
     没有找到,就会向当前的函数作用域上层找是否有 getName 变量,找到了alert(4)函数,将此变量赋值给 function(){alert(1)},将外层的
     作用域内 getName 函数修改了,window中的getName已经被修改为alert(1),所以执行结果为1
     
     第四问:会直接调用getName函数,相当于window.getName(),Foo函数执行后把全局的getName函数给修改了,
     所以结果就是Foo()执行修改之后的getName函数,执行结果为 1

	 第五问:点的优先级比new无参数时优先级高,但new Foo.getName() <==> new (Foo.getName)();这样就变为了new有参数了,而函数调用()优先级低,
	 所以弹出2
 */

注意点:

  • 对象的私有方法和属性,外部不能访问
  • 静态方法和静态属性不需要去实例化,就能调用
  • 而公有方法和属性,就必须要先实例化之后才可以去调用
  • 同时注意公有方法不能去调用静态方法和私有属性

你可能感兴趣的:(JavaScript)