передовой
Из мира просто наблюдать в тайне! ! ! Всем привет, я Король Демонов Нэчжа!
Содержание интервью
Вам нужны базовые знания HTML и CSS, базовый синтаксис JavaScript и ES6, любопытство.
- Вопросы для интервью с начинающим JS
- JS Web API, среда разработки, среда выполнения
- Прототипы, область действия, асинхронность, Ajax, события, веб-пакеты и т. д.
Наблюдайте за тестовой площадкой для всех вопросов интервью
- Учимся разбираться в схеме системы знаний
- Определить систему знаний и осознанно овладеть ею
- Хорошо резюмирует идеи, принципы
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
преобразование типов
- Кроме
0Все числа, кроме , преобразуются в логические значения.true. - Кроме
“ ”Все символы, кроме , преобразуются в логические значения.true. -
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
рукописная глубокая копия
- Определите, является ли это типом значения или ссылочным типом
- Определите, является ли это массивом или объектом
- рекурсия
Код:
// 浅拷贝
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
прототип, цепь прототипов
- Как определить, является ли переменная массивом?
a instanceof Array
- написать простой
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(){
}
}
-
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"
наследовать
extendssuper- расширение, метод переопределения
прототип
Отношения прототипа:
- каждый
classпоказать прототипprototype - Каждый экземпляр имеет неявный прототип
__proto__ - пример
__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)
}
сфера
Очки охвата:
- глобальная область
- объем функции
- Область блока (новое в 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
Закрытие
Производительность закрытия:
- функция передается как параметр
- Функция возвращается как возвращаемое значение
сделать простой
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
- называется нормальной функцией
- использовать
call,apply,bindназываться - вызывается как метод объекта
- существует
classметод называется - стрелочная функция
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
Асинхронный, однопоточный
- В чем разница между синхронным и асинхронным?
- для рукописного ввода
Promiseзагрузить изображение - Каковы сценарии, в которых внешний интерфейс использует асинхронность?
Код:
// setTimeout笔试题
console.log(1)
setTimeout(function(){
console.log(2)
},1000)
console.log(3)
setTimeout(function(){
console.log(4)
},0)
console.log(5)
- однопоточный и асинхронный
- Сценарии применения
-
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)
разница между асинхронным и синхронным
- на основе
jsэто однопоточный язык - Асинхронный не блокирует выполнение кода
- Синхронизация блокирует выполнение кода
для рукописного ввода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))
асинхронный - один поток
- Разница между одиночным потоком и асинхронным, асинхронным и синхронным
- Сценарии внешнего интерфейса асинхронного приложения
-
Promiseрешатьcallback hell
асинхронный обратный вызов
асинхронно, с обратным вызовомcallbackфункциональная форма
Асинхронный — сценарий приложения
- сетевой запрос
- задача на время
Первый сетевой запрос, такой как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
- Какой структурой данных является DOM
- Общие API для манипулирования DOM
- Разница между атрибутом и свойством
DOMСуть работы узла, работы структуры,DOMпредставление
xml— расширяемый язык разметки, способный описывать данные любой структуры,htmlявляется конкретнымxml.
DOMПо сути, это дерево.
- Получать
Domузел attributeproperty
Получать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Структурные манипуляции
- Добавить/вставить узел
- Получить список дочерних элементов, получить родительский элемент
- удалить дочерний элемент
Добавить, вставить узел
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)
проблема:
-
domкакая структура данных -
domЧасто используемые операцииapi -
attrиpropertyразница - Вставить сразу несколько
domNode, рассмотрите проблемы с производительностью
propertyиattributeразница
-
propertyИзменение свойств объекта не отразитсяhtmlв структуре -
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)
Привязка событий и всплывающие сообщения о событиях
- функция прослушивания событий
- Описать поток всплывающих сообщений о событиях
BOM screen
Код:
//screen
console.log(screen.width)
console.log(screen.height)
BOM location
BOM history
ajax
- написать простой
ajax - Общие реализации междоменного
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
- Что такое кросс-происхождение, политика одного и того же происхождения
- JSONP
- 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разница
-
localStorageДанные сохраняются навсегда, если код не будет удален вручную -
sessionStorageДанные существуют только в текущем сеансе и очищаются при закрытии браузера.
общее использованиеlocalStorageбудет больше
файлы cookie для хранения
- Размер хранилища, до 4кб
-
httpПри запросе его нужно отправить на сторону сервера для увеличения объема запрашиваемых данных
- локальное хранилище и хранилище сессий
-
html5Специально разработан для хранения, до 5M -
apiПростой в использованииsetItem,getItem
не последуетhttpзапрос отправлен
хранилище - локальное хранилище
Код:
localStorage.setItem('a',100)
localStorage.getItem('a')
хранилище - sessionStorage
Код:
sessionStorage.setItem('a',100)
sessionStorage.getItem('a')
среда разработки
- git
- инструменты отладки
- захват пакетов
- webpack babel
- Общие команды 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
отлаживать
инструмент отладки хрома
ElementsNetworkConsoleApplicationdebugger
настроить, захватить
Страница мобильного терминала 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
Рабочая среда
- Операционная среда — браузер
serverконец тамnodejs - процесс загрузки веб-страницы
- оптимизация производительности
- Безопасность
Загрузка страницы и процесс рендеринга
- ввод от
urlВесь процесс рендеринга страницы - Разница между 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渲染完既可执行,此时图片,视频还可能没有加载完
})
-
window.onloadЭто может быть выполнено только после загрузки всех ресурсов, включая изображения. -
DOMContentLoaded DOMРендеринг завершен, картинка может быть еще не загружена
оптимизация производительности
Почерк против сотрясений, дросселирование
в общем:
- Используйте больше памяти, кэша или другие методы
- Уменьшите объем вычислений процессора и сократите время загрузки сети
Ускорьте загрузку, рендеринг и уменьшите размер ресурсов. сократить количество посещений, консолидировать код,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>
защита от дрожания
- Слушайте поле ввода и запускайте событие изменения при изменении текста
- Использование события 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))
веб-безопасность
-
Каковы распространенные методы атаки на веб-интерфейсе?
-
Атака с межсайтовым запросом xss
-
Подделка межсайтового запроса xsrf
Рабочая среда
- загрузка страницы: загрузка, визуализация
- Оптимизация производительности: оптимизация загрузки ресурсов, оптимизация рендеринга
- Безопасность: xss, csrf
Суммировать
Что такое переменный подъем
- Разница между var и let const
- какие типы возвращает typeof
- Примеры приведения и неявного преобразования типов
Разница между var и let const
var — это синтаксис es5, пусть const — это синтаксис es6, var имеет продвижение переменной
Var и Let являются переменными, const является константой и не может быть изменена.
пусть const имеет блочную область видимости, var — нет.
объекты и функции
принуждение и неявное преобразование типов
Обязательные: parseInt, parseFloat, toString и т.д.
isEqual
- сравнение глубины почерка
- Разница между split() и join()
- Массив, вытолкнуть, нажать, отменить сдвиг, сдвиг
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-> длина
- Разница между срезом массива и сращиванием
- [10,20,30].map(parseInt) возвращает результат
- Разница между запросом 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()
})
Что такое замыкание, каковы его особенности и каковы негативные последствия
- Область действия и свободные переменные
Поиск свободных переменных должен быть там, где функция определена, а не там, где она выполняется.
Не используйте замыкание без разбора, переменная останется в содержимом и не будет освобождена
Закрытие:
function create() {
let a=100
return function(){
console.log(a)
}
}
let fn = create()
let a=200
fn() // 100
- Как остановить всплытие событий и поведение по умолчанию?
- Методы поиска, добавления, удаления, перемещения узлов dom
- Как уменьшить манипуляции домом
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)
Как уменьшить манипуляции домом
- Кэшировать результаты запроса dom
- Несколько операций 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
- Как ловить исключения в программе Js
- что такое json
- Получить текущие параметры URL страницы
Код:
try {
// todo
}catch(error) {
console.error(error)
}finally{
}
JSON — это формат данных, который по сути является строкой Формат JSON совпадает со структурой объекта js.
window.JSONглобальный объект,JSON。stringify,JSON.parse
Получить текущие параметры URL страницы
традиционный способ, найтиlocation.search
новыйapi,URLSearchParams
сцена 5
- Поговорите о синтаксическом анализе параметров URL в объекты js.
- рукописный массив
- Дедупликация массива
Код:
// 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
- рукописная глубокая копия
- использовать
RAF requestAnimateFrame - Оптимизация производительности интерфейса
Код:
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), тянут в техническую группу (Наггетс - фронтовые колледжи и университеты), и долго обмениваются и учатся.