zoukankan      html  css  js  c++  java
  • JavaScript高级

    1.判断以下程序的输出结果:

    var age=100;

    function test(){ 

       this.age=50;

       return funtion(){   

                  return this.age; 

         }

    }

    var  m = new test();

    alert( m() );

    var n=test();

    alert( n() );

     

    答案:100,50

    构造函数一旦返回一个对象,就不再创建新对象

    m获得的是function(){ return this.age;}

    n=test(), this指向window. 先将全局变量age变为50,

    又返回一个函数function(){ return this.age;} 保存变量

    n中,调用n时,this指向window.

     

    2.判断以下程序的输出结果:

    var name ="The Window";

    var obj ={   

         name:"My obj",

          getName:function(){   

                return function(){   

                     return this.name;

             }

          }

    };

    console.log(obj.getName()());

     

    答案:The window 

    obj.getName()返回的是一个函数对象function(){ return this.name;}

    (function(){return this.name;}()) 相当于匿名函数自调,this指向window

     

    3.判断以下程序的输出结果:

    var length =10;

    function fn(){   

        console.log(this.length);

     }

    var obj ={ 

       length:5;

       method:function(fn){   

             fn();

             arguments[0]();

        }

    }

    obj.method(fn,1)

     

    答案:10  2

    fn()  this指向window,所以输出10

    arguments[0]()属于特殊情况,this->arguments,相当于arguments.0(),所以,

    this指向arguments。fn也属于arguments的成员,所以length输出的是obj.method()的参数个数,2

     

    4.统计一个字符串中出现次数最多的字符是?共出现多少次?

    答案:

    var  dict={};

    var  c="",max=1;

    for(var i=0;i<str.length;i++){

        var char =str[i];

        if(dict[chart]===undefined)

               dict[char]=1;

            else {   

               dict[char]+=1;

               if(dict[char]>max){

                    max=dict[char];

                    c=char;

            }

         }

    }

    console.log(c,max);

    提前创建一个空对象,用于保存每个字母出现的次数。

    提前创建变量,准备保存出现次数最多的字符和出现的次数.

    然后,遍历字符串中的每个字母,每遍历一个字母就判断结果

    对象中是否包含以当前字母为属性名的属性。如果不包含以

    当前字母为属性名的属性,说明是首次遇见该字母,就向结

    果对象中强行添加以该字母为属性名的属性,值暂时为1。如

    果结果对象中已经包含以当前字母为属性名的属性,说明不是

    第一次碰见该字母。则取出该字母名属性对应的次数+1。只要

    当前字母出现的次数>之前变量中记录的最大次数,就用当前字

    母和出现次数,取而代之。

     

    5.判断以下程序的输出结果:

    for(var i=0;i<5;i++){   

        setTimeout(function(){   

            console.log(i);

         },0)

    }

    console.log(i);

     

    答案:5 5 5 5 5

    函数定义时,函数内容是不执行的,所以i还是i,不会变成0,1,2,3,4

    定时器中的回调函数只能在主程序执行完才能开始执行

    当主程序执行完,循环变量i,已经被改为5了.

     

    6.判断以下程序的输出结果:

    window.color ="red";

    let  color="green";

    let   obj={   

        color:"blue"

    };

    let  sayColor=()=>{

       return this.color;

    }

    console.log(sayColor.apply(obj));

    let  a=10;

    console.log(window.a);

    答案:  red  undefined

    let 相当于匿名函数自调,所以,let 声明的变量,不会自动加入到window.

    箭头函数内外this通用,所以apply也无法替换sayColor函数内的this,

    所以this指向window,所以输出red.

     

    7.判断以下程序的输出结果:

    var c=1;

    function c(c){

       console.log(c);

       var c=3;

    }

    c(2);

    答案:报错:TypeError:c 不是一个函数

    function c(c){} 整体被声明提前,后又被c=1代替.所以,

    c最后不是一个函数,而是数字1

     

    8.判断以下程序的输出结果:

    function change(){   

       alert(typeof  fn)

       function  fn(){ alert('hello') }

        var fn;

    }

    change();

     

    答案:function

    function fn(){ ...  }被整体声明提前了

    var  fn发现已经有fn变量了,就不再重复创建,所以,

    var  fn 没作用.

     

    9.判断以下程序的输出结果:

    a=3;

    a.prop=4;

    alert(a+a.prop);

    答案:NaN

    a.prop=4;等效于new Number(a).prop =4,但是new Number(a),

    使用后自动释放,4也不存在了.

    再次使用a.prop,又等效于新的new Number(a),所以没有prop属性,

    值为undefined.

    数字+undefined,undefined隐式转换为数字NaN,导致计算结果为NaN

     

    10.判断以下程序的输出结果:

    var  o={   

        a=10,

        b:{   

           a:12,

           fn:function(){   

                 var a=13;

                 console.log(this.a);

            }

         }

    }

    o.b.fn();

    答案:12 this指.前的o.b对象,所以a为12

     

    11.判断以下程序的输出结果:

    var  obj1={   

        name:'obj1',

         fn:function(){   

              document.write(this.name);

         }

     };

    var     obj2 ={ name:'obj2' };

    var     obj3 ={ name:'obj3' };

    obj1.fn();

    var  newFn =obj1.fn;

    newFn();

    newFn.call(obj2);

    obj3.fn=newFn;

    obj3.fn();

     

    答案: obj1 空字符串 obj2 obj3

    this指.前的obj1

    因为newFn调用时,前没有. ,所以this->window,

    call是强行替换newFn中的this为obj2

    this指 .前的obj3

     

    12.一个数组par中存放有多个人员的信息,

    每个人员的信息由年龄age和姓名name组成,如{age:2,name:'xx'}.

    请写一段JS程序,对这个数组按年龄从小到大进行排序.

    答案:function parSort(arr,propName){   

            arr.sort(function(a,b){

                   return a[propName]-b[propName];

       });

    }

    parSort(arr,"age");

     

    1)数组的sort函数的参数,是一个比较器函数。比较器函数

    的形参a和b,指当前要排序的数组中的任意两个作比较的元素。

    如果要作比较的a和b两个元素时简单的数字类型,则a直接和b相减,

    就可比较两数大小。但是,如果a和b都是对象类型的元素。要比较

    两个对象中某个属性的值的大小,就必须用a.属性-b.属性。如果属性

    名是灵活的,来自于变量,则必须用a[属性名变量]-b[属性名变量],

    就可比出两个对象的某个属性值的大小.

    2)最后,数组是引用类型的对象,在函数内修改数组,等效于修改原数组。

    所以不用返回值。

     

    13.有字符串var =' abc345efgabcab';请写出3条JS语句分别实现如下

    3个功能:

    1)去掉字符串中的a 、b、c字符,形成结果:'345efg'

    2)将字符串中的数字用中括号括起来,形成结果:'abc[345]efgabcab'

    3)将字符串中的每个数字的值分别乘以2,形成结果:'abc6810efgabcab'

     

    答案:

    1)str.replace(/([a-c])/g,'');

    2)str.replace(/(d+)/g,'[$1]');

    3)str.replace(/(d)/g,function(num){ return num*2 });

     

    1)将字符串中的a,b,c三个字符都替换为空字符串

    2)找到字符串中多个连续的数字,分为一组,然后将这一组的内容,替换为用[ ]包裹。$1,

    可获得关键词第一个()包裹的内容.

    3)找到字符串中的每个数字,*2后,再放回原位置.

    14.判断以下程序的输出结果:

    var  a=10;

    var  obj={   

        a:20,

        intr:function(){   

              var a=30;

              console.log(this.a);

        }

     }

    obj.intr();

    var intr=obj.intr;

    intr();

    答案:20 10 

    obj.intr(),this指.前的obj,所以输出20

    intr(),this指window,所以输出10

    15.判断以下程序的输出结果:

    function fun(){   

       for(var i=0;arr=[];i<3;i++){   

           arr[i]=function(){   

                 console.log(i);

             }

       }

           return arr;

    }  

    var funs=fun();

    funs[0]();

    funs[1]();

    funs[2]();

    答案:3 3 3

    16.介绍JavaScript的原型,原型链?有什么特点?

    答案:

    原型:

    -   JavaScript的所有对象中都包含了一个[proto]内部属性,这个属性所对应的就是该

    对象的原型.

    -  JavaScript的函数对象,除了原型[proto]之外,还预置了prototype属性

    -  当函数对象作为构造函数创建实例时,该prototype属性值将被作为实例对象的原型[proto].

    原型链:

    -  当一个对象调用的属性/方法自身不存在时,就会去自己[proto]关联的前辈prototype对象上去找

    -  如果没找到,就会去该prototype原型[proto]关联的前辈prototype去找。依次类推,直到找到属性/

    方法或undefined为止。从而形成了所谓的"原型链"

    原型特点:

    -JavaScript对象是通过引用来传递的,当修改原型时,与之相关的对象也会继承这一改变。

    17.谈谈JavaScript垃圾回收方法

    答案:标记清除(mark and sweep),

    - 这是JavaSript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,

    垃圾回收器将其标记为"进入环境",当变量离开环境的时候(函数执行结束)将其标记为"离开环境"

    - 垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境

    变量中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了.

    引用计数(reference counting)

    -   在低版本 IE 中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个 变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加 1,如果该变量的值变成了另外一个,则这个值得引用次数减 1,当这个值的引用次数变为 0 的时 候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运

    行的时候清理掉引用次数为 0 的值占用的空间

    18.说说严格模式的限制?

    答案:严格模式主要有以下限制:

    -  变量必须声明后再使用

    -  函数的参数不能有同名的属性,否则报错

    -  不能使用width语句

    -  不能对只读属性赋值,否则报错

    -  不能使用前缀0 表示八进制数,否则报错

    -  不能删除变量 delete prop,会报错,只能删除属性delete global[prop]

    -  eval 不会再它的外层作用域引入变量

    -  eval 和arguments不能被重新赋值

    -  arguments不会自动反映函数参数的变化

    -  不能使用arguments.callee

    -  不能使用arguments.caller

    -   禁止this指向全局对象

    -   不能使用fn.caller 和 fn.arguments获取函数调用的堆栈

    -   增加了保留字(比如protected、static 和interface)

    19。使用正则表达式验证邮箱格式

    答案:

    var  reg =/^(w)+(.w+)*@(w)+(.w{2,3}){1,3}$/;

    var email="example@qq.com";

    console.log(email);//true

    20.使用typeof  bar ==="object" 来确定bar是否是一个对象时有什么潜在的缺陷?

    这个陷阱如何避免?

    答案:尽管typeof  bar ==="object"是检查bar是否是对象的可靠方法,

    但JavaScript中令人惊讶的问题null也被认为是一个对象!

    因此,对于大多数开发人员来说,下面的代码会将true(而不是false)打印到控制台:

    var  bar  = null;

    console.log(typeof bar === "object");  ///  logs true

    只要知道这一点,就可以通过检查bar是否为空来轻松避免该问题:

    console.log((bar !== null) && (typeof bar === "object")); // logs false

    为了让我们的答案更加的完整,还有两件事值得注意: 首先,如果bar是一个函数,上面的解决方案将返回false。在大多数情况下,这是所期望的行为,但是在您希望函数返回true的情况下,您可以将上述解决方案修改为:

     

    console.log((bar !== null) && ((typeof bar === "object") || (typeof bar === "function")));

    其次,如果bar是数组,则上述解决方案将返回true(例如,如果var bar = [];)。在大多数情况下,这是所希望的行为,因为数组确实是对象,但是在您想要对数组也是false的情况下,可以将上述解决方案修改为:

     

    console.log((bar !== null) && (typeof bar === "object") && (toString.call(bar) !== "[object Array]"));

    但是,还有一个替代方法对空值,数组和函数返回false,但对于对象则为true:

    console.log((bar !== null) && (bar.constructor === Object));

    或者,如果您使用jQuery:

    console.log((bar !== null) && (typeof bar === "object") && (! $.isArray(bar)));

    ES5使得数组的情况非常简单,包括它自己的空检查:

    console.log(Array.isArray(bar));

    20.以下代码的输出是什么?解释你的答案

    var  a={  },

           b={key:'b'},

           c={key:'c'};

    a[b] =123;

    a[c]  =456;

    console.log(a[b]);

    答案:  456

    原因如下:设置对象属性时,JavaScript会隐式地将参数串联起来。

    在这种情况下,由于b和c都是对象,他们都将转换为"[objet  Object]"。

    因此,a[b]和a[c]都等价于["[objet Object]"],并且可以互换使用。因此,

    设置或引用[c]与设置或引用[b]完全相同。

  • 相关阅读:
    MongoDB的安装与简单使用
    [SCOI2008]天平
    [ZJOI2008]树的统计
    [HEOI2015]兔子与樱花
    [HAOI2006]l旅行
    [ZJOI2008]泡泡堂BNB
    [ZJOI2007]时态同步
    [SCOI2005]栅栏
    [SCOI2008]着色方案
    [SCOI2005]互不侵犯King
  • 原文地址:https://www.cnblogs.com/sna-ling/p/12445311.html
Copyright © 2011-2022 走看看