JavaScript函数面试题(一)

1.// 在javascript中,( )变量在函数外声明,并可从脚本的任意位置访问
// A.局部
// B.全局
// C.typeOf
// D.New

// JavaScript中的变量,分为局部变量和全局变量,局部变量:在函数中声明的变量只在该函数内部可见,而全局变量:在任何函数之外声明的变量,都为全局变量,而全局变量在任意函数中都是可见的。
// 3.typeof: typeof 操作符来检测变量的数据类型。
// 4.new:new是用来实例化一个对象的

// 2.
// for(var i = 0; i < 10; i++) {
// 	setTimeout((function(e) {
// 		return function( ) {
// 			console.log(e);
// 		}
// 	})(i), 1000)
// }

// 产生上述结果的原因主要是因为形成了闭包,同过自执行函数传递进来的变量相当于是在return的函数的作用域的上一级声明了一个局部变量e,当函数执行时,会一级一级的向上查找,当查找到上一级时的发现存在局部变量e,就不再向上查找了,因此返回的结果时0,1,2,3......

``


3.

// 下面有关JavaScript中 call和apply的描述,错误的是?
// A.apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入
// B.call与apply都属于Function.prototype的一个方法,所以每个function实例都有call、apply属性
// C.两者传递的参数不同,call函数第一个参数都是要传入给当前对象的对象,apply不是
// D.call传入的则是直接的参数列表。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。


// Call()方法和apply()方法的作用相同,他们的区别在于接收参数的方式不同。对于call(),第一个参数是this值没有变化,变化的是其余参数都直接传递给函数。(在使用call()方法时,传递给函数的参数必须逐个列举出来。使用apply()时,传递给函数的是参数数组)
// 4.JavaScript实现继承的方式,不正确的是:
// A.原型链继承
// B.构造函数继承
// C.组合继承
// D.关联继承


// JavaScript实现继承共6种方式:
// 原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承。

// 构造函数继承是每次继承都会把父类的所有属性方法全部拷贝一份,而对于公用的方法重复拷贝会浪费内存
// 原型链继承所有对象都公用一份原型属性和方法,对一个类的修改回影响的其他类
// 组合继承是结合两种继承方式,用构造函数方式继承属性,原型链方式继承方法
// 5.
//  var Product = {    
// count: 1,    
// getCount: function( ) {
// return this.count++;
// }
  
// };
  
// console.log(Product.getCount( ));
  
// var func = Product.getCount;
      
// console.log(func( ));

// 1 NaN
// 此时的this指向window,window.count++解析为undefined++,此时js会将undefined隐式转换为Number类型,所以结果为NaN
6.// var A = {n:4399};
// var B = function(){this.n = 9999};
// var C = function(){var n = 8888};
// B.prototype = A;
// C.prototype = A;
// var b = new B();
// var c = new C();
// A.n++;
// console.log(b.n);
// console.log(c.n);


// 在查找 b.n 是首先查找 b 对象自身有没有 n 属性,如果没有会去原型(prototype)上查找
// 当执行 var b = new B() 时,函数内部 this.n=9999(此时this指向b) 返回b对象,b对象有自身的n属性,所以返回 9999
// console.log(c.n);
// 同理
// 当执行 var c = new C() 时,c对象没有自身的n属性,向上查找,找到原型 (prototype)上的 n 属性,因为 A.n++(此时对象A中的n为4400), 所以返回4400
7.
var color = "blue";

function changeColor(){
  var anotherColor = "red";
  function swapColors(){
    var tempColor = anotherColor;
    anotherColor = color;
    color = tempColor;
    // 这里可以访问color、anotherColor 和t empColor
  }
  // 这里可以访问color and anotherColor,但不能访问 tempColor        
  swapColors();
}
changeColor();
// 这里可以访问color,但不能访问anotherColor 和 tempColor
console.log("Color is now " + color);  // Color is now red


以上代码共涉及3个执行环境:全局环境、changeColor()的局部环境和swapColors()的局部环境。全局环境中有一个变量color和一个函数changeColor()。changeColor()的局部环境中有一个名为anotherColor的变量和一个名为swapColors()的函数,但它也可以访问全局环境中的变量color。swapColors()的局部环境中有一个变量tempColor,该变量只能在这个环境中访问到。无论全局环境还是changeColor()的局部环境都无权访问tempColor。然而,在swapColors()内部则可以访问其他两个环境中的所有变量,因为那两个环境是它的父执行环境。


8.// 块级作用域
function a(){
  let b = 10;
  if (true) {
    let b = 20;
    console.log(b);  // 20
  }
  console.log(b);  // 10
}
a();

在以上代码中,分别用let在不同的花括号内声明了b,但是最终外层代码块不受内层代码块的影响。如果两次都使用var定义变量,则两个输出的值都是20
9.function SuperType(){
    this.colors = ["red", "blue", "green"];
}

function SubType(){            
}

// 继承了 SuperType
SubType.prototype = new SuperType();

var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors);    //"red,blue,green,black"

var instance2 = new SubType();
alert(instance2.colors);    //"red,blue,green,black"


SuperType构造函数定义了一个colors属性,SuperType的每个实例都会有各自包含自己数组的colors属性。当SubType通过原型链继承了SuperType之后,SubType.prototype就变成了SuperType的一个实例,因此它也拥有了一个它自己的colors属性 —— 就跟专门创建了一个SubType.prototype.colors属性一样。结果SubType的所有实例都会共享这一个colors属性。


10.var num = 1;
var myObject = {
  num: 2,
  add: function() {
    this.num = 3;
    (function() {
      console.log("第1个出现的console:" + this.num);
      this.num = 4;
    })();
    console.log("第2个出现的console:" + this.num);
  },
  sub: function() {
    console.log("第3个出现的console:" + this.num);
  }
};

myObject.add();
console.log("第4个出现的console:" + myObject.num);
console.log("第5个出现的console:" + num);
var sub = myObject.sub;
sub();

//第1个出现的console:1
//第2个出现的console:3
//第3个出现的console:4
//第4个出现的console:3
//第5个出现的console:4
myObject.add()里,第1个出现的console在立即执行函数里,根据上面提到过的,那么这个1.2所说,立即执行函数在myObject.add()里,this应该指向myObject。然而,立即执行函数中的this指向window,因为立即执行函数是window调用的,所以,第1个出现的console的值为1。

第1个出现的console执行完以后,this.num = 4,改变的是window中的值。所以第5个出现的console的值为4var sub = myObject.sub;,此时sub的环境也是window,所以第3个出现的console的值也是4

你可能感兴趣的:(JavaScript函数面试题(一))