Interesting JavaScript

作者:ManfredHu
链接:http://www.manfredhu.com/2016/07/07/20-interestingJavascript
声明:版权所有,转载请保留本段信息,否则请不要转载

1.声明提升

写出下面代码的运行结果

    var a,b;
    (function(){
        console.log(a);
        console.log(b);
        var a=b=3;
        console.log(a);
        console.log(b);
    })();
    console.log(a);
    console.log(b);

A. undefined,undefined,3,3,undefined,3
B. undefined,undefined,3,3,undefined,undefined
C. 0,0,3,3,undefined,undefined
D. undefined,undefined,3,3,0,0

正确答案:A
解释:代码相当于下面这样的过程

    var a,b;
    (function(){
        var a;
        console.log(a); //undefined
        console.log(b); //undefined
        a=3;
        b=3;
        console.log(a); //3
        console.log(b); //3
    })();
    console.log(a); //undefined
    console.log(b); //3

2.变量定义规则

下面符合一个有效的javascript变量定义规则的是?

A. _

t2
B. with
C. a bc
D. 2a

正确答案: A
考点:ECMAScript语法
解析:with为关键字,空格不行,数字开头的不行

3.document.getElementById和document.getElementsByTagName

JavaScript中document.getElementById的返回值的类型和document.getElementsByTagName的返回值类型分别是?

A. Array,NodeList
B. Object, HTMLCollection
C. String,NodeList
D. Function,NodeList

正确答案: B
解析:这题可能有争议,浏览器测试代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Id与TagName类型检测</title>
</head>
<body>
    <div id="test"></div>
    <script type="text/javascript">
        function checkType(element){
            console.log(Object.prototype.toString.call(element));
        }
        checkType(document.getElementById(‘test‘)); //[object HTMLDivElement]
        checkType(document.getElementsByTagName(‘div‘)); //[object HTMLCollection]
    </script>
</body>
</html>

4.if/var

下面关于块内函数的做法哪些是正确的?
A. if(x){ function foo(){}}
B. if(x){ var function foo(){}}
C. if(x){ foo = function(){}}
D. ECMAScript明确的规范了块级函数,JavaScript实现了这个规范

正确答案:B
解析:测试报错

5.hasOwnProperty

下列代码

    var obj={}
    ……
    obj.hasOwnProperty("val");

中hasOwnProperty的作用是?
A. 判断obj对象是否具有val的属性
B. 判断obj对象是否具有val的值
C. 判断obj的原型对象是否具有val的属性
D. 判断obj的原型对象是否具有val的值

正确答案:A
解析:hasOwnProperty()函数用于指示一个对象自身(不包括原型链)是否具有指定名称的属性。如果有,返回true,否则返回false

6.call和apply

下面有关JavaScript中 call和apply的描述,错误的是?

A. call和apply都属于Function.prototype的方法,所以每个function实例都有call,apply属性
B. 两者传递的参数不一样,call函数第一个参数都是传入给当前对象的对象,apply不是
C. apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入
D. call传入的则是直接的参数列表。call方法可将一个函数的对象上下问从出事的上下文改变为thisObj指定的新对象。

正确答案:B
解析:applycall都是改变函数内部this指向的方法,挂载在Function.prototype

7.script标签

(不定项选择题)给网页添加javascript的方式有

A. 使用script标签,将JavaScript代码写到<script></script>之间
B. 添加外部javascript文件
C. 使用行内javascript
D. 使用@import引入javascript文件

正确答案:A,B,C
解析:只有CSS可以用@import方法,题目其实可以换成CSS,则全部正确

给网页添加css的方式有
A. 使用style标签,将JavaScript代码写到<style></style>之间
B. 添加外部css文件
C. 使用行内css
D. 使用@import引入css文件

8.parseInt与map

[“1”, “2”, “3”].map(parseInt)的输出结果是
A. [1,NaN,NaN]
B. [1,2,3]
C. [NaN,NaN,NaN]
D. 发生错误

正确答案: A. [1,NaN,NaN]
解析:

  • Array.prototype.map(func(currentValue, index, arrary),thisObj)
    map接受两个参数, 一个回调函数 callback, 一个回调函数的this值。其中回调函数接受三个参数 currentValue, index, arrary
  • parseInt 只接受两个两个参数 string, radix(基数).基数。该值介于 2 ~ 36 之间,如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。如果为0,则直接输出字符串

如下的例子来看this的运用和基数的例子:

