передовой
Из мира просто наблюдать в тайне! ! ! Всем привет, я Король Демонов Нэчжа!
Содержание интервью
Вам нужны базовые знания 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"
наследовать
extends
super
- расширение, метод переопределения
прототип
Отношения прототипа:
- каждый
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
узел 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
Структурные манипуляции
- Добавить/вставить узел
- Получить список дочерних элементов, получить родительский элемент
- удалить дочерний элемент
Добавить, вставить узел
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
разница - Вставить сразу несколько
dom
Node, рассмотрите проблемы с производительностью
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
отлаживать
инструмент отладки хрома
Elements
Network
Console
Application
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
Рабочая среда
- Операционная среда — браузер
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
), тянут в техническую группу (Наггетс - фронтовые колледжи и университеты), и долго обмениваются и учатся.