【转】外国朋友出的js题目,你能对几道
原文地址 http://perfectionkills.com/javascript-quiz/
中文地址加解释:by Aaron:http://www.cnblogs.com/aaronjs/p/3172112.html
附带了自己的理解,答案有争议的地方欢迎大家指出
题目一
|
2
3
4
|
(function(){ return typeof arguments; })(); |
"object"
arguments是对象,伪数组有两件事要注意这里:
参数不是数组,它是一个数组一样的物体,你可以使用方括号和整数索引的元素,但方法通常可在一个如推上不存在参数数组
Array.prototype.slice.call(arguments); 转成数组
当然arguments即使是数组,返回的依然是"object",因为数组也是对象,附加:typeof 对类型的判断
https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Operators/typeof
题目二
|
2
3
|
var f = function g(){ return 23; }; typeof g(); |
会发生错误
因为function g(){ return 23; }是函数表达式,事实上只有事一个名字,不是一个函数声明
函数实际上是绑定到变量f,不是g.
指定的标识符在函数表达式虽然有其用途:堆栈跟踪是清晰而不是充斥着无名的函数,你可以有一个匿名函数递归调用本身不使用argument.callee
附非常详细的帖子函数表达式
http://kangax.github.io/nfe/
题目三
|
2
3
4
5
|
(function(x){ delete x; return x; })(1); |
1
参数不可删除
见我发过的帖子(js中的delete定义)
http://www.cnblogs.com/aaronjs/articles/3148934.html
国外的帖子(理解删除)
http://perfectionkills.com/understanding-delete/
题目四
|
2
3
|
var y = 1, x = y = typeof x; x; |
"undefined"
通过重写代码如下结果:
var a, b; 展开就是 var a; var b;.
A = B = C;相当于 B = C = B; 知道了这一点,我们重写并得到:
var y = 1;
y = typeof x;
var x = y;
x; 当执行
y = typeof x时,x 还没有被定义,所以y成为字符串"undefined",然后被分配到x
题目五
|
2
3
4
|
(function f(f){ return typeof f(); })(function(){ return 1; }); |
"number"
为了便于理解我们继续分解: 第一部分
var baz = function(){ return 1; }; 第二部分
(function f(f){
return typeof f();
})(baz); 在这里,函数f接受一个参数是另一个函数,f函数内部执行这个实参函数并且返回类型
无论是从调用该函数返回,即使参数名称f与函数名冲突,函数接受本身作为自己的参数,然后调用,此时就看谁更具有更高的优先级了,显然,参数的优先级更高,所以实际执行的是returntypeof 1
题目六

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