var obj = {
    value:1
};
["1", "2", "3"].map(function(currentValue, index, arrary){
    console.log(this); //输出3次obj
},obj);

console.log(parseInt(‘1‘, 0)); //1
console.log(parseInt(‘123‘, 0)); //123
console.log(parseInt(‘2‘, 1)); //NaN
console.log(parseInt(‘3‘, 2)); //NaN

["1", "2", "3"].map(parseInt)的时候,传入parseInt的参数为currentValue,index

9.Function.prototype.name

function foo() { }
var oldName = foo.name;
foo.name = "bar";
console.log([oldName, foo.name]);

A. [‘foo’,’bar’]
B. [‘foo’,’foo’]
C. [‘bar’,’bar’]
D. [‘bar’,’foo’]

答案:B.[‘foo’,’foo’];

函数的name属性指向函数名,挂载在Function.prototype下,所以不要给函数赋值属性name哈。并且这个属性是不可改变的.

所以下面这样的例子就不要出现了

function foo() {}
foo.name = "bar"; //bad,你居然真忘了Function.prototype.name是一个不可修改的属性!!

测试代码:

console.log(Function.prototype.hasOwnProperty(‘name‘)); //true

10.正则test方法的参数问题

var lowerCaseOnly =  /^[a-z]+$/;
[lowerCaseOnly.test(null), lowerCaseOnly.test()]

A. false, true
B. false,true
C. true,true
D. true,false
答案: C.true, true

如题所示,test方法如果参数为null或者不屑,则默认返回true

11.变量作用域

写出这段代码的运行结果

<SCRIPT type="text/javascript">
    var bb = 1;
    function aa(bb) {
        bb = 2;
        console.log(bb);
    };
    aa(bb);
    console.log(bb);
</SCRIPT>

正确答案: 2 1

12.+-操作符

如下代码输出的结果是什么:

console.log(1+ "2"+"2");
console.log(1+ +"2"+"2");
console.log("A"- "B"+"2");
console.log("A"- "B"+2);

正确答案:
122 //数字与字符串+则数字默认转换为字符串
32 //+号会将字符串2先转化为数字,这种也是常用的将字符串转换为数字的方式
NaN 2
NaN

解析:插播——常见的将字符串转换为数字的方法:

  1. parseInt,具体使用请看前面第8题
  2. +"123" 类似这种写法,比如某个参数不确定是不是数字可以这样 +data.len
  3. Number方法

从带宽(精简压缩后)考虑会用第二种,所以通常会在代码上大量看到这种写法

13.null和Object的关系

[typeof null, null instanceof Object]的输出结果是

正确答案:object, false
解析:
null为一个空的对象,这个对象存在但是里面一点东西都没有,相当于有堆空间但是里面没有属性。而undefined可以理解为连堆空间都没有(至少表现出来是这样的不是吗?)
null instanceof Objectfalse是因为null连属性都没有,更没有检测原型链的_proto_prototype了。

14.+运算符优先于?:运算符

var val = ‘smtg’;
console.log(‘Value is ’ + (val === ‘smtg’) ? ‘Something’ : ‘Nothing’);
正确答案: ‘Something’

15.变量作用域

写出下面代码的执行效果
var name = ‘World!‘;
(function () {
    if (typeof name === ‘undefined‘) {
        var name = ‘Jack‘;
        console.log(‘Goodbye ‘ + name);
    } else {
        console.log(‘Hello ‘ + name);
    }
})();

正确答案: Goodbye Jack

编译语法分析后代码(声明提升)如下

var name = ‘World!‘;
(function () {
    var name;
    if (typeof name === ‘undefined‘) {
        name = ‘Jack‘;
        console.log(‘Goodbye ‘ + name); //Goodbye Jack
    } else {
        console.log(‘Hello ‘ + name);
    }
})();

16.

写出下面题的答案

    var END = Math.pow(2, 53);
    var START = END - 100;
    var count = 0;
    for (var i = START; i <= END; i++) {
        count++;
    }
    console.log(count);

正确答案:不会输出,因为END是最大值了,
解析:在 JS 里, Math.pow(2, 53) == 9007199254740992 是可以表示的最大值. 最大值加一还是最大值. 所以循环不会停

17.浮点数的不准确性

输出0.1+0.2 === 0.3的结果,并简单地解释。
解析:经典的题目,浮点数因为存在误差,所以不能用===判定,通常在金额处理的时候会乘以10/100倍来小数部分的数据

