[Предложение👍] Запишите интервью по интерфейсу JavaScript в интернет-компании первого уровня BAT.

JavaScript
[Предложение👍] Запишите интервью по интерфейсу JavaScript в интернет-компании первого уровня BAT.

передовой

Из мира просто наблюдать в тайне! ! ! Всем привет, я Король Демонов Нэчжа!

Содержание интервью

Вам нужны базовые знания HTML и CSS, базовый синтаксис JavaScript и ES6, любопытство.

  • Вопросы для интервью с начинающим JS
  • JS Web API, среда разработки, среда выполнения
  • Прототипы, область действия, асинхронность, Ajax, события, веб-пакеты и т. д.

Наблюдайте за тестовой площадкой для всех вопросов интервью

  1. Учимся разбираться в схеме системы знаний
  2. Определить систему знаний и осознанно овладеть ею
  3. Хорошо резюмирует идеи, принципы

Typeof может определить, какие типы

тип оператора:

  • Типы, которые могут идентифицировать все значения
  • функция может быть признана
  • Может принудительно определить, является ли он ссылочным типом

Тестовый сайт: тип переменной JS

Код:

// 判断所有值的类型
let a; typeof a // 'undefined'
const str = 'abc'; typeof str // 'string'
const n = 10; typeof n // 'number'
const b = true; typeof b // 'boolean'
const s = Symbol('s'); typeof s // 'symbol'

// 能够判断函数
typeof console.log // 'function'
typeof function(){} // 'function'

// 能够识别引用类型
typeof null // 'object'
typeof ['a','b'] // 'object'
typeof {x:10} // 'object'

Когда использовать === и когда использовать ==

Тестовый сайт: принудительное преобразование типов

Преобразование типов для конкатенации строк

const a = 10 + 1 // 11
const b = 10 + '10' // '1010'
const c = true + '1' // true1

Решение:

10 + parseInt('1') // 11

==преобразование типов операторов

100 == '100' // true
0 == '' // true
0 == false // true
false == '' // true
null == undefined // true

преобразование типов

  1. Кроме0Все числа, кроме , преобразуются в логические значения.true.
  2. Кроме“ ”Все символы, кроме , преобразуются в логические значения.true.
  3. nullиundefinedПреобразуется в логическое значение какfalse.

когда использовать===, когда использовать==

Кроме==Кроме нуля, используется в другом месте===

const obj = {a:1}
if(obj.b==null){}
// 相当于
//if(obj.b === null || obj.b === undefined){}

Разница между window.onload и DOMContentLoaded

Тестовый сайт: процесс загрузки страницы

Создайте 10 этикеток, нажмите и появится соответствующий серийный номер

Тестовый сайт: область применения JS

Рукописный дроссель, защита от дрожания

Тестовый сайт: производительность, оптимизация опыта

Какую проблему решает Promise

Тестовый сайт: JS асинхронный

Разница между типом значения и ссылочным типом

Представление типов значений:

// 值类型
let a = 10
let b = a
a= 20
console.log(b); // 10

Представление ссылочных типов:

// 引用类型
let a = { age:12 }
let b = a
b.age = 13
console.log(a.age) // 13

рукописная глубокая копия

  1. Определите, является ли это типом значения или ссылочным типом
  2. Определите, является ли это массивом или объектом
  3. рекурсия

Код:

// 浅拷贝
const obj1 = {
    age: 12,
    name: 'web',
    address: {
        city: 'beijing'
    },
}

const obj2 = obj1
obj2.address.city = 'shanghai'
console.log(obj1.address.city)

результат:

shanghai

Глубокая копия: определите объект для копирования

const obj2 = deepClone(obj1)
obj2.address.city = 'shanghai'
console.log(obj1.address.city)

function deepClone(obj = {}){
    if(typeof obj !== 'object' || obj == null){
        // obj是null,或者不是对象和数组情况,直接返回
        return obj
    }
    
    // 初始化返回结果
    let result
    if(obj instanceof Array){
        result = []
    }else{
        result = {}
    }
    
    for (let key in obj) {
        // 保证Key不是原型的属性
        if(obj.hasOwnProperty(key)){
            // 递归调用
            result[key] = deepClone(obj[key])
        }
    }
    
    // 返回结果
    return result
}

результат глубокого копирования

beijing

прототип, цепь прототипов

  1. Как определить, является ли переменная массивом?
  • a instanceof Array
  1. написать простойjquery, с учетом плагинов и расширяемости?

Код:

