前端面试题(二)

八, for循环与 map 的区别

1. foreach 与 for 的区别:

(1),固定长度或者长度不需要计算的时候用for, 不确定长度或者计算长度有损性能的时候用fo reach

(2),foreach用于集合或者数组遍历, for在复杂的循环中效率更高;

(3),对集合进行修改的时候, 用for;

(4),foreach 相比 for 的优势在于对稀疏数组的处理, 会跳过数组中的空位;

2. 数组中foreach 与 map

相同点:

  • 都是循环遍历数组中的每一项;
  • 每次执行匿名函数都支持 3 个参数,item(当前每一项),index(索引值), arr(原数组)
  • 匿名函数中的 this 都是指向window;
  • 只能遍历数组;
  • 都不会改变原数组;

区别:

map: 返回一个新的数组, 数组中的元素为原始数组调用函数处理后的值; map不会对空数组进行监测, map方法不会改变原始数组;arr 是空数组, 返回也是空数组; 支持 chrome等;

forEach:用来调用数组的每个元素, 将元素传给回调函数; 对于空数组不会调用回调函数; 无论arr 是不是空数组, forEach返回的都是 undefined。

九, 图片自适应拉伸

图片设置 no-repeat, background-size: 100% 100%; 自适应大小;

十,JS 原型链

原型链和原型对象是 js 的核心。

原型:JavaScript 是基于原型的我们创建的每个函数都有一个prototype(原型)属性, 该属性是一个指针, 指向一个对象,该对象的用途是包含可以由特定类型的所有实例共享的属性和方法。(当我们创建一个函数的时候 ,系统会自动分配一个 prototype属性, 用来存储可以让所有实例共享的属性和方法);

  • 每个构造函数都有一个 prototype 属性,这个属性指向原型对象;
  • 原型对象默认拥有一个constructor 属性,指向他的构造函数;
  • 每个对象都拥有一个 _proto_ 隐藏属性,指向它的原型对象;

若已经创建实例, 重写原型会切断实例与原型之间的联系。 重写原型对象时候将constructor指向构造函数。

原型链: 所有的对象都是由他的原型对象继承而来, 而原型对象自己本身也是一个对象,它也有自己的原型对象 , 这样层层上朔,就形成了一个原型链。

  • 所有原型链的终点都是Object 函数的 prototype 属性;
  • Object.prototype 指向的原型对象也拥有原型, 不过是null, null没有原型;

十一,怎样累加求和

  1. for 循环累加;
  2. forEach循环累加;
  3. return eval(arr.join("+")) 

 4. 函数式编程:

function sumArr(arr){
        return arr.reduce(function(prev,cur){
            return prev + cur;
        },0);
}

十二,TypeScript原理

Scanner 扫描器(scanner.ts)

Parser 解析器 (parser.ts)

Binder 绑定器 (binder.ts)

Checker 检查器 (checker.ts)

Emitter 发射器(emitter.ts)

工作原理: 

  1. TypeScript 源码经过扫描器扫描之后会变成一系列 Token;
  2. 解析器解析token,得到一棵 AST 语法树;
  3. 绑定器遍历 AST 语法树, 生成一系列Symbol,并将这些 Symbol 连接到对应的节点上去;
  4. 检查器再次扫描 AST, 检查类型, 并将错误收集起来;
  5. 发射器根据AST 生成 JavaScript代码;

十三,同步,异步

同步转异步:

  • 定时器, setTimeout
  • promise 
    let p = new Promise( res => {
        resolve();
    });
    
    p.then(() => {
        // 之前的同步操作
    })

异步转同步(promise):

// 定义需要异步处理的方法
function getData() {
    return new Promise( reslove => {
        resolve('resolve');
    })
}

async function callback() {
    var data = await getData();
    // 处理结果

}

十四,数组转对象

  1. 展开运算符
    const arr = ['one', 'two', 'three'];
    const obj = {...arr};
    console.log(obj); // {0: 'one', 1: 'two', 2: 'three'};
  2. Object.assign()
    const arr = [1, 2, 3];
    const obj = Object.assign({}, arr);
    console.log(obj); //  {0:1, 1:2, 2:3}
  3. Object.fromEntries, 把键值对转换为对象
    const arr = [['1', 1], ['2', 2], ['3', 3]];
    const obj = Object.fromEntried({arr);
    console.log(obj); //  {1:1, 2:2, 3:3}
  4. forEach, 定义变量循环赋值

十五,对象转数组

  1. Object.entries();
    const obj = {a: 1, b:2, c: 3};
    const arr = Object.entries(obj);
    console.log(arr); // [['a', 1], ['b', 2], ['c', 3]]
  2. Object.keys()
    const obj = {a: 1, b:2, c: 3};
    const arr = Object.keys(obj);
    console.log(arr); // ['a', 'b', 'c']
  3. Object.values(), 由给定的对象自身可枚举的属性值组成的数组
    const obj = {a: 1, b: 2, c: 3};
    const arr = Object.values(obj);
    console.log(arr); // [1, 2, 3]
  4. Array.from(arr, fn, this), 从一个类似数组对象或可迭代对象创建一个新的, 浅拷贝的数组实例。 参数:

        array: 要变化成数组的数组对象或可迭代对象;

        fn: 指定了该参数, 新数组中的每个元素都会执行该回调函数;

        this:执行回调函数时的this对象;

// 数组对象
const obj = {
    0: 'name',
    1: 'age',
    2: 'sex',
    3: 'height,
    length: 3
};

const arr = Array.from(obj);
console.log(arr); // ['name', 'age', 'sex']

// 输出3个是因为上面说的length的长度决定了数组的长度

// 可迭代对象

const obj2 = {
    0: 'name',
    1: 'age',
    2: 'sex',
    3: 'height'
};

function *createInterator(ojb) {
    for( let value in obj ) {
        yield obj[value];
    } 
}

const arr2 = Array.from(createInterator(obj2));
console.log(arr2); // ['name', 'age', 'sex', 'height'];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值