18.正则表达式replace的高级用法

写出答案

"1 2 3".replace(/\d/g, parseInt)

答案:1, NaN, 3
解析:replace() 方法的参数第二个参数可以是函数而不是字符串。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。

1.该函数的第一个参数是匹配模式的字符串
2.接下来的参数是与模式中的子表达式匹配的字符串,可以有 0 个或多个这样的参数
3.接下来的参数是一个整数,声明了匹配在 stringObject 中出现的位置
4.最后一个参数是 stringObject 本身。

题目中因为没有子表达式匹配,即()括起来的匹配项,所以传入parseInt的参数三次分别为:

parseInt("1", 0) //1,因为当基数为0时候直接输出第一个参数
parseInt("2",2) //NaN,因为2进制只有01两个数字
parseInt("3",4) //3,因为不超过四进制的最大值4

19.getPrototypeOf根据proto获取类型

    function f() {}
    var a = f.prototype, b = Object.getPrototypeOf(f);
    console.log(a === b);

答案:false
解析如下:

function f() {}
var a = f.prototype; //Object
var c = new f();
var b = Object.getPrototypeOf(f); //function
var d = Object.getPrototypeOf(c); //Obejct
console.log(a === b); //false
console.log(d === a); //true

函数的原型是一个对象,而函数的原型会是函数,对象的原型会是对象
题目这里就是让你混淆普通函数的原型到底是什么?函数还是对象?
答案是函数,因为普通函数的_proto_指向的是Function.prototype,所以Object.getPrototypeOf拿到的是function

你可以狠狠戳这里去看我以前写的15条规则解析JavaScript对象布局

这里应该可以看的很清楚了,函数FooprototypeFoo.prototype
Object.getPrototypeOf拿的是_proto_指向的Function.prototype,所以输出的是一个function
而普通对象,如图的o1,o2_proto_指向的是Object.prototype

20.[,]和join

[,,,].join(", ")

答案: “, , ”
解析:

[,,,].lenth //3
[,,,].join(‘-‘) //--

所以这题很明显了,三个逗号默认忽略最后一个,然后用’-‘会在两项中间添加连接符

21.Function.length和new Function.length

var a = Function.length,
    b = new Function(1,‘2234‘).length;
console.log(a === b);

答案 false
解析:a为1,b为0,不相等

22.Math.min()和Math.max()在没有参数时候的奇葩情况

var min = Math.min(), max = Math.max()
min < max

答案;false
解析:min为Infinity,b为-Infinity,结果是min > max

min() 方法可返回指定的数字中带有最低值的数字。
Math.min(x,y) 如果没有参数,则返回 Infinity。如果有某个参数为 NaN,或是不能转换成数字的非数字值,则返回 NaN。

max() 方法可返回两个指定的数中带有较大的值的那个数。
Math.max(x…) 如果没有参数,则返回 -Infinity。如果有某个参数为 NaN,或是不能转换成数字的非数字值,则返回 NaN。

23.闭包

    function aa() {
        console.log("aaa");
        return function(){
            console.log("bbb");
        };
    }
    console.log(aa);
    console.log(aa());
    console.log(aa()());

答案:

function aa() {
    console.log("aaa");
    return function(){console.log("bbb");};
}
aaa
function(){console.log("bbb");};
aaa
bbb
undefined

第一个输出aa的函数体,大家都懂
第二个执行了aa(),输出文本"aaa",同时返回了里面的匿名函数
第三个在第二步的基础上执行了匿名函数,最后再输出一个bbb,最后因为执行函数没有返回值,返回了undefined

24.类数组(array like)

类数组对象是什么?说一下你知道的JavaScript里面类数组对象有哪些,类数组怎么转化为数组?

类数组: 指向对象元素的数字索引下标以及 length 属性告诉我们对象的元素个数,但是不具有诸如 pushforEach 以及 indexOf 等数组对象具有的方法
常见例子: DOM方法 document.getElementsByClassName() 的返回结果(实际上许多DOM方法的返回值都是类数组)以及特殊变量 arguments

所以通常要有一个转换的过程,借助 Array.prototype.slice 可以实现:

Array.prototype.slice.call(arguments) //arguments转化为普通数组

25.构造函数与静态方法

写出下面代码输出的结果并写出你的解题思路?

    function Foo() {
        getName = function () { console.log (1); };
        return this;
    }
    Foo.getName = function () { console.log (2);};
    Foo.prototype.getName = function () { console.log (3);};
    var getName = function () { console.log (4);};
    function getName() { console.log (5);}

    //请写出以下输出结果:
    Foo.getName();
    getName();
    Foo().getName();
    getName();
    new Foo.getName();
    new Foo().getName();
    new new Foo().getName();

