JavaScriptの你问我答( 更新中......)

一些js的问题与解析

1) ["1","2","3"].map(parseInt);的运行结果是?

A.["1","2","3"]
B.[1,2,3]
C.[0,1,2]
D.其他

分析:

D

map对数组的每个元素调用定义的回调函数并返回包含结果的数组。["1","2","3"].map(parseInt)对于数组中每个元素调用paresInt。但是该题目不同于:

function testFuc(a){
        return parseInt(a);
}
console.info(["1","2","3"].map(testFuc));

题目等同于:

function testFuc(a,x){
        return parseInt(a,x);
}
console.info(["1","2","3"].map(testFuc));

map中回调函数的语法如下所示:function callbackfn(value, index, array1),可使用最多三个参数来声明回调函数。第一参数value,数组元素的值;第二个参数index,数组元素的数组所以;array1,包含该元素的数组对象。 因此,题目等同于[parseInt(1,0),parseInt(2,1),parseInt(3,2)] 最终返回[1, NaN, NaN].

parseInt():

parseInt(string, radix);接受两个参数stringradix

string

需要解析的一串‘类数字’string。

(The value to parse. If string is not a string, then it is converted to one. Leading whitespace in the string is ignored.)

radix

解析string的基数设置,可取值范围在2~36之间[闭区间]。

(An integer between 2 and 36 that represents the radix (the base in mathematical numeral systems) of the above mentioned string. Specify 10 for the decimal numeral system commonly used by humans. Always specify this parameter to eliminate reader confusion and to guarantee predictable behavior. Different implementations produce different results when a radix is not specified.)

从parseInt的定义中可以得出一个方便的理解,parseInt的第一个参数一定要小于第二个参数,当然它们都是数字的String的比较。否则结果就是NaN。

一个意外:当radix取值为0的时候,相当于默认的parseInt(string)而没有radix.eg:


parseInt(1,0);//相当于parseInt(1); ->1
parseInt(0123,0);//相当于parseInt(0123); ->83

2) [typeof null, null instanceof Object]的运行结果是?

A.["object",false]
B.[null,false]
C.["object",true]
D.其他

分析

A

typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果:

number,boolean,string,function(函数),object(NULL,数组,对象),undefined。

instanceof 表示某个变量是否是某个对象的实例,null是个特殊的Object类型的值 ,表示空引用的意思 。但null返回object这个其实是最初JavaScript的实现的一个错误, 然后被ECMAScript沿用了,成为了现在的标准,不过我们把null可以理解为尚未存在的对象的占位符,这样就不矛盾了 ,虽然这是一种“辩解”。
对于我们开发人员 还是要警惕这种“语言特性”。最终返回:["object", false]

3) [[3,2,1].reduce(Math.pow),[].reduce(Math.pow)]的运行结果是?

A.报错
B.[9,0]
C.[9,NaN]
D.[9,undefined]

分析

A

pow() 方法可返回 x 的 y 次幂的值。[3,2,1].reduce(Math.pow);等同于:


function testFuc(x,y){
        console.info(x +" : "+y);
        return Math.pow(x,y);
}
console.info([3,2,1].reduce(testFuc));

执行Math.pow(3,2)Math.pow(9,1)[].reduce(Math.pow),等同于执行Math.pow();会导致错误。

这里要介绍下arr.reduce(callback[, initialValue])

国际惯例,官方解释:

Parameters

allback
      Function to execute on each value in the array, taking four arguments:
      previousValue
         The value previously returned in the last invocation of the callback,
         or initialValue, if supplied.
      currentValue
         The current element being processed in the array.
      index
         The index of the current element being processed in the array.
      array
         The array reduce was called upon.

initialValue
      Optional. Object to use as the first argument to the first call of the callback.

4) 以下代码的运行结果是:


var name = ‘World‘;
(function(){
    if(typeof name === ‘undefined‘){
      var name = "Jack";
      console.info(‘Goodbye ‘+ name);
    }else{
      console.info(‘Hello ‘ + name);
    }
})();
A.Goodbye Jack
B.Hello Jack
C.Goodbye undefined
D.Hello undefined

分析

A

js函数内有个叫做【声明提前】的东西。故选A。

5) 以下代码的运行结果是:


var arr = [0,1,2];
arr[10] = 10;
arr.filter(function(x){return x === undefined});

A.[undefined x 7]
B.[0,1,2,10]
C.[]
D.[undefined]

分析

C

filter会接触到没有被赋值的元素,即在arr中,长度为10但实际数值元素列表为[0, 1, 2, 10],因此,最终返回一个空的数组[]

又有机会解释js函数了哈arr.filter(callback[, thisArg])

国际惯例,官方解释:

Parameters callback Function to test each element of the array. Invoked with arguments (element, index, array). Return true to keep the element, false otherwise. thisArg Optional. Value to use as this when executing callback.