class jQuery {
    constructor(selector){
        const result = document.querySelectorAll(selector)
        const length = result.length
        for(let i=0; i<length; i++){
            this[i] = result[i]
        }
        this.length = length
    }
    get(index){
        return this[index]
    }
    each(fn){
        for(let i=0;i<this.length;i++){
            const elem = this[i]
            fn(elem)
        }
    }
    on(type,fn){
        return this.each(elem=>{
            elem.addEventListener(type,fn,false)
        })
    }
}

Расширяемость подключаемых модулей

jQuery.prototype.dialog = function(info) {
    alert(info)
}

Механизм копирования:

class myJQuery extends jQuery {
    constructor(selector) {
        super(selector)
    }
    // 扩展自己的方法
    study(){
        
    }
}
  1. classКак понять суть прототипа?
  • Иллюстрация прототипов и цепочек прототипов

класс как шаблон

  • constructor
  • Атрибуты
  • метод

Код:

// 类

class Person {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    study() {
        console.log('study')
    }
}

// 通过类 new 对象,实例
const web = new Person('哪吒', 10)

класс на самом деле является функцией, видимым синтаксическим сахаром

typeof Student
结果:
"function"
typeof People
结果:
"function"

наследовать

  • extends
  • super
  • расширение, метод переопределения

прототип

Отношения прототипа:

  1. каждыйclassпоказать прототипprototype
  2. Каждый экземпляр имеет неявный прототип__proto__
  3. пример__proto__указать на соответствующийclassизprototype

Сеть прототипов

console.log(Student.prototype.__proto__)
console.log(People.prototype)
console.log(People.prototype === Student.prototype.__proto__)

Типовое решение instanceof

[] instanceof Array // true
[] instanceof Object // true
{} instanceof Object // true

размах, закрытие

  • thisКак получить значение в различных сценариях применения?
  • почеркbindфункция
  • Сценарии применения замыканий в реальной разработке с примерами

Создайте 10 тегов, нажмите, чтобы открыть соответствующий серийный номер

let i, a
for(i=0; i<10; i++) {
    a=document.createElement('a')
    a.innerHTML = i + '<br>'
    a.addEventListener('click', function(e){
        e.preventDefault()
        alert(i)
    })
    document.body.appendChild(a)
}

сфера

Очки охвата:

  1. глобальная область
  2. объем функции
  3. Область блока (новое в es6)

Код:

let a = 0
function fn1() {
    let a1 = 100
    function fn2() {
        let a2 = 200
        function fn3() {
            let a3 = 300
            return a+a1+a2+a3
        }
        fn3()
    }
    fn2()
}
fn1()

область действия блока

if(true) {
    let x=100
}
console.log(x) // 会报错

свободная переменная

Если переменная не определена в текущей области видимости, но используется, ищите ее в области видимости верхнего уровня, слой за слоем, пока не найдете.Если она не будет найдена в глобальной области видимости, будет сообщено об ошибке.xx is not defined

Закрытие

Производительность закрытия:

  1. функция передается как параметр
  2. Функция возвращается как возвращаемое значение

сделать простойcacheинструмент

Замыкания скрывают данные

function createCache() {
    const data={}
    // 闭包中的数据,被隐藏,不被外界访问
    return {
        set: function(key,val) {
            data[key] = val
        },
        get: function(key){
            return data[key]
        }
    }
}

const c = createCache()
c.set('a', 100)
console.log(c.get('a'))

функция как возвращаемое значение

function create(){
    let a = 100
    return function(){
        console.log(a)
    }
}
let fn = create()
let a = 200
fn()

результат:

100

функция как параметр

function print(fn) {
    let a = 200
    fn()
}

let a = 100
function fn(){
    console.log(a)
}
print(fn)

результат:

100

Поиск всех свободных переменных находится в том месте, где функция определена, в верхней области видимости, а не там, где она выполняется.

this

  1. называется нормальной функцией
  2. использоватьcall,apply,bindназываться
  3. вызывается как метод объекта
  4. существуетclassметод называется
  5. стрелочная функция

thisКакое значение принимать, определяется при выполнении функции, а не при ее определении.

callнаправление,bindвернет новую функцию

Код:

function fn1(){
    console.log(this)
}
fn1() // window

fn1.call({x:10}) // {x:10}

const fn2 = fn1.bind({x:20})
fn2() // {x:20}

Код:

