javascript笔试题(1)

来源:互联网 发布:淘宝靠谱香水代购 编辑:程序博客网 时间:2024/06/03 14:53

在网上看到一波笔试题。感觉好几个都不会,特拿来研究一下。

题目一

(function(){   return typeof arguments; })();

结果:“object”

arguments是伪数组对象。虽然不是数组,但是可以使用方括号或数组索引来获取元素。

//可以转换成数组。Array.prototype.slice.call(arguments);

其实数组使用typeof返回的也是object

关于typeof:参见MDN typeof
另附instanceof:MDN instanceof

题目二

var f = function g(){ return 23; }; typeof g();

结果:报错

这叫函数表达式:

var f = function (){ return 23; }; 

这叫函数声明:

function g(){ return 23; }; 

那这个是什么?函数表达式还是函数声明??

var f = function g(){ return 23; }; 

这里有一个外国小牛牛的文章:http://kangax.github.io/nfe/

里面是这么说的:

We can see that when identifier is omitted, that “something” can only
be an expression. But what if identifier is present? How can one tell
whether it is a function declaration or a function expression — they
look identical after all? It appears that ECMAScript differentiates
between two based on a context. If a function foo(){} is part of, say,
assignment expression, it is considered a function expression. If, on
the other hand, function foo(){} is contained in a function body or in
a (top level of) program itself — it is parsed as a function
declaration.

如何界定它是函数表达式还是函数声明呢?ECMAScript界定它们使用的是上下文。

  • 如果 function foo(){}是一个赋值表达式的一部分,它就被认为是函数表达式。
  • 如果function foo(){}包含在一个函数体内或者在一个(最高等级的)程序里,就被解释为一个函数声明。
//函数声明 因为它是整个程序的一部分function foo(){} // declaration, since it's part of a <em>Program</em>//函数表达式 因为它是赋值表达式的一部分var bar = function foo(){}; // expression, since it's part of an <em>AssignmentExpression</em>//函数表达式  因为它是new表达式的一部分new function bar(){}; // expression, since it's part of a <em>NewExpression</em>//函数声明 因为它是一个函数体的一部分(function(){  function bar(){} // declaration, since it's part of a <em>FunctionBody</em>})();

现在明白了

var f = function g(){ return 23; }; 

这个表达式是一个函数表达式。没有函数提升,而且把函数的指针赋值给f。

更重要的是,函数的名字(g)只在函数内部有意义

var f = function g(){ console.log(typeof g); };    console.log(typeof f);    //下面这句话报错,g在函数外部没有意义   // console.log(typeof g);    f();

运行结果:function function

详细讨论见:汤姆大叔的深入理解javascript
函数名称在函数外面没有意义。

第三题

(function(x){   delete x;   return x; })(1);

运行结果:1

这里有一篇很不错的文章:delete的内部原理

我们知道,定义的函数和变量不能被delete删除,传入函数的arguments也不能被delete删除,而变量的属性可以被删除。

实际上,通过变量声明创建的全局对象,就会被解析成一个全局变量的属性,这个属性拥有一个特殊的属性DontDelete属性,是DontDelete这个属性让delete函数不能正确执行。

而,通过变量赋值没有变量声明的对象,会被解析成一个全局变量的属性,这个属性没有DontDelete属性,delete函数可以正确执行。

var GLOBAL_OBJECT = this;var foo = 1;GLOBAL_OBJECT.foo; // 1function bar() {};typeof GLOBAL_OBJECT.bar; // "function"GLOBAL_OBJECT.bar === bar; // true
var GLOBAL_OBJECT = this;/* 通过变量声明生成全局对象的属性,拥有DontDelete */var foo = 1;/* 通过未声明的变量赋值生成全局对象的属性,没有DontDelete */bar = 2;delete foo; // falsedelete bar; // true//注意:内部属性是在属性生成时确定的,之后的赋值过程不会改变已有的属性的内部属性。 理解这一区别是重要的。/* 'foo'创建的同时生成DontDelete */function foo() {};/* 之后的赋值过程不改变已有属性的内部属性,DontDelete仍然存在 */foo = 1;delete foo; // false;typeof foo; // "number"/* 但赋值一个不存在的属性时,创建了一个没有内部属性的属性,因此没有DontDelete */this.bar = 1;delete bar; // true;typeof bar; // "undefined"

属性的一个特殊的内部属性控制着该属性是否可以被删除。 注意:内建对象的一些属性拥有内部属性 DontDelete,因此不能被删除; 特殊的
arguments 变量(如我们所知的,活化对象的属性)拥有 DontDelete; 任何函数实例的 length
(返回形参长度)属性也拥有 DontDelete:

(function() {    //不能删除'arguments',因为有DontDelete    delete arguments; // false;    typeof arguments; // "object"    //也不能删除函数的length,因为有DontDelete    function f() {};    delete f.length; // false;    typeof f.length; // "number"}) ();

这就是为什么delete删除不了arguments啦。

第四题

var y = 1, x = y = typeof x; x;

结果:”undefined”

把上面的代码重写一下就是

var y=1;y=typeof x;//x未定义 y是undefinedx=yx

第五题

(function f(f){   return typeof f(); })(function(){ return 1; });

结果:”number”
代码重写一下:

var a=function(){ return 1; }(function f(f){     //a()返回1,即 return typeof 1;  return typeof a(); })(a);

注意:()里的函数都看作函数表达式而不是函数声明哦

第六题

var foo = {    bar: function() { return this.baz; },    baz: 1 }; (function(){    return typeof arguments[0](); })(foo.bar);

结果:”undefined”

让我们重写一下:

(function(){    return typeof arguments[0](); })(function() { return this.baz; });

再重写一下:

var a=function() { return this.baz; }(function(){    return typeof arguments[0](); })(a);

再写一下

 return typeof a(); 

a函数里return this.baz;的this是谁?
我们知道是arguments调用的a函数,上文我们也知道arguments在函数内部,作为函数内部一个变量的属性,那么是arguments调用了a,arguments没有属性baz,所以返回undefined。

那我测一下是不是真的是arguments喽

 var foo = {        bar: function ss() { return this;},        baz: 1    };    var a=function s(){        console.log(arguments);        console.log(arguments[0]()) ;    }    a(foo.bar);

结果:这里写图片描述
哈哈 console.log(arguments);console.log(arguments0) ;两只结果一模一样。

0 0
原创粉丝点击