简单的来。就是filter返回arr中callback(value)结果为true的值。over

6) 以下代码运行结果是:


var two = 0.2;
var one = 0.1;
var eight = 0.8;
var six = 0.6;
[two -one == one,eight- six == two];
A.[true,true]
B.[false,false]
C.[true,false]
D.其他

分析

C

两个浮点数相加或者相减,将会导致一定的正常的数据转换造成的精度丢失问题eight-six = 0.20000000000000007。 JavaScript中的小数采用的是双精度(64位)表示的,由三部分组成: 符 + 阶码 + 尾数,在十进制中的 1/10,在十进制中可以简单写为 0.1 ,但在二进制中,他得写成:0.0001100110011001100110011001100110011001100110011001…..(后面全是 1001 循环)。因为浮点数只有52位有效数字,从第53位开始,就舍入了。这样就造成了“浮点数精度损失”问题。

更严谨的做法是(eight-six ).totoFiexd(1)或者用用Math.round方法回归整数运算。判断两个浮点数是否相等,还是建议用逼近的比较,比如if((a-b) < 1E-10)

值得注意的是,0.2-0.1却是==0.1的。

7) 以下代码运行的结果是:


function showCase(value){
      switch(value){
           case ‘A‘:
                 console.info(‘Case A‘);
                 break;
            case ‘B‘:
                 console.info(‘Case B‘);
                 break;
            case undefined :
                 console.info(‘undefined‘);
                 break;
            default:
                 console.info(‘Do not know!‘);
     }
}
showCase(new String(‘A‘));
A.Case A
B.Case B
C.Do not know
D.undefined

分析

C

使用new String()使用构造函数调用讲一个全新的对象作为this变量的值,并且隐式返回这个新对象作为调用的结果,因此showCase()接收的参数为String {0: "A"}为不是我们所认为的“A”

但是,其实显然,此时的new String(‘A‘) == ‘A‘;虽然new出来的是个String对象。

var a = new String(‘A‘);
                    //->a == String {0: "A", length: 1, [[PrimitiveValue]]: "A"}
a == ‘A‘;       //-> true

从上面我们可以知道,即使把题中的showCase(new String(‘A‘));改为var a = new String(‘A‘);showCase(a);,它传进去的依然是个String{0:‘A‘...}对象。结果依然是C。

8) 以下表达式的运行结果是:


Array.isArray(Array.prototype)
A.true
B.false
C.报错
D.其他

分析

A

Array.prototype为[],Array.isArray(a)是一个判断a是否为数组的方法。 判断对象是否为数组的方法:

  • 1)ES5函数isArray(),该函数测试对象的内部[[Class]]属性是否为Array: Arrray.isArray(a);
  • 2)判断对象的构造函数是否为Array: a.constructor === Array
  • 3)使用对象内部[[Class]]属性创建结果字符串: Object.prototype.toString.call(a)
  • 4)使用instanceof操作符测试对象是否继承自Array: (但由于,一个页面的iframe不会继承自另外一个页面的iframe,该方法不可靠) a instanceof Array

9) [] == [] 的运行结果是:

A.true
B.false
C.报错
D.其他

分析

B

数组,在 Javascript 中是对象,对象使用 == 比较都是比较的引用。简单的说,就是,如果是同一个对象,就相等,如果不是同一个对象,就不等。每次使用 [] 都是新建一个数组对象,所以 [] == [] 这个语句里建了两个数据对象,它们不等。

那么问题来了,如何判断两个数组相等呢?

lodash中用_.isEqual(value, other, [customizer], [thisArg])来比较即可。

10) [3.toString(),3..toString(),3...toString()]的运行结果是:

A.["3",error,error]
B.["3","3.0",error]
C.[error,"3",error]
D.其他

分析

C

Number中的toString(a)能够将数值转化成为a进制的值。但a缺省时,默认转化为十进制,一般使用方法为:


var n = 3;
n.toString();

执行3.toString(),因为3只是为数值型变量,为非Number实例,因此对于3不能直接调用Number方法。而执行3..toString(),会强制将3转化为数字实例,因此能够被解释,输出‘3‘,同样可以使用(3).toString()

11) 列举IE和FF脚本兼容性的问题:

分析

列举IE和FF脚本兼容性的问题

  • (1)window.event 表示当前的事件对象,IE有这个对象,FF没有
  • (2)获取事件源 IE用srcElement获取事件源,而FF用target获取事件源
  • (3)添加、移除事件
             IE:element.attachEvent("onclick",function)
                 element.detachEvent("onclick",function)
             FF: element.addEventListener("click",function,true)
                 element.removeEventListener("click",function,true)
    