const Jeskson = {
    name: 'web',
    sayHi() {
        // this是指当前对象
        console.log(this)
    },
    wait(){
        setTimeout(function(){
            // this === window
            console.log(this)
        }
    }
}

Код:

const Jeskson = {
    name: 'web',
    sayHi() {
        // this是指当前对象
        console.log(this)
    },
    wait() {
        setTimeout(()=>{
          // this指当前对象
          console.log(this)
        })
    }
}

Код:

class People {
    constructor(name){
        this.name = name
        this.age = 20
    }
    sayHi(){
        console.log(this)
    }
}
const Jeskson = new People('web')
Jeskson.sayHi() // Jeskson 对象

почеркbindфункция

Function.prototype.bind1 = function(){
    // 将参数解析为数组
    const args = Array.prototype.slice.call(arguments)
    // 获取this
    const t = args.shift()
    const self = this // 当前函数
    // 返回一个函数
    return function() {
        // 执行原函数,并返回结果
        return self.apply(t, args)
    }
}

Код:

function fn1(a,b,c) {
    console.log('this',this)
    console.log(a,b,c)
    return 'this is fn1'
}

const fn2 = fn1.bind ({x:100},10,20,30)
const res = fn2()
console.log(res)

Chrome:

fn1.hasOwnProperty('bind')
//false
fn1.__proto__ == Function.prototype
// true
Function.prototype.apply/call/bind

Асинхронный, однопоточный

  1. В чем разница между синхронным и асинхронным?
  2. для рукописного вводаPromiseзагрузить изображение
  3. Каковы сценарии, в которых внешний интерфейс использует асинхронность?

Код:

// setTimeout笔试题
console.log(1)
setTimeout(function(){
    console.log(2)
},1000)
console.log(3)
setTimeout(function(){
    console.log(4)
},0)
console.log(5)
  1. однопоточный и асинхронный
  2. Сценарии применения
  3. callback hellиPromise

JS — это однопоточный язык, который может выполнять только одно действие за раз. браузер иnodejsслужба поддержкиjsзапустить процесс какweb workerРендеринг JS и DOM использует один и тот же поток.

асинхронный:

console.log(100)
setTimeout(function(){
    console.log(200)
},1000)
console.log(300)

Синхронизировать

console.log(100)
alert(200)
console.log(300)

разница между асинхронным и синхронным

  1. на основеjsэто однопоточный язык
  2. Асинхронный не блокирует выполнение кода
  3. Синхронизация блокирует выполнение кода

для рукописного вводаPromiseзагрузить изображение

function loadImg(src) {
    return new Promise(
        (resolve, reject) => {
            const img = document.createElement('img')
            img.onload = () => {
                resolve(img)
            }
            img.onerror = () => {
                const err = new Error(`图片加载失败 ${src}`)
                reject(err)
            }
            img.src = src
        }
    )
}

const url = ''
loadImg(url).then(img => {
    console.log(img.width)
    return img
}).then(img => {
    console.log(img.height)
}).catch(ex=>console.error(ex))

асинхронный - один поток

  1. Разница между одиночным потоком и асинхронным, асинхронным и синхронным
  2. Сценарии внешнего интерфейса асинхронного приложения
  3. Promiseрешатьcallback hell

асинхронный обратный вызов

асинхронно, с обратным вызовомcallbackфункциональная форма

Асинхронный — сценарий приложения

  1. сетевой запрос
  2. задача на время

Первый сетевой запрос, такой какajaxЗагрузка изображения, вторая задача по времени, напримерsetTimeout.

//ajax
console.log('start')
$.get('./data.json', function(data1){
  console.log(data1)  
})
console.log('end')

загрузка изображения

console.log('start')
let img = document.createElement('img')
img.onload = function() {
    console.log('loaded')
}
img.src="/xxx.png"
console.log('end')

Сценарии применения кода:

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

// setInterval
console.log(100)
setInterval(function(){
    console.log(200)
},1000)
console.log(300)

Асинхронное обещание

PromiseКод:

function getData(url){
    return new Promise((resolve, reject) => {
        $.ajax({
            url,
            success(data) {
                resolve(data)
            },
            error(err) {
                reject(err)
            }
        })
    }
}

Promise

const url1 = '/data1.json'
const url2 = '/data2.json'
const url3 = '/data3.json'
getData(url1).then(data1=>{
    console.log(data1)
    return getData(url2)
}).then(data2 => {
    console.log(data2)
    return getData(url3)
}).then(data3 => {
    console.log(data3)
}).catch(err => console.error(err))

calback hell, ад обратного звонка

Код:

// 获取第一个数据
$.get(url1, (data1) => {
    console.log(data1)
    
    // 获取第二个数据
    $.get(url2, (data2) => {
        console.log(data2)
        
        // 获取第三个数据
        $.get(url3, (data3) => {
            console.log(data3)
            // 还可能获取更多的数据
        })
    })
})

ДОМ, БОМ

Манипуляции с домом, манипуляции с элементами дома на веб-страницах, текст в браузерах, изображения

Операция Bom, работа с некоторыми вещами в браузере, навигация в браузере, адрес и т. Д.

привязка событий, ajax, хранилище

ДОМ,Document Object Model

  1. Какой структурой данных является DOM
  2. Общие API для манипулирования DOM
  3. Разница между атрибутом и свойством

DOMСуть работы узла, работы структуры,DOMпредставление

xml— расширяемый язык разметки, способный описывать данные любой структуры,htmlявляется конкретнымxml.

DOMПо сути, это дерево.

  • ПолучатьDomузел
  • attribute
  • property

ПолучатьDOMузел

const div1 = document.getElementById('div1') // 元素

const divList = document.getElementsByTagName('div') // 集合

console.log(divlist.length)
console.log(divList[0])

const containerList = document.getElementsByClassName('.container') // 集合

const pList = document.querySelectorAll('p') // 集合

DOMузлаproperty

const pList = document.querySelectorAll('p');
const p = pList[0]
console.log(p.style.width) // 获取样式
p.style.width='100px' // 修改样式
console.log(p.className) // 获取class
p.className='p1' // 修改class
// 获取nodeName 和 nodeType
console.log(p.nodeName)
console.log(p.nodeType)

propertyиattribute

propertyИзменение свойств объекта не отразитсяhtmlв структуре

attributeИсправлятьhtmlсвойства, изменитсяhtmlструктура

Оба могут вызватьDOMперерисовать

DOMСтруктурные манипуляции

  1. Добавить/вставить узел
  2. Получить список дочерних элементов, получить родительский элемент
  3. удалить дочерний элемент

Добавить, вставить узел

const div1 = document.getElementById('div1')
// 添加新节点
const p1 = document.createElement('p')
p1.innerHTML = 'this is p1'
div1.appendChild(p1)
const p2 = document.getElementById('p2')
div1.appendChild(p2)

Получить список дочерних элементов и получить родительский элемент

//获取子元素列表
const div1 = document.getElementById('div1')
const child = div1.childNodes

//获取父元素
const div1 = document.getElementById('div1')
const parent = div1.parentNode

удалить узел

const div1 = document.getElementById('div1')
const child = div1.childNodes
div1.removeChild(child[0])

Производительность DOM

DOMОперация будет потреблять ЦП, избегайте частых, даDOMкэш запросов

DOMкэш запросов

// 不缓存DOM查询结果
for(let=0; i<document.getElementsByTagName('p').length;i++) {
    // 每次循环,都会计算length,频繁进行dom查询
}
// 缓存dom查询结果
const pList = document.getElementsByTagName('p')
const length = pList.length
for(let i = 0; i<length; i++){
    // 缓存length,只进行一次dom查询
}

Замените частые операции на одноразовые операции

const listNode = document.getElementById('list')

// 创建一个文档片段,此时没有插入到dom树中
const frag = document.createDocumentFragment();

// 执行插入
for(let x=0; x<10; x++) {
    const li = document.createElement("li")
    li.innerHTML="List item"+x
    frag.appendChild(li)
}

// 都完成后,再插入到dom树中
listNode.appendChild(frag)

проблема:

  1. domкакая структура данных
  2. domЧасто используемые операцииapi
  3. attrиpropertyразница
  4. Вставить сразу несколькоdomNode, рассмотрите проблемы с производительностью

propertyиattributeразница

  1. propertyИзменение свойств объекта не отразитсяhtmlв структуре
  2. attributeИсправлятьhtmlсвойства, изменитсяhtmlструктура

Оба могут вызватьdomперерисовать

  • domПрирода
  • domРабота узла
  • domСтруктурные манипуляции
  • domпредставление

BOMдействоватьbrowser object model

Вопрос: Как определить тип браузера

Проблема: Разбор и разборкаurlРазличные части

BOM navigator

Код:

//navigator
const ua = navigator.userAgent
const isChrome = ua.indexOf('Chrome`)
console.log(isChrome)

Привязка событий и всплывающие сообщения о событиях

  1. функция прослушивания событий
  2. Описать поток всплывающих сообщений о событиях

BOM screen

Код:

//screen
console.log(screen.width)
console.log(screen.height)

BOM location

BOM history

ajax

  1. написать простойajax
  2. Общие реализации междоменного

ajax XMLHttpRequest

Код:

//get请求
const xhr = new XMLHttpRequest()
xhr.open('GET','/api', true)
xhr.onreadystatechange = function() {
    // 这里的函数异步执行
    if (xhr.readyState === 4){
        if(xhr.state === 200) {
            alert(xhr.responseText);
        }
    }
}
xhr.send(null)

код состояния ajax

xhr.readyState

  • 0 означает, что еще не звонилиsend()метод
  • 1 называетсяsend()метод, запрос отправляется
  • 2 дляsend()Выполнение метода завершено, и все содержимое ответа получено.
  • 3 анализирует содержимое ответа
  • 4 — завершенный анализ содержимого ответа, который можно вызвать на клиенте.

xhr.status

  • 2xx означает, что запрос был успешно обработан
  • 3xx указывает, что требуется перенаправление, и браузер переходит напрямую
  • 4xx означает ошибку запроса клиента
  • 5xx означает ошибку на стороне сервера

перекрестный домен ajax

  1. Что такое кросс-происхождение, политика одного и того же происхождения
  2. JSONP
  3. CORS, поддержка на стороне сервера

Политика одного и того же происхождения — между доменами

ajaxПри запросе браузер запрашивает текущую страницу иserverдолжны быть гомологичны

Гомология: протокол, доменное имя, порт, непротиворечивый

код

function ajax(url) {
    const p = new Promise((resolve, reject)=>{
        const xhr = new XMLHttpRequest()
        xhr.open('GET',url,true)
        xhr.onreadystatechange=function(){
            if(xhr.readyState === 4){
                if(xhr.status===2000) {
                    resolve(
                        JSON.parse(xhr.responseText)
                    )
                }else if(xhr.status === 404) {
                    reject(new Error('404 not found'))
                }
            }
        }
        xhr.send(null)
    }
}

событие

  • привязка события
  • всплывающее окно событий
  • агент событий

привязка событий

Код:

const btn = document.getElementById('btn1')
btn.addEventListener('click',event=>{
    console.log('clicked')
})

Код:

//通用的绑定函数
function bindEvent(elem, type, fn)
    elem.addEventListener(type,fn)
}

const a = document.getElementById('web')
bindEvent(a, 'click', e=>{
    e.preventDefault()
    alert('clicked')
})

событие - бурление

Код:

<body>
<div id="div1">
<p id="p1">web</p>
<p id="p2">it</p>
<p id="p3">it</p>
<p id="p4">it</p>
</div>
<div id="div2">
<P id="p5">it</p>
<p id="p6">it</p>
</div>
</body>

const p1 = document.getElementById('p1')
const body = document.body
bindEvent(p1, 'click', e=>{
    e.stopPropagation() // 阻止冒泡
    alert('web')
})
bindEvent(body, 'click', e=>{
    alert('it')
})

агент событий

Код:

<div id="div1">
<a href="#">a1</a>
<a href="#">a2</a>
</div>
<button>点击
</button>

const div1 = document.getElementById('div1')
div1.addEventListener('click', e=>{
 const target = e.target
 if(e.nodeName === 'A') {
     alert(target.innerHTML)
 }
})

Прокси-сервер событий, который может уменьшить использование памяти браузера.

Общая функция привязки событий

const btn1 = document.geteElementById('btn1')
bindEvent(btn1,'click',event=>{
    // console.log(event.target) // 获取触发的元素
    event.preventDefault() // 阻止默认行为
    alert('clicked')
})

const div2 = document.getElementById('div2')
bindEvent(div2,'click',event=>{
    event.preventDefault()
    const target = event.target
    if(target.nodeName === 'A') {
        alert(target.innerHTML)
    }
})

Код:

function bindEvent(elem, type, selector, fn) {
    if(fn==null) {
        fn = selector
        selector = null
    }
    elem.addEventListener(type, e=>{
        let target
        if(selector) {
            // 需要代理
            target = e.target
            if(target.matches(selector)){
                fn.call(target, e)
            }
        } else {
            // 不需要代理
            fn(e)
        }
    })
}

место хранения

cookie,localStorage,sessionStorageразница

  1. localStorageДанные сохраняются навсегда, если код не будет удален вручную
  2. sessionStorageДанные существуют только в текущем сеансе и очищаются при закрытии браузера.

общее использованиеlocalStorageбудет больше

файлы cookie для хранения

  • Размер хранилища, до 4кб
  • httpПри запросе его нужно отправить на сторону сервера для увеличения объема запрашиваемых данных
  1. локальное хранилище и хранилище сессий
  2. html5Специально разработан для хранения, до 5M
  3. apiПростой в использованииsetItem,getItem

не последуетhttpзапрос отправлен

хранилище - локальное хранилище

Код:

localStorage.setItem('a',100)
localStorage.getItem('a')

хранилище - sessionStorage

Код:

sessionStorage.setItem('a',100)
sessionStorage.getItem('a')

среда разработки

  1. git
  2. инструменты отладки
  3. захват пакетов
  4. webpack babel
  5. Общие команды Linux

git

  • Крупномасштабные проекты требуют совместной разработки несколькими людьми, и необходимо использовать git.

Код: Общие команды git

git add .
git checkout xxx
git commit -m 'xxx'
git push origin master
git pull origin master

git branch
git checkout -b xxx / git checkout xx
git merge xxx

отлаживать

инструмент отладки хрома

  1. Elements
  2. Network
  3. Console
  4. Application
  5. debugger

настроить, захватить

Страница мобильного терминала h5, для просмотра сетевых запросов необходимо использовать инструменты для перехвата пакетов

windowsобщее использованиеfiddler

вебпак и бабел

Код:

const path = require('path')

module.exports = {
    mode: 'development',
    entry: path.join(__dirname, 'src', 'index.js'),
    output: {
        filename: 'bundle.js',
        path: path.join(__dirname,'dist')
    }
}

линукс команда

Онлайн-машины, как правило, Linux

Код:

ssh work
ls

rm -rf abc
cd dist
mv index.html index1.html

rm a1.js
touch d.js
rm -rf d.js

Рабочая среда

  1. Операционная среда — браузерserverконец тамnodejs
  2. процесс загрузки веб-страницы
  3. оптимизация производительности
  4. Безопасность

Загрузка страницы и процесс рендеринга

  1. ввод отurlВесь процесс рендеринга страницы
  2. Разница между window.onLoad и DOMContentLoaded
  • Форма загружаемого ресурса
  • Процесс загрузки ресурсов
  • Процесс рендеринга страницы

Форма ресурса:htmlкод, мультимедийные файлы, такие как изображения, видео и т. д.,javascript,css.

Процесс загрузки:dnsдоменное имя,ipадрес. браузер в соответствии сipадрес к серверуhttpпросить.

серверная обработкаhttpзапрос и возврат в браузер.

процесс рендеринга, согласноhtmlгенерация кодаdom tree,в соответствии сcssгенерация кодаcssom. разговариватьdom treeиcssomИнтегрированный маршрутrender tree.

в соответствии сrender treeвизуализировать страницу, столкнутьсяscriptПриостановить рендеринг, сначала загрузить и выполнитьjsкод, заполните, прежде чем продолжить.

рендеринг страницы

window.onLoadиDOMContentLoaded

Код:

window.addEventListener('load',function(){
    // 页面的全部资源加载完才会执行,包括图片,视频等
})
document.addEventListener('DOMContentLoad',function(){
  // dom渲染完既可执行,此时图片,视频还可能没有加载完 
})
  1. window.onloadЭто может быть выполнено только после загрузки всех ресурсов, включая изображения.
  2. DOMContentLoaded DOMРендеринг завершен, картинка может быть еще не загружена

оптимизация производительности

Почерк против сотрясений, дросселирование

в общем:

  1. Используйте больше памяти, кэша или другие методы
  2. Уменьшите объем вычислений процессора и сократите время загрузки сети

Ускорьте загрузку, рендеринг и уменьшите размер ресурсов. сократить количество посещений, консолидировать код,ssrРендеринг на стороне сервера, кэширование.

правильноdomЗапросы кешируются, частоdomоперации, объединить и вставитьdomструктура, дросселированиеthrottleСтабилизаторdebounce.

ssr

Рендеринг на стороне сервера, совместная загрузка веб-страниц и данных и совместный рендеринг

Не ssr, сначала загрузите веб-страницу, затем загрузите данные, а затем отобразите данные.

ленивая загрузка

Код:

<img id="img1" src="preview.png" data-realsrc="abc.png"/>
<script type="text/javascript">
var img1 = document.getElementById('img1')
img1.src = img1.getAttribute('data-realsrc')
</script>

защита от дрожания

  1. Слушайте поле ввода и запускайте событие изменения при изменении текста
  2. Использование события keyup напрямую будет часто вызывать событие изменения

Anti-shake, событие изменения будет запущено только тогда, когда пользовательский ввод завершится или будет приостановлен.

Код:

const input1 = document.getElementById('input1')
input1.addEventListener('keyup', function(){
    console.log(input1.value)
}}

Код:

const input1 = document.getElementById('input1')
let timer = null
input1.addEventListener('keyup', function(){
    if(timer){
        clearTimeout(timer)
    }
    timer = setTimeout(()=>{
        // 模拟触发change事件
        console.log(input1.value)
        // 清空定时器
        timer = null
    },500)
})

код защиты от дребезга:

function debounce(fn, delay = 500) {
    // timer 是闭包中的
    let timer = null
    return function() {
        if(timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(()=>{
            fn.apply(this, arguments)
            timer = null
        },delay)
    }
}

input1.addEventListener('keyup', debounce(()=>{
    console.log(input1.value)
}),600)

дросселированиеthrottle

При перетаскивании элемента вам нужно получить позицию, в которую элемент был перетащен в любое время.

Код:

const div1 = document.getElementById('div1')
let timer = null
div1.addEventListener('drag',function(e){
    if(timer){
        return
    }
    timer = setTimeout(()=>{
        console.log(e.offsetX, e.offsetY)
        timer = null
    },100)
})

Код дросселирования:

function throttle(fn, delay = 100) {
    let timer = null
    return function() {
        if(timer) {
            return
        }
        timer = setTimeout(()=>{
            fn.applay(this,arguments)
            timer = null
        },delay)
    }
}

div1.addEventListener('drag',throttle(function(e){
    console.log(e.offsetX,e.offsetY)
},200))

веб-безопасность

  1. Каковы распространенные методы атаки на веб-интерфейсе?

  2. Атака с межсайтовым запросом xss

  3. Подделка межсайтового запроса xsrf

Рабочая среда

  1. загрузка страницы: загрузка, визуализация
  2. Оптимизация производительности: оптимизация загрузки ресурсов, оптимизация рендеринга
  3. Безопасность: xss, csrf

Суммировать

Что такое переменный подъем

  1. Разница между var и let const
  2. какие типы возвращает typeof
  3. Примеры приведения и неявного преобразования типов

Разница между var и let const

var — это синтаксис es5, пусть const — это синтаксис es6, var имеет продвижение переменной

Var и Let являются переменными, const является константой и не может быть изменена.

пусть const имеет блочную область видимости, var — нет.

объекты и функции

принуждение и неявное преобразование типов

Обязательные: parseInt, parseFloat, toString и т.д.

isEqual

  1. сравнение глубины почерка
  2. Разница между split() и join()
  3. Массив, вытолкнуть, нажать, отменить сдвиг, сдвиг

lodash.isEqual

//实现如下效果
const obj1 = {a:10, b:{x:100,y:200}}
const obj2 = {a:10, b:{x:100,y:200}}
isEqual(objq,obj2) === true

Определить, является ли это объектом или массивом

Код:

function isObject(obj){
    return typeof ojb === 'object' && obj !== null
}
// 全相等
function isEqual(obj1,obj2){
    if(!isObject(obj1) || !isObject(obj2)) {
        // 值类型
        return obj1===obj2
    }
    if(obj1===obj2){
        return true
    }
    // 两个都是对象或数组,而且不相等
    const obj1key = Object.keys(obj1)
    const obj2key = Object.keys(obj2)
    
    if(obj1key.length !== obj2key.length){
        return false
    }
    for(let key in obj1){
        const res = isEqual(obj1[key],obj2[key])
        if(!res){
            return false
        }
    }
    return true
}

Разница между split() и join()

'1-2-3'.split('-') // [1,2,3]
[1,2,3].join('-') // '1-2-3'

pop, push, unshift, сдвиг массива

Что такое функция, каково возвращаемое значение и каково влияние.

pop возвращает последнее удаленное значение

push возвращает длину добавленного элемента

несместить вставку на перед, вернуть длину длину

shift удаляет самый передний и возвращает удаленное значение

  • поп, шифт-> возвращаемое значение
  • unshift, push-> длина

  1. Разница между срезом массива и сращиванием
  2. [10,20,30].map(parseInt) возвращает результат
  3. Разница между запросом ajax get и post

  • get используется для запроса, post используется для отправки
  • Параметр get наклеивается на url, а пост помещается в тело запроса

Разница между вызовом и применением

Код:

fn.call(this, p1,p2,p3)
fn.apply(this, argument)

Что такое брокер событий

Код:

const p1 = document.getElementById('p1')
const body = document.body

bindEvent(p1, 'click', e=>{
    e.stopProgation();
    alert()
})
bindEvent(body, 'click', e=>{
    alert()
})

Что такое замыкание, каковы его особенности и каковы негативные последствия

  1. Область действия и свободные переменные

Поиск свободных переменных должен быть там, где функция определена, а не там, где она выполняется.

Не используйте замыкание без разбора, переменная останется в содержимом и не будет освобождена

Закрытие:

function create() {
    let a=100
    return function(){
        console.log(a)
    }
}
let fn = create()
let a=200
fn() // 100
  1. Как остановить всплытие событий и поведение по умолчанию?
  2. Методы поиска, добавления, удаления, перемещения узлов dom
  3. Как уменьшить манипуляции домом
  • event.stopPropagation()
  • event.preventDefault()

Код:

// 新建节点
const newP = document.createElement('p')
newP.innerHTML = 'this is newP'
// 插入节点
div1.appendChild(newP)
// 移动节点
const p1 = document.getElementById('p1')
div2.appendChild(p1)
//获取父元素
console.log(p1.parentNode)

Как уменьшить манипуляции домом

  1. Кэшировать результаты запроса dom
  2. Несколько операций dom, объединенных в одну вставку

Код:

const list = document.getElementById('list')
const frag = document.createDocumentFragment()

for(let i=0; i<20; i++){
    const li = document.createElement('li')
    li.innerHTML = 'list'
    frag.appendChild(li)
}
list.appendChild(frag)

Принцип jsonp, почему это не настоящий ajax

Политика одинакового происхождения браузера и кросс-происхождение

Разница между загруженным документом и готовым

load:

Разностный ресурс страницы не будет выполняться до тех пор, пока ресурс не будет загружен

ready:

После рендеринга dom его можно запустить, но картинки, видео и т.д. не загрузились.

Разница между объявлением функции и выражением функции

объявление функции

function fn(){...}

Выражение функции:

const fn = function(){...}

Объявления функций предварительно загружаются, в то время как выражения функций не загружаются.

Разница между новым Object() и Object.create()

  • {}эквивалентnew Object(), прототип Object.prototype

Сценарий Вопрос 1

Код:

let i 
for (i = 1; i <= 3; i++) {
    setTimeout(function(){
        console.log(i)
    },0)
}

сцена 2

Код:

let a = 100
function test() {
    alert(a)
    a = 10
    alert(a)
}
test()
alert(a)

сцена 3

Метод обрезки рукописной строки для обеспечения совместимости с браузером

Наследование с Js

сцена 4

  1. Как ловить исключения в программе Js
  2. что такое json
  3. Получить текущие параметры URL страницы

Код:

try {
    // todo
}catch(error) {
    console.error(error)
}finally{
    
}

JSON — это формат данных, который по сути является строкой Формат JSON совпадает со структурой объекта js.

window.JSONглобальный объект,JSON。stringify,JSON.parse

Получить текущие параметры URL страницы

традиционный способ, найтиlocation.search

новыйapi,URLSearchParams

сцена 5

  1. Поговорите о синтаксическом анализе параметров URL в объекты js.
  2. рукописный массив
  3. Дедупликация массива

Код:

// 1
function queryToObj(){
    const res={}
    const search = location.search.substr(1)
    search.split('&').forEach(res => {
        const arr = res.split('=')
        const key = arr[0]
        const key = arr[1]
        res[key] = val
    })
}

Использование параметров URLSearchParams

function queryToObj() {
    const res = {}
    const pList = new URLSearchParams(location.search)
    pList.forEach((val,key) => {
      res[key] = val  
    })
    return res
}

рукописный массив

Код:

function flat(arr) {
    const isDeep = arr.some(item=> item instanceof Array)
    if(!isDeep) {
        return arr
    }
    const res = Array.prototype.concat.apply([],arr)
    return flat(res)
}

Дедупликация массива

Код:

function unique(arr) {
    const res=[]
    arr.forEach(item => {
        if(res.indexOf(item) < 0) {
            res.push(item)
        }
    })
    return res
}

Использовать набор

function unique(arr) {
    const set = new Set(arr)
    return [...set]
}

сцена 6

  1. рукописная глубокая копия
  2. использоватьRAF requestAnimateFrame
  3. Оптимизация производительности интерфейса

Код:

function deepClone(obj = {}) {
    if(type of obj !== 'object' || obj == null){
        return obj
    }
    let result
    if(obj instanceof Array) {
        result = []
    }else{
        result = {}
    }
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            result[key] = deepClone(obj[key])
        }
    }
    return result
}

Object.assignНе глубокая копия!

оптимизация производительности

Принцип: использовать больше памяти, кэша, сократить вычисления, сетевые запросы

Подумайте больше о загрузке страниц, рендеринге страниц, операциях со страницами и т. д.

Наконец

Добро пожаловать, чтобы добавить меня в WeChat Jeskson (xiaoda0423), тянут в техническую группу (Наггетс - фронтовые колледжи и университеты), и долго обмениваются и учатся.