"undefined"
为什么是"undefined"?.
我们必须要知道this运算符是怎么工作的. JS语言精粹总结的很精炼:
1 纯粹的函数调用
2 作为对象方法的调用
3 作为构造函数调用
4 apply调用 我们看看题目是属于那种环境?
在arguments[0]()中执行了一个方法,arguments[0]就是foo.bar方法
注意:这在foo.bar中的this是没有绑定到foo 虽然 foo.bar 传递给了函数,但是真正执行的时候,函数 bar 的上下文环境是 arguments ,并不是 foo
arguemnts[0] 可以理解为 arguments.0(不过写代码就不要这样了,语法会错误的),所以这样看来,上下文环境是 arguemnts 就没问题了,所以在执行baz的时候自然this就是window了,window 上没有baz属性,返回的就是undefined, typeof调用的话就转换成"undefined"了 附上博文
http://www.cnblogs.com/aaronjs/archive/2011/09/02/2164009.html MDC
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/this_Operator#Description
题目七
var foo = {
bar: function(){ return this.baz; },
baz: 1
}
typeof (f = foo.bar)();
"undefined"
继续改写一下:
var foo = {
bar: function(){ return this.baz; },
baz: 1
} f = foo.bar; typeof f(); 把foo.bar存储给f然后调用,所以this在foo.bar引用的是全局对象,所以就没有baz属性了
换句话说
foo.bar执行的时候上下文是 foo,但是当 把 foo.bar 赋值给 f 的时候,f 的上下文环境是 window ,是没有 baz 的,所以是 ”undefined"
题目八
var f = (function f(){ return "1"; }, function g(){ return 2; })();
typeof f;
"number" 逗号操作符的使用可以很混淆,但这段说明它的行为:
var x = (1, 2, 3);
x; x的值是3,这表明,当你有一系列的组合在一起,并由逗号分隔的表达式,它们从左到右进行计算,但只有最后一个表达式的结果保存。由于同样的原因,这个问题可以改写为减少混乱: var f = (function g(){ return 2; })();
typeof f; 关于逗号表达式:
原文:
http://www.2ality.com/2012/09/expressions-vs-statements.html
译文:
http://www.cnblogs.com/ziyunfei/archive/2012/09/16/2687589.html
题目九
var x = 1;
if (function f(){}) {
x += typeof f;
}
x;
"1undefined"
这里有个难点
if 中的 function f(){} 要如何处理? 函数声明的实际规则如下: 函数声明只能出现在程序或函数体内。从句法上讲,它们 不能出现在Block(块)({ ... })中,例如不能出现在 if、while 或 for 语句中。因为 Block(块) 中只能包含Statement语句, 而不能包含函数声明这样的源元素。另一方面,仔细看一看规则也会发现,唯一可能让表达式出现在Block(块)中情形,就是让它作为表达式语句的一部分。但是,规范明确规定了表达式语句不能以关键字function开头。而这实际上就是说,函数表达式同样也不能出现在Statement语句或Block(块)中(因为Block(块)就是由Statement语句构成的)。 假设代码我们不妨变一下: var x = 1;
if (function(){}) {
x += typeof f;
}
x; var x = 1;
x += typeof f;
x; f在这了没有被定义,所以typeof f 是字符串"undefined" ,字符与数字相加结果也是一个字符串,
所以最后的x就是"1undefined"了
题目十
(function f(){
function f(){ return 1; }
return f();
function f(){ return 2; }
})();
2
如果是一直看下来的话,这个题目应该是比较简单
简单的来说在执行return之前,函数声明会在任何表达式被解析和求值之前先被解析和求值,
即使你的声明在代码的最后一行,它也会在同作用域内第一个表达式之前被解析/求值,
参考如下例子,函数fn是在alert之后声明的,但是在alert执行的时候,fn已经有定义了 alert(fn()); function fn() {
return 'Hello world!';
} 所以题目中函数提升了两次,第二次把第一次覆盖了,
所以 return 后面的 f 是 return 语句的下一条语句声明的函数 f 。
注意自执行函数 (function f (){})(); 中的 f 并没有函数提升效果,它是表达式
题目十一
function f(){ return f; }
new f() instanceof f;
false
怎样去理解?
new f()
首先这个操作会创建一个新对象并调用构造函数函数这一新的对象作为它的当前上下文对象
简单的说 new f();
依稀记得高级程序设计里面是这么说的:
1 创建空对象。
2 将类的prototype中的属性和方法复制到实例中。
3 将第一步创建的空对象做为类的参数调用类的构造函数
默认如果没有覆盖这个空对象的话,返回this var a = new Object;
a instanceof Object 为 true 我们在看 f() 返回了 return f; 那么也就是说这个新的对象是是自身,构造函数本身在 new 的过程中会返回一个表示该对象的实例。
但是函数的返回值覆盖了这个实例,这个new 就形同虚设
果f的形式为 function f(){return this}或function f(){}就不一样
var a = new f();
a instanceof f // false 值得注意的是 instanceof 检测的是原型 又附上我博客的
JS 对象机制深剖——new 运算符
http://www.cnblogs.com/aaronjs/archive/2012/07/04/2575570.html
题目十二
var x = [typeof x, typeof y][1];
typeof typeof x;
答案
这题目比较简单,注意下返回类型即可
x = [,][1];
即 x = typeof y = 'undefind'.
typeof 返回的是string类型就可以了
typeof typeof必然就是'string'了.
题目十三
function(foo){
return typeof foo.bar;
})({ foo: { bar: 1 } });
"undefined"
又是一个恶心的题目,纯文字游戏,大家看仔细看 先分解一下 var baz = { foo: { bar: 1 } }; (function(foo){
return typeof foo.bar;
})(baz); 去掉函数关联
var baz = { foo: { bar: 1 } };
var foo = baz;
typeof foo.bar; 最后,通过替代我们除去中间变量foo
var baz = { foo: { bar: 1 } };
typeof baz.bar; 所以现在就很清晰了,属性中没有定义baz;它被定义为baz.foo上了,所以结果是:”undefined"
题目十四
with (function(x, undefined){}) length;
2
with用得很少,with 语句就是用于暂修改作用域链的或者通常用来缩短特定情形下必须写的代码量 使用with语句的JavaScript代码很难优化,因此它的运算速度比不使用with语句的等价代码要慢得多。 而且,在with语句中的函数定义和变量初始化可能会产生令人惊讶的、相抵触的行为,因此我们避免使用with语句 with的用法是这样的:
with(object) {},在大括号里面,可以引用object的属性而不用使用object.attr这种形式。
这道题里面,with接受了一个对象,只不过这个对象是函数,函数有length属性,
代表形参的个数,所以上面返回的值是2 mozilla with
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Statements:with
如果是原创文章,转载请注明出处!!!
【转】外国朋友出的js题目,你能对几道的更多相关文章
- Atitti 跨语言异常的转换抛出 java js
Atitti 跨语言异常的转换抛出 java js 异常的转换,直接反序列化为json对象e对象即可.. Js.没有完整的e机制,可以参考java的实现一个stack层次机制的e对象即可.. 抛出Ru ...
- Eclipse的Jar包解压出System.js里String与Boolean定义分号可有可无吗?
Eclipse的Jar包解压出System.js里String与Boolean定义分号可有可无吗? org.eclipse.wst.jsdt.core_1.3.300.v201410221502\li ...
- 包学会之浅入浅出Vue.js:结业篇(转)
蔡述雄,现腾讯用户体验设计部QQ空间高级UI工程师.智图图片优化系统首席工程师,曾参与<众妙之门>书籍的翻译工作.目前专注前端图片优化与新技术的探研. 在第一篇<包学会之浅入浅出Vu ...
- 包学会之浅入浅出Vue.js:升学篇
包学会之浅入浅出Vue.js:升学篇 蔡述雄,现腾讯用户体验设计部QQ空间高级UI工程师.智图图片优化系统首席工程师,曾参与<众妙之门>书籍的翻译工作.目前专注前端图片优化与新技术的探研. ...
- 包学会之浅入浅出Vue.js:开学篇(转)
包学会之浅入浅出Vue.js:开学篇 蔡述雄,现腾讯用户体验设计部QQ空间高级UI工程师.智图图片优化系统首席工程师,曾参与<众妙之门>书籍的翻译工作.目前专注前端图片优化与新技术的探研. ...
- 包学会之浅入浅出Vue.js:结业篇
在第一篇<包学会之浅入浅出Vue.js:开学篇>和上一篇<包学会之浅入浅出Vue.js:升学篇>的学习中,我们首先了解了Vue环境的搭建以及两个重要思想——路由和组件的学习,通 ...
- 一道原生js题目引发的思考(鼠标停留区块计时)
我瞎逛个啥论坛,发现了一个题目,于是本着练手的心态就开始写起来了,于是各种问题接踵而至,收获不小. 题目是这样的: Demo: mouseenter与mouseover区别demo 跨浏览器的区块计数 ...
- 前端弹出对话框 js实现 ajax交互
原本计划实现这样一个需求: 前台点击触发某业务动作,需要用户补充信息,不做跳转页面,弹窗的形式进行补充信息. 折腾出来了,但是最终没有用到. 代码还有些毛躁,提供大概实现逻辑. 实现思路: 在窗口铺上 ...
- 织梦建站:视频弹出播放JS+CSS
需要 jquery.js 文件,JS代码一定要放在HTM下面,否则没效果罗! CSS代码: 1.fdspbf{ width:650px; height:550px; position:fixed; l ...
随机推荐
- 3D空间中射线与三角形的交叉检测算法【转】
引言 射线Ray,在3D图形学中有很多重要的应用.比如,pick操作就是使用射线Ray来实现的,还有诸如子弹射线的碰撞检测等等都可以使用射线Ray来完成.所以,在本次博客中,将会简单的像大家介绍下,如 ...
- 转载:R语言Data Frame数据框常用操作
Data Frame一般被翻译为数据框,感觉就像是R中的表,由行和列组成,与Matrix不同的是,每个列可以是不同的数据类型,而Matrix是必须相同的. Data Frame每一列有列名,每一行也可 ...
- 用注册表禁止windows添加新用户
运行 regedt32.exe 打开你的注册表,里面有一个目录树:打开其中目录 HKEY_LOCAL_MACHINE再打开其中目录 SAM再打开其中目录 SAM再打开其中目录 Domains再打开其中 ...
- vs2017使用rdlc
写在前面:因为公司要求做个批量打印工具,以前用Delphi+FastReport开发的,现在因为公司就剩下一个Delphi开发工程师了,还外出,所以这是就落在我身上.因为这个打印工具不需要使用人员设计 ...
- VS版本与系统不兼容问题
1.VS2012在win7 64位系统安装快结束时报出一个不兼容的错误. 2.这种情况官方给出解决方法: http://www.microsoft.com/en-us/download/details ...
- 先装VS2008之后,又装了2013,然后启动VS2008提示“Tools Version”有问题?
这个网上资料一搜很多,我就是按照下面这个链接去解决的,删除 “14.0” 整个键值文件夹之后重启VS2008就好了, 注意:上面第一张图是我在网上找的08和10版本弹出的错误,我自己弹出的是提示14. ...
- Python初学手记----在window系统中安装环境
官网地址: https://www.python.org/ Win版下载地址:https://www.python.org/downloads/windows/ 安装注意:安装路径推荐修改. path ...
- 附2 volatile
注:在阅读本章之前,先要了解Java内存模型,见上一章<附1 Java内存模型与共享变量可见性>,链接如下: http://www.cnblogs.com/java-zhao/p/5124 ...
- AJPFX的资金安全性
AJPFX承诺保证客户资金安全,并严格按照英国的相关规章制度从事经营活动.客户资金存放于投资级银行的独立账户中.通过实行公司资产与客户资金分别保管,在发生无偿债能力的罕见情况下,客户可获退还独立存放资 ...
- Restframework 渲染器 render 组件实例-4
渲染器默认存放位置: 在默认配置下 default-settings里 (APIVIEW点击去--> 1. renderer_classes = api_settings.DEFAULT_REN ...