小言_互联网的博客

前端笔试面试备考3

321人阅读  评论(0)

简述单向绑定与双向绑定

单向绑定是数据流单一,双向数据绑定主要用于需要实时反映用户输入的场合

JavaScript中的模块化

名称 实现 其他
AMD 浏览器端,require.js实现 依赖前置
CMD 浏览器端,see.js实现 依赖就近
CommonJS 服务器端,NodeJs实现

作用域与闭包的理解

当参数为普通数据类型时

for(var i=0;i<5;i++){
 (function(i){
   setTimeout(function(){
   	console.log(i);  // 0,1,2,3,4
   },0);
 })(i);
}
for(var i = 0; i < 5; i++){
   setTimeout(function(){
   	console.log(i);// 4,4,4,4,4
   },0); 
}

当参数为对象时

for (var i = {j:0}; i < 5; i.j++) {
 (function(i) {
   setTimeout(function(){
  	 console.log(i.j);//4,4,4,4,4
   }, 0);
 })(i);
}

引用类型变量,加上自执行函数,仍然不行的原因:

    for(var i = {j: 0}; i.j < 5; i.j++){
        (function(i) {
            setTimeout(function(){
                console.log(i.j); // 0,1,2,3,4
            },0);
        })(JSON.parse(JSON.stringify(i)));
    }

代码分析:

  • 知识点1:这道题涉及到,for循环中,var申明变量没有块级作用域。会导致for循环结束后,以前的值,无法保留下来。
  • 知识点2:JS里面的语句执行顺序。总体是从上往下执行,调用function时会将它放入栈中,遇到 setTimeOut()会放入队列中。function按照先进后出的顺序执行。而setTimeOut会在所有可以执行的JS语句都执行完毕后,再按照先进先出的顺序执行计时器
    对于没有块级作用域,通过闭包的原理解决。
    网上有人说,例子二输出一样是因为没有块级作用域,但我认为不太对,因为我们已经用自执行函数解决了没有块级作用域的问题。

(1)JSON.stringify:将JS数据结构转化为JSON字符串
(2)JSON.parse :将JSON字符串解析为JS数据结构

检测一下是否弄懂了

var data = [];
for(var i = 0; i < 3; i++){
  data[i] = (function(num){
    return function(){
      console.log(num);
    }
  })(i);
}

data[0](); //0
data[1](); //1
data[2](); //2
for (let i = 0; i < 3; i++) {
       setTimeout(function() {
              console.log(i++);
        }, 1000);
}
// 0,1,2

按址引用

    var setPerson=function(person){
        person.name="kevin";
        //console.log("1", person);
        person = {name:"nick"};
        //console.log(2, person);
    };
    //console.log(person);
    var person={name:"alan"};
    //console.log(person);
    setPerson(person);
    //person = {name:"nick"};
    //console.log("外", person);
    alert(person.name);

答案:Kevin
详解:

  • JS里面的参数都是按值传递的。调用setPerson时,将实参person_A的地址赋值给了函数里面的形参person_B。(加上后缀,好区分)
  • person.name=“kevin”,因为此时person_B与person_A的指向一样,person_B通过地址修改了内存里面的对象的name属性。
  • person = {name:“nick”} 语句,开辟一个新的对象,将新地址值赋值给person_B,注意此时,person_B和person_A的指向已经不一样了。这一语句不会影响到person_A
  • 通过person_A访问到的对象的name属性——Kevin

数组的迭代类方法

    var array1=Array(3);
    array1[0]=2;
    var result=array1.map(element => "1");
    console.log(result);

答案:[ “1”, null, null ]
详解:

  • map函数,按照原始数组元素顺序依次操作元素
  • return 语句 结束本轮循环,并将 return语句后面的表达式结果,保存到一个新数组里边
  • 返回值:新数组,与原数组等长
  • 是否改变原数据:否

|| 运算符

var a= 2018<0 || typeof(2018+"");
console.log(a);

答案:string
详解:
|| 运算符 真前假后

下列关于line-height,说法正确的是

A line-height设置150%或1.5都是一样的效果
B 在Inline元素设置line-height不会生效
C 设定line-height的值少于font-size 的值,元素高度为font-size的值
D line-height属性会被继承

答案:A D
line-height详解


以下代码运行结果为

   var elements = ['Fire','wind','Rain'];
    console.log(elements.join(','));

答案:Fire,wind,Rain

以下代码运行结果为

 var execFunc = function(){
        console.log("executed");
    };
    setTimeout(execFunc,0);
    console.log("changed");
    execFunc = function(){
        console.log("another executed");
    }

答案:changed executed

能阻止事件冒泡的方法

A e.preventDefault()

B event.cancelBubble = true

C event.returnValue = false

D e.stopPragation()

答案: B D

分析:DOM中的事件对象 event.stopPropagation()可以阻止事件的传播.,取消进一步的事件冒泡或者捕获

IE中的事件对象 cancelBubble属性值为true,可以取消事件冒泡。

preventDefault() 阻止事件的默认行为,只有cancelabel属性的值设为true时,才可以使用preventDefalut.

下面选项中给submitan按钮绑定click事件,正确的是

A btn.addEventListener(“click”,fun,false);

B btn.dispatchEvent(“click”,fun,true);

C btn.attachEvent(“onclick”,fun);

D btn.detachEvent(“onclick”,fun);

答案:ABC

分析: DOM2级事件绑定: addEventListener有三个参数:第一个参数表示事件名称(不含 on,如 “click”);第二个参数表示要接收事件处理的函数;第三个参数为 useCapture。

IE用了attachEvent(),和detachEvent(),接收两个参数,事件名称和事件处理程序函数。由于IE8及以前只支持事件冒泡;通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。

