JS面试题第二章

ES6语法

比较var let const

var有什么问题?

1.声明提升
javascript 复制代码
console.log(num); // undefined
var num = 123

这样应该是报错会更好

所以,let这样操作会直接报错

javascript 复制代码
console.log(num);
let num = 123
// 报错
2.变量覆盖
javascript 复制代码
    var num1 = 123
    var num1 = 1234
    console.log(num1);  // 1234
    // 2.变量覆盖
javascript 复制代码
    let num2 = 123
    let num2 = 1234
    // 报错
    // let 不允许变量覆盖
3.var没有块级作用域
javascript 复制代码
    function f2() {
        for (var i = 0; i < 3; i++) {
            console.log(i);
        }
        console.log(i);
    }
    f2()

const

特性:

  • 定义常量,值不能修改

  • const 声明了值一定要赋值

  • let的属性const都支持

  • 全局常量一般大写

快速去重的方法

ES6之前

使用两个传统的for循环

而ES6可以,利用集合

javascript 复制代码
    let arr = [12, 43, 43, 123, 12, 55]
    let item = [...new Set(arr)]
    // 利用集合
    console.log(item);

Promise

javascript 复制代码
    const promise = new Promise((resolve, reject) => {
        console.log(1);
        resolve()
        console.log(2)
    })
    promise.then(() => {
        console.log(3);
    })
    console.log(4);

输出是 1243

因为promise构造函数的方法同步执行

而.then异步执行

闭包

什么是闭包?

闭包就是__方法里面有一个方法

javascript 复制代码
function a() {
    function b() {
        let a = 1
        return function () {
            console.log(a)
        }
    }
}

闭包的意义何在?

1.延长变量的生命周期

2.创建私有环境

javascript 复制代码
let name = "admin"
function fn1() {
    let b = 1
    console.log(name);
}
// console.log(b);  报错
fn1()

JS的执行机制

JS运行的时候会生成一个临时的变量对象.AO(active object)

运行的时候会把所有的变量和临时的方法都放进去,全局变量不在这个里面

1.函数执行完之后,AO销毁

2.函数执行完之后,AO销毁,但是临时的方法还在

3.函数执行完之后,AO销毁,但是临时的方法还在,但是临时的方法里面有变量,这个变量还在

作用域链

javascript 复制代码
 let name = "小明"
    function fn2() {
        let name = "小白"
        function fn1() {
            let name = "小红"
            console.log(name);
        }
        fn1()
    }
    fn2()  // 小红
    // 函数抱着函数就形成了作用域链,就近原则
    // 一层一层的向外找

其实,闭包就是桥梁,所谓沟通内外部方法的桥梁

javascript 复制代码
 function outer() {
        let a1 = 111
        let a2 = 222
        return function inner() {
            return a1
        }
    }
    function h5() {
        let num = outer()
        console.log(num); // 不会输出
        // 为什么不建议定义全局变量
        // 1. 污染全局变量
        // 2.全局变量不会被垃圾机制所回收
    }

闭包的问题

闭包会常驻内存,所以要慎用

闭包的应用

Vue中的data()为什么是一个函数,实际上就是一个闭包的设计,Vue中会有很多对应的组件,每一个组件都有一个data,保证了各个组件之间都拥有了一块私有的作用域。

如果不用闭包,各个组件之间就会干扰,这就是闭包的作用

私有作用域

javascript 复制代码
 let makeCounter = function () {
        let num = 0
        function changeBy(val) {
            num += val
        }
        return {
            add: function () {
                changeBy(1)
            },
            reduce: function () {
                changeBy(-1)
            },
            get: function () {
                return num
            }
        }
    }
    // 一个经典的闭包的私有作用域应用
    let counter1 = makeCounter()
    let counter2 = makeCounter()
    console.log(counter1.get());
    counter1.add()
    counter2.add()
    counter1.add()
    console.log(counter1.get());
    console.log(counter2.get());
    // 他们俩都有各自独立的作用域

原型链与继承

原型是什么?

原型是prototype

原型链是什么?

原型链是什么 proto 谷歌浏览器上 是[[prototype]]

javascript 复制代码
// 常规对象上没有原型
let obj = {}
let list = []
obj.prototype.a = 56
list.prototype[0] = 123
// 对象和数组上没有

原型是函数上特有的

javascript 复制代码
// 原型是函数上特有的
function fn() {

}
fn.prototype.name = "cc"
fn.prototype.fn2 = function () {
    console.log("fn2")
}
/**
 * 原型是函数特有的
 * 为什么要在函数原型上挂载东西
 * 为了继承
 */

原型链是大家都有的

原型链,原型,继承三者的关系

javascript 复制代码
// 不是构造函数
    function Person() {

    }
    Person.prototype.name = "cc"
    Person.prototype.age = 18
    Person.prototype.say = function () {
        console.log(this.age)
    }
    let person1 = new Person()
    /**
     * new一个东西的时候才是叫做构造函数
     * 通过new关键字继承了它的原型属性和方法
     * person1就是Person构造函数的实例
     */
    console.log(person1.name);  // cc
    /**
     * 首先从当前实例属性去找
     * 如果找到了就返回
     * 否则就沿着原型链一层一层网上找
     * 知道找到了null为止
     * 如果找到null还没找到就会报错
     */

    /**
     * 还有一个问题
     * 自身也有属性,父类也有属性
     * 它怎么判断呢?
     * 它会通过一个forin去循环整个对象
     * 对象本身就有一个方法hasOwnPropery
     */
    person1.name = "自己的"
    console.log(person1.name); // 自己的
    // 这样子就能查到私有属性
    let item
    for (item in person1) {
        if (person1.hasOwnProperty(item)) {
            console.log(item);
        }
    }
    /**
     * 问题是自己没有这个hasOwnPropery方法
     * 父类也没有这个方法
     * 这个方法从哪里来的?
     * 这个是他爹的爹Object上的方法
     * Object.hasOwnProperty
     * 它爹直接继承Object
     */

    /**
     * 总结:被构造的东西,它的原型链指向的是构造他的方法的原型
     */
相关推荐
什么鬼昵称20 分钟前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色38 分钟前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2341 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河1 小时前
CSS总结
前端·css
NiNg_1_2341 小时前
Vue3 Pinia持久化存储
开发语言·javascript·ecmascript
读心悦1 小时前
如何在 Axios 中封装事件中心EventEmitter
javascript·http
BigYe程普1 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
神之王楠2 小时前
如何通过js加载css和html
javascript·css·html
余生H2 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
花花鱼2 小时前
@antv/x6 导出图片下载,或者导出图片为base64由后端去处理。
vue.js