Javascript笔试题汇总(一)

1.以下代码的输出是:
(function() {
    var x=foo();
    var foo=function foo() {
        return "foobar"
    };
    return x;
})();

A. foo()
B. 类型错误
C. undefined
D. foobar

答案:B
JS中变量声明、函数声明会提升,而函数表达式不会提升。上面的代码执行顺序是:var x; var foo; x=foo(); 执行到这里会因为foo为undefined而报错(foo is not a function)。如果是下面的代码就不会报错:

(function() {
    var x=foo();
    function foo() {
        return "foobar"
    };
    return x;
})();

2.下面哪些语句可以 在JS里判断一个对象oStringObject是否为String:

A. oStringObject instanceof String
B. typeof oStringObject == ‘string’
C. oStringObject is String
D. 以上答案都不正确

答案:A

var str1 = new String('js');
var str2 = 'js';
typeof str1; //object
typeof str2; //string
str1 instanceof String; //true
str2 instanceof String; //false

判断一个变量是否是字符串的周全的办法:

function isString(str){
    return (typeof str == 'string')||(str instanceof String)
}

因为本题中说的是一个对象oStringObject,那它一定是用String构造函数创建的对象,只能用instanceof。
需要注意的是用到instanceof时,关键字的左边一定是对象,如果是基本类型的话那么返回一定是false,因为基本类型的变量不可能属于任何类,例如上面代码中的str2。关键字的右边一定是类名,例如Object、String、Array、Date等等或是用户通过构造函数自定义的类,例如:

function Person(name){
    this.name = name;
}
var p = new Person();
p instanceof Person; //true

typeof运算符判断的是变量的数据类型。Js中的的数据类型有:undefined、null、string、number、boolean、object、(function)。使用typeof运算符返回的结果只有以上7中。function被作为一种特殊的object,会返回function。通过对象字面量、内建对象的构造函数、用户自定义的构造函数创建的对象都会返回object。

关于typeof和instanceof还有一个需要注意的是null,这是Javascript的历史遗留问题

typeof null; //object
null instanceof Object; //false

3.假设 output 是一个函数,输出一行文本。下面的语句输出结果是什么?
output(typeof (function() {
    output('Hello World!')
    })()
);

答案:Hello World undefined
typeof 立即执行函数 返回undefined哟


4.以下代码的运行结果:
var obj ={a:1,b:function () {alert(this.a)}}; 
var fun =obj.b; 
fun();

答案:undefined
以上代码这样看比较清晰:

var foo = function(){
    alert(this.a);
}
var obj ={a:1,b:foo}; 
var fun =obj.b; 
fun();

foo是一个独立的函数,fun和obj.b都是对foo的引用。在函数中调用this时要根据具体的上下文来输出,下面讨论几种上下文情况:

  • 全局调用,默认情况下执行foo(),此时的上下文是window。也就是代码中通过fun()调用。
  • 对象的属性方法调用,上下文是对象本身。也就是代码中通过obj.b()调用的情况。
  • call、apply调用,上下文是指定的对象。
  • 构造函数中调用,上下文是被创建的对象。

5.关于javascript的原始类型(primitive type),错误的是

A. 有5种primitive type,分别是Undefined、Null、Boolean、Number 和 String
B. var sTemp = “test string”; alert (typeof sTemp);结果为string
C. var oTemp;alert(oTemp == undefined)为true
D. alert(null == undefined);结果为false

答案:D

null == undefined; //true
null === undefined; //false

==和===的区别简单的总结以下:

  • 基本类型之间的比较

    1. 不同类型之间的比较:==会转化为相同类型后比较值是否相等,===因类型不同直接返回false
    2. 相同类型的比较:直接比较值是否相等,两者结果相同
  • 引用类型之间的比较

    1. 两者都比较地址是否相等
  • 基本类型与引用类型的比较

    1. ==将引用类型转化为基本类型后比较值是否相等,===因类型不同直接返回false

6.以下程序的运行结果:
function Foo(){
     var i=0;
     return function(){
         document.write(i++);
     }
}
var f1=Foo(),
f2=Foo();
f1();
f1();
f2();

答案:010
关于闭包的概念和作用就不解释了,这里想分析以下这两段代码(来自阮一峰博客):