attachEvent(event, function):event 必须。字符串,指定事件名。注意: 使用 “on” 前缀。 例如,使用 “onclick” ,而不是使用 “click”

btn.detachEvent(“onclick”,handler); /IE下移除侦听器/

事件触发器也是分为高级浏览器和IE两派,而dispatchEvent正是用于高级浏览器的事件触发。 dispatchEvent是作为高级浏览器(如chrome、Firfox等)的事件触发器来使用的。

单词逆序

对于一个字符串,请设计一个算法,只在字符串的单词间做逆序调整,也就是说,字符串由一些由空格分隔的部分组成,你需要将这些部分逆序。
给定一个原字符串A,请返回逆序后的字符串。例,输入"I am a boy!", 输出"boy! a am I"

    function reverseString (str){
        var arr = str.split(/\s/g);
        console.log(arr.reverse().join(" "));
    }
    reverseString("I am a boy!");

硬币划分

有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱(n <= 100000),有多少种组合可以组成n分钱?

字符串全排列

对K个不同字符的全排列组成的数组, 面试官从中随机拿走了一个, 剩下的数组作为输入, 请帮忙找出这个被拿走的字符串? 比如[“ABC”, “ACB”, “BAC”, “CAB”, “CBA”] 返回 “BCA”

字符串加密和解密

输入的字符串规则:由数字和26个英文字母的大小写组成
加密规则:

  • 数字 +1 ,9变为0
  • 字母 变为下一个字母 ,并转变大小写,z变为A ,Z变为a
function change(str){
        var code_A = "A".charCodeAt(0); //65
        var code_a = "a".charCodeAt(0); //97
        var arr = str.replace(/\s/g, "").split("");
        var newArr = arr.map((item, index) => {
            if(isNaN(Number(item))){
                var code_item = item.charCodeAt(0);

                if(code_item >= code_A && code_item < code_a){
                //    字符为 大写
                    var new_code = code_item - code_A + code_a + 1;
                    if(new_code === code_a + 26){
                        new_code = code_a;
                    }
                    item = String.fromCharCode(new_code);
                    return item;

                } else {
                //    字符为小写
                    var new_code = code_item - code_a + code_A + 1;
                    if(new_code === code_A + 26){
                        new_code = code_A;
                    }
                    item = String.fromCharCode(new_code);
                    return item;
                }
            } else {
                item = Number(item);
                item += 1;
                if(item === 10){
                    item = 0;
                }
                return item;
            }
        });
        console.log(newArr.join(""));
    }
    change("12A39z0Z"); //23b40A1a

进制转换

涉及到数字的计算,不采用JS,采用Java

import java.util.Scanner;
public class Main{
    public static void  mian(String[] args){
      Scanner in = new Scanner(System.in);
      int n = in.nextInt();
      int jinzhi = in.nextInt();
      zhuanHuan(n, jinzhi);
    } 
    public void zhuanHuan(int n,int jinzhi){
        String str = "";
        while(n!=0){
        str = n%jinzhi + str;
         n = n/jinzhi;
       }
         System.out.println(str);
    }
}

封装函数 f,使 f 的 this 指向指定的对象

function bindThis(f, oTarget) {
    return function (){
        return f.apply(oTarget, arguments);
    }
}

解题思路

call,apply,bind 都是改变上下文的,但是call apply是立即执行的,而bind是返回一个改变上下文的函数副本

获取 url 中的参数

  1. 指定参数名称,返回该参数的值 或者 空字符串
  2. 不指定参数名称,返回全部的参数对象 或者 {}
  3. 如果存在多个同名参数,则返回数组


需要明确

  • 指定参数,返回的是一个对象
    • 一个参数时,对象属性值为参数值
    • 多个同名参数,对象属性值为一个数组,这个数组包含了所有的参数值
  • 不指定参数,返回的是一个对象,或者 空字符串

我一开始理解成了,没有指定参数时,返回对象或者空字符串,指定参数后若参数只有一个则返回参数值,若多个参数同名则返回数组。于是,分情况讨论,代码一大片,最后还错了!

emmmm,清楚的了解题目的意思特别的重要。否则只能是南辕北辙!

function getUrlParam(sUrl, sKey) {
    var paramArr = sUrl.split('?')[1].split('#')[0].split('&'); // 取出每个参数的键值对放入数组
    const obj = {};
    paramArr.forEach(item => {
        const [key, value] = item.split('='); // 取出数组中每一项的键与值
        if(obj[key] === void 0){ // 表示第一次遍历这个元素,直接添加到对象上面
            obj[key] = value
        } else{
            obj[key] = [].concat(obj[key], value); // 表示不是第一次遍历说明这个键已有,通过数组存起来。
        }
    });
    return sKey === void 0 ? obj: obj[sKey] || '' 
    // 如果该方法为一个参数,则返回对象。
    //如果为两个参数,sKey存在,则返回值或数组,否则返回空字符。
}

void 0

void 操作符,执行后面的语句后返回 undfined,那么,为何不直接用undefined呢?
在这道题使用undefined是完全可以的!

在实际开发中,推荐使用 void 0 为何?因为

  • 占位少
  • JS中,undefined 并不是保留字或者关键字,这意味着我们可以将undefined作为变量名进行赋值,会导致undefined不是一个纯正的undefined,变成了一个可以是任意数值的变量

查找两个节点的最近的一个共同父节点,可以包括节点自身

输入描述:
oNode1 和 oNode2 在同一文档中,且不会为相同的节点

function commonParentNode(oNode1, oNode2) {
    for(;;oNode1 = oNode1.parentNode){
        if(oNode1.contains(oNode2)){
            return oNode1;
        }
    }
}


转载:https://blog.csdn.net/weixin_44048286/article/details/101429905
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场