JavaScript让前端飞JavaScript 进阶营

JavaScript 常见面试题分析(二)

2018-02-07  本文已影响283人  Nian糕
Unsplash
01 说明 this 几种不同的使用场景

this 要在执行时才能确认值,定义时无法确认

运行结果

① 作为构造函数执行 (this 指向创建出来的实例对象)

function Foo(name) {
    this.name = name
}
var f = new Foo('年糕')
运行结果

② 作为对象属性执行 (this 指向调用该方法的对象)

var obj = {
    name: 'Niangao',
    printName: function() {
        console.log(this.name)
    }
}
obj.printName()
运行结果

③ 作为普通函数执行 (this 指向 window)

function fn() {
    console.log(this)
}
fn()
运行结果

call() 方法 apply() 方法 bind() 方法 (this 指向第一个参数)

function fn1(name, age) {
    console.log(name)
    console.log(this)
}
fn1.call({x:100}, 'niangao', 17)

function fn2(name, age) {
    console.log(name)
    console.log(this)
}
fn2.apply({x:100}, ['niangao', 17])

var fn3 = function(name){
    console.log(name)
    console.log(this)
}.bind({y:200})
fn3('niangao')
运行结果
02 实际开发中闭包的应用

闭包实际应用中主要用于封装变量,收敛权限,下面是一个验证是否为第一次登陆的例子

function ifFirstLoad() {
    var _list = [];
    return function (id) {
        if(_list.indexOf(id) >= 0) {
            return false;
        }else {
            _list.push(id);
            return true;
        }
    }
}
运行结果

闭包的使用场景主要有两个:① 函数作为返回值;② 函数作为参数传递

function F1() {
    var a = 100;
    // 函数作为返回值
    return function(){
        console.log(a)
    }
}
var f1 = F1();

function F2(fn) {
    var a = 200;
    // 函数作为参数传递
    fn()
}
F2(f1)
03 创建 10 个 <a> 标签,点击的时候弹出对应的序号
for(var i = 0; i < 10; i++){
    (function(i){
        var div = document.createElement('div');
        div.innerHTML = i + '<br>';
        div.addEventListener('click', function(e){
            e.preventDefault();
            console.log(i);
        })
        document.body.appendChild(div)
    })(i)
}
运行结果
04 如何理解作用域

① 没有块级作用域,只有函数和全局作用域
② 自由变量
③ 作用域链,即自由变量的查找

// 无块级作用域
if(true){
    var name = "niangao"
}
console.log(name) // niangao

// 函数和全局作用域
var a = 100;
function fn() {
    var a = 200;
    console.log('fn', a);
}
console.log('global', a) // global 100
fn() // fn 200

a 和 b 是自由变量——当前作用域没有定义的变量,即“自由变量”

运行结果

上面这个例子中,console.log(a); 并没有在当前作用域寻找到自由变量 a,于是不断的往父级作用域寻找自由变量 a,直到全局作用域,而能够沿着作用域一级级向上寻找的机制就称为“作用域链”

需要注意的是,一个函数的父级作用域是它定义时的作用域,而不是它执行时的作用域

运行结果
05 同步和异步的区别是什么

同步会阻塞代码执行,而异步不会

//异步
console.log(100);
setTimeout(function(){
    console.log(200);
}, 1000)
console.log(300);

//同步
console.log(100);
alert(200);
console.log(300);
06 前端使用异步的场景有哪些

在可能发生等待的情况下,我们会需要异步,比如定时任务(setTimeout, setInterval),网络请求(Ajax 请求,动态 <img> 加载),事件绑定

Ajax 请求代码示例

<script src="./jquery.js"></script>
<script type="text/javascript">
    console.log('start');
    $.get('./data.json', function(data) {
        console.log(data);
    })
    console.log('end');
</script>
运行结果

<img>加载示例

console.log('start');
var img = document.createElement('img');
img.onload = function(){
    console.log('loaded')
}
img.src = 'https://github.com/Niangao-Warren/JianShu/blob/master/Demo/Mouse_sliding_picture_showing_hidden/images/n1.jpg?raw=true';
console.log('end');
运行结果

事件绑定示例

运行结果 1 运行结果 2
07 一道关于 SetTimeout 的题目
console.log(1);
setTimeout(function(){
    console.log(2)
}, 0);
console.log(3);
setTimeout(function(){
    console.log(4)
}, 1000);
console.log(5);
运行结果
08 获取 2018-02-07 格式的日期

常用的日期 API 如下

Date.now() // 获取当前时间毫秒数
var today = new Date()
today.getTime() // 获取毫秒数
today.getFullYear() // 年
today.getMonth() // 月(0-11)
toddy.getDate() // 日(0-31)
today.getHours() // 时(0-23)
today.getMinutes() // 分(0-59)
today.getSeconds() // 秒(0-59)
function formatDate(today) {
    if(!today) {
        today = new Date()
    }
    var year  = today.getFullYear(),
        month = today.getMonth() + 1,
        date  = today.getDate();
    if(month < 10) {
        month = '0' + month;
    }
    if(date < 10) {
        date = '0' + date;
    }
    return year + '-' + month + '-' + date;
}
运行结果
09 获取随机数,要求是长度一致的字符串格式
var random = Math.random();
var random = random + '0000000000' // 后面加上 10 个零
var random = random.slice(0, 10);
image.png
10 写一个能遍历对象和数组的通用 forEach 函数

常用的数组 API 有

API 作用
forEach 遍历所有元素
every 判断所有元素是否都符合条件
some 判断是否有至少一个元素符合条件
sort 排序
map 对元素重新组装,生成新数组
filter 过滤符合条件的元素

forEach 遍历所有元素
item 对应的是元素的值,index 对应的是元素的位置

forEach

every 用来判断数组所有元素,都满足一个条件

every

some 用来判断数组所有元素,只要有一个满足条件即可

some

sort 排序

sort

map 对元素重新组装,生成新数组

map

filter 通过某一条件过滤数组

filter
function forEach(obj, fn) {
    var key;
    if(obj instanceof Array) {
        obj.forEach(function(item, index) {
            fn(index, item)
        })
    }else {
        for(key in obj) {
            fn(key, obj[key])
        }
    }
}
运行结果
End of File

行文过程中出现错误或不妥之处在所难免,希望大家能够给予指正,以免误导更多人,最后,如果你觉得我的文章写的还不错,希望能够点一下喜欢关注,为了我能早日成为简书优秀作者献上一发助攻吧,谢谢!^ ^

上一篇下一篇

猜你喜欢

热点阅读