代码1:
   var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
    alert(object.getNameFunc()());
代码2:
   var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()());

代码中object.getNameFunc()()取到的是getNameFunc的闭包。有一点需要明确:闭包中this的上下文是全局作用域,而不是object;object.getNameFunc()中的this的上下文才是object。

第一段代码中this.name取到的是window下的name,”This Window”。第二段代码中由于在getNameFunc中将this存储在that中,在闭包中就能访问到this.name。


7.下列描述中,关于 js 函数定义方式,正确的是:

A. function add(a,b){return a+b;} 函数表达式
B. var add = new Function('a','b','return a+b') 函数表达式
C. function add(a,b){return a+b;} 函数声明
D. var add = function(a,b){return a+b;} 函数声明
E. var add = new Function('a','b','return a+b') 函数声明

答案:C

//函数声明
function add(a,b){return a+b;} 
//函数表达式或函数字面量(函数本身为匿名函数,即使这里给了函数名的话也只能在函数内部通过函数名调用)
var add = function(a,b){return a+b;} 
//构造函数或函数对象(可以接受任意数量的参数,但最后一个始终被作为函数体)
var add = new Function('a','b','return a+b'); 

8.以下代码的输出结果是:
var f = function g() {
        return 23;
    };
typeof g();

A. number
B. undefined
C. function
D. 报错

答案:D
函数表达式中的函数名是可选的。如果具有函数名的话,那它相当于函数内部的一个变量,在函数外部是无法调用的,所以报错会提示ReferenceError:g is not a function

在函数表达式中使用命名函数的一个情况是函数递归,这样也可以避免使用非标准的arguments.callee属性。
被函数表达式赋值的变量一定会有name属性。name属性可以看作函数的名字,如果赋值的是匿名函数表达式时,name就是变量名;如果赋值的是命名函数表达式时,name就是函数名。


9.下列描述错误的是:

A. 在原型上扩展的可枚举方法,会被for in循环出来
B. 使用object.defineProperty可向对象添加或者修改属性
C. 每个对象都有prototype属性,返回对象类型原型的引用
D. 通过hasOwnProperty可判断一个对象以及其原型链上是否具有指定名称的属性
E. 原型链是JS实现继承的一种模型
F. For循环是按顺序的,for in循环是不一定按顺序的

答案:
关于for in和for of:
我们知道for in和for of最大的区别是:for in遍历的到的是keyfor of遍历的到的是value,因此更合理的做法是使用for in遍历对象,使用for of遍历数组。ES6中的for of功能很强大,能够遍历数组、字符串、Set、Map、NodeList和生成器。
除此之外,用for in遍历数字还有很多弊端:

  1. for in能够遍历包括原型上的所有可遍历的属性。
  2. 遍历不一定按照数组的内部顺序

ES6中提供了一种新的方法,可以轻松的获取对象的自有键:

var obj = {a:'a',b:'b'};
Object.keys(obj); //['a','b']

hasOwnProperty用于判断对象自身是否具有某属性
definePeoperty用于为对象添加或修改属性,这里可以对属性进行更多的配置。在大部分的mvvm框架中会使用这个方法来实现数据绑定。


10.如何判断一个js对象是否是Array。arr为要判断的对象,其中最准确的方法是?

A.typeof(arr)
B. arr instanceof Array
C. arr.toString==='[object Array]'
D. Object.prototype.toString.call(arr) === '[object Array]'

答案:D
arr instanceof Array返回true,但在跨frame对象构建的场景下会失效。
arr.toString是一个函数,调用toString将数组转换为字符串:

var arr = [1,2,3];
arr.toString() //"1,2,3"

Object.prototype.toString.call()可用于精确判断对象的类型,它会返回object和对象类型的组合:

Object.prototype.toString.call(123); //[object Number]
Object.prototype.toString.call('123'); //[object String]
Object.prototype.toString.call([1,2,3]); //[object Array]
Object.prototype.toString.call({}); //[object Object]
Object.prototype.toString.call(new Date()); //[object Date]
Object.prototype.toString.call(new Function()); //[object Function]

但无法判断用户自定义的对象类型,会统一判断为Object:

function Person(){}
Object.prototype.toString.call(new Person()); //[object Object]

你可能感兴趣的:(Javascript笔试题汇总(一))