11) 以下函数有什么问题?如何改进?

    
        function initButtons(){
            var body = document.body,button,i;
            for(i =0;i<5;i++){
                button = document.createElement("button");
                button.innerHTML = "Button" + i;
                button.addEventListener("click",function(e){
                    alert(i);
                },false);
                body.appendChild(button);
            }
        }
        initButtons();
    

分析

题目所给出的代码,除了有addEventListener不兼容IE浏览器的问题之外,最突出的一个问题是:

虽然在页面上会显示值为button+i的按钮,但是点击任意一个按钮,最终都会显示5。 要想点击相关按钮,弹出相应的1,2,3,4,5的值,需要理解闭包原理实现和使用立即回调函数。修改后的代码如下:


    function initButtons(){
        var body = document.body,button,i;
        for(i =0;i<5;i++){
            (function(i){
                button = document.createElement("button");
                button.innerHTML = "Button" + i;
                button.addEventListener("click",function(e){
                    alert(i);
                },false);
                body.appendChild(button);
            })(i);
        }
    }
    initButtons();

涉及绑定和赋值得到区别。在运行时,进入一个作用域,javascript会为每一个绑定到该作用域的变量在内存中分配一个“槽”(slot)。 函数中,创建变量document.body,button,i,因此当函数体(创建按钮,并为按钮绑定事件)被调用时,函数会为每个变量分配一个“槽”。 在循环的每次迭代中,循环体都会为嵌套函数分配一个闭包。我们可能理解为,该函数存储的是嵌套函数创建时变量i的值。 但事实上,他存储的是i的引用。由于每次函数创建后变量i的值都发生变化,因此函数内部最终看到的是变量i的引用。闭包存储的是外部变量的引用而非值。 立即调用的函数表达式,是一种不可或缺的解决javascript缺少块级作用域的方法。

如此这样,我们就要来说一下js中的闭包了啊。

闭包

鉴于这个篇幅可能有点长,放另外一个Closures文件中。

12) 写一段代码,判断一个字符串中出现次数最多的字符,并统计出现的次数。

分析


    /*写一段代码。判断一个字符串中出现次数最多的字符串,并统计出现的次数*/

    //常规方法
    function toGetTheMostCharsByArray(s){
        var r={};
        for(var i=0;i< s.length;i++){

            if(!r[s[i]]){
                r[s[i]] = 1;
            }else{
                r[s[i]]++;
            }
        }
        var max = {
            "value": s[0],
            "num": r[s[0]]
        };

        for(var n in r){
            if(r[n]>max.num){
                max.num = r[n];
                max.value = n;
            }
        }
        return max;
    }
    //使用正则方法
    function toGetTheMostCharsByRegex(s){
        var a = s.split(‘‘);
        a.sort();
        s = a.join(‘‘);
        var regex = /(\w)\1+/g ; // \1+代表重复的
        var max = {
            "value" :s[0],
            "num" :  0
        };

        s.replace(regex,function(a,b){//a是重复的string:eg:‘aaa‘,b是重复的字母char:eg:‘a‘;
            if(max.num < a.length){
                max.num = a.length;
                max.value= b;
            }
        });
        return max;
    }
    var test = "efdfssssfrhth";
    console.info("使用常规方法,出现最多的字符串为:"+toGetTheMostCharsByArray(test).value+" ,出现次数:"+toGetTheMostCharsByArray(test).num);
    console.info("使用字符串匹配,出现最多的字符串为:"+toGetTheMostCharsByRegex(test).value+" ,出现次数:"+toGetTheMostCharsByRegex(test).num);

注意这里的正则判断重复字母,先留个位置为介绍正则......

13) 请问一下两段代码有什么不同?


    //1.
    setTimeout(function(){
        /*代码块*/
        setTimeout(arguments.callee,10);
    },10);

    //2.
    setInterval(function(){
        /*代码块*/
    },10);

分析

javascript的引擎是单线程的

javascript的引擎是基于事件驱动的

setTimeout和setInterval都是往事件队列中增加一个待处理时间而已,setTimeout只触发一次,而setInterval是循环触发


    setTimeout(function(){
        //代码块
        setTimeout(arguments.callee,10);
    },10);
    //上段代码可使得setTimeout循环触发。但是,执行完这段代码块才挂起时间,所以两次执行时间会大于10ms

    setInterval(function(){
     /*代码块*/
    },10);
    //而上段代码,是自动在10ms的时候挂上这个事件,所以两次事件的相隔会小于等于10ms。

当线程阻塞在一个事件的时候,不管是使用setInterval还是setTimeout都需要等待当前事件处理完才能执行。

由这个问题,我们引入下面这个话题:

使用console进行性能测试计算代码运行时间

14)以下代码弹出的是?


    alert(1&&2);

分析

a && b : 若a为真,返回b,若a为假,返回a。故弹出2.