答案:

    Foo.getName();//2
    getName();//4
    Foo().getName();//1
    getName();//1
    new Foo.getName();//2
    new Foo().getName();//3
    new new Foo().getName();//3

26.典型闭包

下面代码的运行结果是?

<html>
<head>
    <meta charset="utf-8">
    <title>DOM进阶</title>
    <script type="text/javascript">
    window.onload=function(){
            var buttons=document.getElementsByName(‘button1‘);
              for(var i=0;i<buttons.length;i++){
                    buttons[i].onclick=function(){
                        console.log(i);
                    };
              }
    };
    </script>
</head>
<body >
    <input type="button" name="button1" value="按钮1" />
    <input type="button" name="button1" value="按钮2" />
    <input type="button" name="button1" value="按钮3" />
    <input type="button" name="button1" value="按钮4" />
    <input type="button" name="button1" value="按钮5" />
</body>
</html>

这个错新手估计会犯,当初的我也是。
闭包,点那个按钮都是输出 buttons.length 的值,这里是5

时间: 2024-08-02 11:02:55

Interesting JavaScript的相关文章

Vue.js小案例(2)

即时搜索 这个例子主要应用了vue.js的自定义过滤器,可以通过Vue.filter()注册一个全局过滤器,具体用法可以参考这里,vue.js也提供了一些内置过滤器. CSS代码: [v-cloak] { display: none; } *{ margin:0; padding:0; } body{ font-family:Microsoft YaHei; text-align:center; } li{ list-style:none; } .bar{ background-color:#5

【前端】Vue.js实现网格列表布局转换

网格列表布局转换 实现效果: 实现代码及注释: <!DOCTYPE html> <html> <head> <title>布局转换</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-e

使用javascript完成一个简单工厂设计模式。

在JS中创建对象会习惯的使用new关键字和类构造函数(也是可以用对象字面量). 工厂模式就是一种有助于消除两个类依赖性的模式. 工厂模式分为简单工厂模式和复杂工厂模式,这篇主要讲简单工厂模式. 简单工厂模式:使用一个类来生成实例. 复杂工厂模式:使用子类来决定一个成员变量应该是哪个具体的类的实例. 简单工厂模式: 常用对象方法创建和调用 var BallShop = function(){}; BallShop.prototype = { sellBall : function(model){

【温故而知新-Javascript】使用 Document 对象

Document 对象时通往DOM功能的入口,它向你提供了当前文档的信息,以及一组可供探索.导航.搜索或操作结构与内容的功能. 我们通过全局变量document访问Document对象,它是浏览器为我们创建的关键对象之一.Document对象提供了文档的整体信息,并让你能够访问模型里的各个对象.简单示例如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>

The Modern JavaScript Developer’s Toolbox

The Modern JavaScript Developer’s Toolbox Posted by David Haney on Mar 09, 2015 The Web Platform has gone a long way since HTML5 was first made popular and people started looking into JavaScript as a language that could do build complex apps. Many AP

如何成为一个javascript高手【转载】

原文网址: http://www.cnblogs.com/keva/p/how-to-become-a-javascript-badass.html 英文网址:http://www.clientcide.com/deep-thoughts/how-to-become-a-javascript-badass/ 上周我写了一篇相当漫长的文章,感叹要找到一个有天分的前端开发人员是相当具有挑战性的.这篇文章引起了一些评论和电子邮件形式的讨论,我不只是想要在这里抱怨这种客观事实而是想要对该现状发表一下个人

JavaScript constructors, prototypes, and the `new` keyword

Are you baffled(阻碍:使迷惑) by the new operator in JavaScript? Wonder what the difference between a function and a constructor is? Or what the heck a prototype is used for? I’m going to lay it out straight. Now, there’s been a lot of talk for a long time

Learning JavaScript Design Patterns The Observer Pattern

The Observer Pattern The Observer is a design pattern where an object (known as a subject) maintains a list of objects depending on it (observers), automatically notifying them of any changes to state. When a subject needs to notify observers about s

JavaScript Patterns 2.11 Writing Comments

Document all functions, their arguments and return values, and also any interesting or unusual algorithm or technique. Think of the comments as hints to the future readers of the code; the readers need to understand what your code does without readin