JavaScript 常见面试题分析(二)

2024-03-16 15:21:29 浏览数 (1)

01 说明 this 几种不同的使用场景

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

运行结果运行结果

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

代码语言:javascript复制
function Foo(name) {
    this.name = name
}
var f = new Foo('年糕')
运行结果运行结果

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

代码语言:javascript复制
var obj = {
    name: 'Niangao',
    printName: function() {
        console.log(this.name)
    }
}
obj.printName()
运行结果运行结果

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

代码语言:javascript复制
function fn() {
    console.log(this)
}
fn()
运行结果运行结果

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

代码语言:javascript复制
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 实际开发中闭包的应用

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

代码语言:javascript复制
function ifFirstLoad() {
    var _list = [];
    return function (id) {
        if(_list.indexOf(id) >= 0) {
            return false;
        }else {
            _list.push(id);
            return true;
        }
    }
}
运行结果运行结果

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

代码语言:javascript复制
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> 标签,点击的时候弹出对应的序号

代码语言:javascript复制
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 如何理解作用域

a. 没有块级作用域,只有函数和全局作用域

b. 自由变量

c. 作用域链,即自由变量的查找

代码语言:javascript复制
// 无块级作用域
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

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

运行结果运行结果

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

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

运行结果运行结果

05 同步和异步的区别是什么

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

代码语言:javascript复制
//异步
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 请求代码示例

代码语言:javascript复制
<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>加载示例

代码语言:javascript复制
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运行结果 1
运行结果 2运行结果 2

07 一道关于 SetTimeout 的题目

代码语言:javascript复制
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 如下

代码语言:javascript复制
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)
代码语言:javascript复制
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 获取随机数,要求是长度一致的字符串格式

代码语言:javascript复制
var random = Math.random();
var random = random   '0000000000' // 后面加上 10 个零
var random = random.slice(0, 10);
运行结果运行结果

10 写一个能遍历对象和数组的通用 forEach 函数

常用的数组 API 有

API

作用

forEach

遍历所有元素

every

判断所有元素是否都符合条件

some

判断是否有至少一个元素符合条件

sort

排序

map

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

filter

过滤符合条件的元素

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

forEachforEach

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

everyevery

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

somesome

sort 排序

sortsort

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

mapmap

filter 通过某一条件过滤数组

filterfilter
代码语言:javascript复制
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])
        }
    }
}
运行结果运行结果

0 人点赞