同理,|| 前面为假取后,前面为真取前。

时间: 2024-10-09 12:11:13

JavaScriptの你问我答( 更新中......)的相关文章

[问与答]Python 中 __all__ 的作用 ?

你要是看Python的源码或者相关框架的源码,总是在 __init__.py 或者是源文件的开头看到一个 __all__ 变量的定义,今天就说说它的作用. orangleliu 问题出处 Can someone explain all in Python? 问题 我越来越多的使用Python了,经常看到 __all__ 变量再各种 __init__.py 文件中,谁能解释为什么那么做呢? 解答 它是一个string元素组成的list变量,定义了当你使用 from <module> import

我觉得有意思的JavaScript题目(01-05更新中)

对于以下js题目均来至于网络中.有的来至于文章之中,有的也许来至于问答题型中. 如果你有更好的问题解释,请留言交流! 1.相关问题描述:到底该怎么去理解闭包? 代码片段A: !function(){ var num=1; var exp={}; functionadd(num){ return num++; } exp.getAddNum=function(){ return add(num); } window.a=exp; }() console.log(a.getAddNum()); //

【前端】Util.js-ES6实现的常用100多个javaScript简短函数封装合集(持续更新中)

Util.js (持续更新中...) 项目地址: https://github.com/dragonir/Util.js 项目描述 Util.js 是对常用函数的封装,方便在实际项目中使用,主要内容包含:数组类.浏览器类.日期类.函数类.数学类.媒体类.节点类.对象类.字符串类.类型检测类.正则表达式类等内容. 使用方法 1. 引入Bable transpiler以保证支持ES6 <script type="javascript/text" src="./browser

Android开发面试经——4.常见Android进阶笔试题(更新中...)

Android开发(29)  版权声明:本文为寻梦-finddreams原创文章,请关注:http://blog.csdn.net/finddreams 关注finddreams博客:http://blog.csdn.net/finddreams/article/details/44301359 上一篇文章我们已经了解了Android笔试的一些基础题目, [<Android开发面试经——2.常见Android基础笔试题> ] (http://blog.csdn.net/finddreams/a

OpenGL快问快答

OpenGL快问快答 本文内容主要来自对(http://www.opengl.org/wiki/FAQ)的翻译,随机加入了本人的观点.与原文相比,章节未必完整,含义未必雷同,顺序未必一致.仅供参考. 我写这个是为了加深印象,好记性不如烂笔头,好记星不如烂键盘. +BIT祝威+悄悄在此留下版了个权的信息说: 名词术语 渲染:等于"画",等于"draw". OpenGL是什么? OpenGL是Open Graphics Library(开源图形库)的缩写.它是一本说明书

k3 Bos开发百问百答

          K/3 BOS开发百问百答   (版本:V1.1)           K3产品市场部       目录 一.基础资料篇__ 1 [摘要]bos基础资料的显示问题_ 1 [摘要]单据自定义无法看到bos定义的基础资料_ 1 [摘要]在调出基础资料序时簿时,过滤出我需要的基础资料_ 1 [摘要]bos定义的基础资料能否做到按名称而不是按代码进行自动匹配_ 1 二.业务单据篇__ 2 [摘要]是否支持多插件和数据授权_ 2 [摘要]K3BOS单据(新)中的数量字段怎样才能控制到两

PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)

PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++:      欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/problem-sets/994805046380707840/problems 目录 (点击对应题目即可进入相应题解--小声BB--) L1-001 Hello World (5 分) L1-002 打印沙漏 (20 分) L1-003 个位数统计 (15 分) L1-004 计算摄氏温度 (5

Vue.js 一问一答

Vue.js 一问一答 记录一下在学习 Vue 过程中给自己问的一些问题,持续更新中... Vue.js 的核心是什么? 官网:Vue.js 的核心是一个允许采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统. 以下面的例子来说明: // Vue 中的模板语法 <div id="app"> {{message}} </div> var app = new Vue({ el: "#app", data: { message: "

真问真答:中国人为何蔑称朝鲜人“棒子”|大象公会

真问真答:中国人为何蔑称朝鲜人“棒子”|大象公会 真问真答:中国人为何蔑称朝鲜人“棒子”|大象公会 大象公会 作者: 小白兔吃猫饼干 2016-06-30 22:56:22 举报 阅读数:41545 关于“棒子”蔑称的起源,网上有很多不靠谱的解释.一种说法称朝鲜人爱种也爱吃玉米,而玉米在东北又被称作“棒子”,但事实上朝鲜人很少种植玉米,基本以水稻和小麦做主食. 另一种说法称朝鲜人在伪满洲国时期帮日本人做警察,日本人却不给他们配以武器,只能挥舞朝鲜妇女的洗衣棒欺压中国人,因而得到“棒子”的蔑称,然