Заявление: МООКСоветы по собеседованию на Front-End JavaScriptЗаметки предназначены только для просмотра и обзора, а не для коммерческого использования.
BAT Дэниел проведет вас через основное интервью по интерфейсу JavaScript
Глава 1 Введение в курс
1-1 Введение в курс
Базовые знания
- Прототип, цепь прототипов
- размах, закрытие
- Асинхронный, однопоточный
JS API
- Манипуляции с DOM
- Ajax
- привязка события
среда разработки
- Управление версиями
- модульный
- упаковочный инструмент
Рабочая среда
- Рендеринг страницы
- оптимизация производительности
1-2 Предисловие
Об интервью
- Базовый инженер - Основы
- Старший инженер - Опыт реализации проектов
- Архитектор - Решения
На основе
- Самосовершенствование для инженеров — основы
- Прочная основа позволит вам эффективно изучать новые технологии
1-3 Несколько вопросов интервью
Начнем с нескольких вопросов интервью
- используется в JS
typeofКакие типы доступны? - когда использовать
===, когда использовать==? -
window.onloadа такжеDOMContentLoadedразница? - Создайте 10 с помощью JS
<a>Метка, при нажатии на которую появится соответствующий серийный номер - Кратко опишите, как реализовать загрузчик модулей, который реализует что-то вроде
require.jsосновные функции - Реализовать случайную сортировку массивов
думать
- Когда вам задают вопрос на собеседовании, что вы видите в первую очередь?
- Как вы смотрите на бескрайнее море вопросов, найденных в Интернете?
- Как ответить на следующие вопросы интервью?
1-4 Как получить все вопросы интервью
Заключение предыдущего раздела размышления о проблеме
- Когда вам задают вопрос на собеседовании, что вы видите в первую очередь? -испытательный центр
- Как вы смотрите на бескрайнее море вопросов, найденных в Интернете? -изменить без изменений
- Как ответить на следующие вопросы интервью? -тема к знаниям к теме
Очки знаний по теме исследования
- используется в JS
typeofКакие типы доступны? Тестовый сайт:Тип переменной JS - когда использовать
===, когда использовать==? Тестовый сайт:принуждение -
window.onloadа такжеDOMContentLoadedразница? Тестовый сайт:процесс рендеринга в браузере - Создайте 10 с помощью JS
<a>Метка, при нажатии на которую появится соответствующий серийный номер Тестовый сайт:объем - Кратко опишите, как реализовать загрузчик модулей, который реализует что-то вроде
require.jsосновные функции Тестовый сайт:Модульный JS - Реализовать случайную сортировку массивов Тестовый сайт:Базовый алгоритм JS
Глава 2. Основы JS (Часть 1)
2-1 Типы переменных и вычисления - 1
тема
- используется в JS
typeofКакие типы доступны? - когда использовать
===, когда использовать==? - Какие есть встроенные функции в JS?
- Каковы типы переменных JS в соответствии с их методами хранения и описанием их характеристик?
- Как понять JSON?
Точка знаний
- тип переменной
- Расчет переменных
тип переменной
- тип значения, ссылочный тип
-
typeofоператор
тип значения
let a = 100
let b = a
a = 200
console.log(b) // 100
тип ссылки
let a = { age: 20 }
let b = a
b.age = 21
console.log(a.age) // 21
typeofоператор
typeof undefined // "undefined"
typeof 'abc' // "string"
typeof 123 // "number"
typeof true // "boolean"
typeof {} // "object"
typeof [] // "object"
typeof null // "object"
typeof console.log // "function"
Переменная оценка - принуждение
Конкатенация строк
let a = 100 + 10 // 110
let b = 100 + '10' // "10010"
==оператор
100 == '100' // true
0 == '' // true
null = undefined // true
ifутверждение
let a = true
if (a) {}
let b = 100
if (b) {}
let c = ''
if (c) {}
Логические операторы
console.log(10 && 0) // 0
console.log('' || 'abc') // "abc"
console.log(!window.abc) // true
// 判断一个变量会被当做 true 还是 false
let a = 100
console.log(!!a) // true
2-2 Типы переменных и вычисления - 2
отвечать
используется в JStypeofКакие типы доступны?
отвечать:undefined,string,number,boolean,object,function,symbol
let sym = Symbol('commet')
console.log(typeof sym) // "symbol"
когда использовать===, когда использовать==?
Ответ: Определить, существует ли свойство объекта.nullможно использовать, когда==, так как исходный код jQuery использует
if (obj.a == null) {
// 这里相当于 obj.a === null || obj.a === undefined 的简写形式
// 这是 jQuery 源码中推荐的写法
}
Какие есть встроенные функции в JS?
Ответ: Объекты класса инкапсуляции данных, включаяString,Number,Boolean,Object,Array,Function,Date,RegExp,Error
Каковы типы переменных JS в соответствии с их методами хранения и описанием их характеристик?
Ответ: тип значения и ссылочный тип, в одном хранится значение, в другом хранится ссылочный адрес, а ссылочный тип может бесконечно расширять свойства.
2-3 Типы переменных и вычисления - 3
Как понять JSON?
Ответ: JSON — это просто объект JS и формат данных.
JSON.stringify({ a: 10, b: 20 })
JSON.parse('{"a":10,"b":20}')
2-4 Типы переменных и расчеты — демонстрация кода
ifВ заявлении есть условиеfalseЧто за ситуация?
отвечать:'',0,NaN,false,null,undefined
Что такое встроенные объекты в JS?
отвечать:JSON,Math
2-5 typeof symbol
let s = Symbol()
typeof s // "symbol"
let s1 = Symbol()
console.log(s === s1) // false
let s2 = Symbol('s2s2')
console.log(s2) // Symbol(s2s2)
let s3 = s2
console.log(s3 === s2) // true
let sym1 = Symbol('111')
let sym2 = Symbol('222')
let obj = { [sym1]: 'hello world' }
obj[sym2] = 123
console.log(obj) // {Symbol(111): "hello world", Symbol(222): 123}
console.log(obj[sym1]) // "hello world"
console.log(obj[sym2]) // 123
2-6 прототипов и цепочек прототипов
тема
- Как точно определить, является ли переменная типом массива
- Напишите пример наследования цепочки прототипов
- описывать
newпроцесс объекта - Как использовать цепочку прототипов в zepto или другом исходном коде фреймворка
Точка знаний
- Конструктор
- Конструктор - Расширение
- Правила и примеры прототипов
- Сеть прототипов
instanceof
Конструктор
function Foo(name, age) {
this.name = name
this.age = age
this.class = 'class__1'
// return this // 默认有这一行
}
let f = new Foo('negrochn', 18)
// let f2 = new Foo('lexiaodai', 17) // 创建多个对象
Конструктор - Расширение
let a = {} // 其实是 let a = new Object() 的语法糖
let b = [] // 其实是 let b = new Array() 的语法糖
function Foo() {} // 其实是 let Foo = new Function()
// 使用 instanceof 判断一个函数是否是一个变量的构造函数
console.log(b instanceof Array) // true
2-7 Прототипы и цепочки прототипов - 5 правил прототипов
5 правил прототипа
- Все ссылочные типы (массивы, объекты, функции) имеют объектные свойства, которые можно свободно расширять (кроме
nullза пределами) - Все ссылочные типы (массивы, объекты, функции) имеют
__proto__(Неявный прототип), значением свойства является простой объект - Все функции имеют
prototype(Явный прототип), значение свойства также является обычным объектом - все ссылочные типы (массивы, объекты, функции),
__proto__Значение свойства указывает на его конструкторprototypeзначение атрибута - При попытке получить атрибут объекта, если сам объект не имеет этого атрибута, он перейдет к своему
__proto__(т.е. его конструкторprototype) найти
// 原则 1
let obj = {}
obj.a = 100
let arr = []
arr.a = 100
function fn() {}
fn.a = 100
// 原则 2
console.log(obj.__proto__)
console.log(arr.__proto__)
console.log(fn.__proto__)
// 原则 3
console.log(fn.prototype)
// 原则 4
console.log(obj.__proto__ === Object.prototype) // true
// 构造函数
function Foo(name) {
this.name = name
}
Foo.prototype.alertName = function() {
alert(this.name)
}
// 创建实例
let f = new Foo('negrochn')
f.printName = function() {
console.log(this.name)
}
// 测试
f.printName()
f.alertName() // 原则 5
2-8 прототипов и цепочек прототипов - добавлено 5 правил для прототипов 2 очка
for (let key in f) {
// 高级浏览器已经在 for in 中屏蔽了来自原型的属性
// 但是这里建议大家还是加上这个判断,保证程序的健壮性
if (f.hasOwnProperty(key)) {
console.log(key)
}
}
2-9 Прототипы и цепочки прототипов - Цепочки прототипов
// 构造函数
function Foo(name) {
this.name = name
}
Foo.prototype.alertName = function() {
alert(this.name)
}
// 创建实例
let f = new Foo('negrochn')
f.printName = function() {
console.log(this.name)
}
// 测试
f.printName()
f.alertName()
f.toString() // 要去 f.__proto__.__proto__ 中查找
2-10 прототипов и цепочек прототипов — instanceof
// instanceof 用于判断引用类型属于哪个构造函数的方法
console.log(f instanceof Foo) // true, f 的 __proto__ 一层一层往上,能否对应到 Foo.prototype
console.log(f instanceof Object) // true
2-11 Прототипы и цепочки прототипов — Решение 1
Как точно определить, является ли переменная типом массива
Ответ: использоватьinstanceof Array
let arr = []
console.log(arr instanceof Array) // true
console.log(typeof arr) // "object" ,typeof 是无法判断是否是数组的
Напишите пример наследования цепочки прототипов
// 动物
function Animal() {
this.eat = function() {
console.log('animal eat')
}
}
// 狗
function Dog() {
this.bark = function() {
console.log('dog bark')
}
}
Dog.prototype = new Animal()
// 哈士奇
let hashiqi = new Dog()
// 接下来代码演示时,会推荐更加贴近实战的原型继承示例
описыватьnewпроцесс объекта
отвечать:
- создать новый объект
-
thisуказывает на этот новый объект - выполнить код, т.е.
thisназначать - вернуть
this
function Foo(name, age) {
this.name = name
this.age = age
this.class = 'class__1'
// return this // 默认有这一行
}
let f = new Foo('negrochn', 18)
Как использовать цепочку прототипов в zepto или другом исходном коде фреймворка
отвечать:
- Чтение исходного кода — эффективный способ улучшить свои навыки
- Но сильно "просверлить голову" нельзя, в этом есть навыки
- Поиск МООК "дизайн zepto и анализ исходного кода"
2-12 Прототипы и цепочки прототипов — Решение 2
Напишите пример, который инкапсулирует запрос DOM
function Elem(id) {
this.elem = document.getElementById(id)
}
Elem.prototype.html = function(val) {
let elem = this.elem
if (val) {
elem.innerHTML = val
return this // 为了链式操作
} else {
return elem.innerHTML
}
}
Elem.prototype.on = function(type, fn) {
let elem = this.elem
elem.addEventListener(type, fn)
return this // 为了链式操作
}
let div1 = new Elem('div1')
div1.html('<p>Hello World</p>').on('click', function() {
alert('clicked')
})
2-13 Прототипы и цепочки прототипов — Демонстрация кода
без
Глава 3. Основы JS (Часть 2)
3-1 Область действия и замыкания — контекст выполнения
тема
- Поговорите о понимании переменного продвижения
- иллюстрировать
thisНесколько разных сценариев использования - Создать 10
<a>Метка, при нажатии на которую появится соответствующий серийный номер - Как понять охват
- Применение замыканий в реальной разработке
Точка знаний
- контекст выполнения
this- объем
- цепочка прицелов
- Закрытие
контекст выполнения
- Объем: один сегмент
<script>или функция - Глобальный контекст: перед выполнением будут удалены определения переменных и объявления функций (обратите внимание на разницу между объявлениями функций и функциональными выражениями).
- Контекст функции: перед выполнением поместите определения переменных, объявления функций,
this,argumentsвозьми это
console.log(a) // undefined
var a = 100
fn('negrochn') // "negrochn" 20
function fn(name) {
age = 20
console.log(name, age)
var age
}
3-2 Scope и Closures — Демонстрация кода контекста выполнения
без
3-3 Scope и Closures - это
this, значение может быть подтверждено только во время выполнения и не может быть подтверждено во время определения
- Выполнить как конструктор
- Выполнить как свойство объекта
- Выполнить как обычную функцию
-
call,apply,bind
var a = {
name: 'A',
fn: function() {
console.log(this.name)
}
}
a.fn() // this === a
a.fn.call({ name: 'B' }) // this 作为 { name: 'B' }
var fn1 = a.fn
fn1() // this === window
3-4 Scope and Closures — эта демонстрация кода
// 作为构造函数执行
function Foo(name) {
this.name = name
}
let f = new Foo('negrochn')
f.name // "negrochn"
// 作为对象属性执行
let obj = {
name: 'A',
printName: function() {
console.log(this.name)
}
}
obj.printName() // "A"
// 作为普通函数执行
function fn() {
console.log(this)
}
fn() // window
// call 、apply 、bind
function fn1(name, age) {
console.log(name)
console.log(this)
}
fn1.call({ x: 1 }, 'negrochn', 20) // "negrochn" { x: 1 }
fn1.apply({ x: 200 }, ['negrochn', 20]) // "negrochn" { x: 200 }
let fn2 = function(name, age) {
console.log(name)
console.log(this)
}.bind({ x: 300 })
fn2('negrochn', 20) // "negrochn" { x: 300 }
3-5 Область действия и замыкания - Область действия
объем
- нет области блока
- Только функции и глобальный объем
// 无块级作用域
if (true) {
var name = 'negrochn'
}
console.log(name) // "negrochn"
// 只有函数和全局作用域
var a = 100
function fn() {
var a = 200
console.log('fn', a)
}
console.log('global', a) // "global" 100
fn() // "fn" 200
цепочка прицелов
var a = 100
function fn() {
var b = 200
// 当前作用域没有定义的变量,即“自由变量”
console.log(a)
console.log(b)
}
fn()
var a = 100
function f1() {
var b = 200
function f2() {
var c = 300
console.log(a) // a 是自由变量
console.log(b) // b 是自由变量
console.log(c)
}
f2()
}
f1()
3-6 Scope and Closures — Демонстрация кода Scope
без
3-7 Дополнение - Объем блока ES6
JS не имеет блочной области, ES6 имеет блочную область
3-8 Область действия и замыкания — замыкания
Закрытие
function f1() {
var a = 100
// 返回一个函数(函数作为返回值)
return function() {
console.log(a)
}
}
// f1 得到一个函数
var f = f1()
var a = 200
f() // 100
Сценарии использования закрытия
- функция как возвращаемое значение
- функция передана как параметр
3-9 Scope and Closures — Демонстрация кода замыкания
// 闭包 1 ,函数作为返回值
function f1() {
var a = 100
return function() {
console.log(a) // a 是自由变量,向父级作用域去寻找,函数定义时的父作用域
}
}
var f = f1()
var a = 200
f() // 100
// 闭包 2 ,函数作为参数传递
function f1() {
var a = 100
return function() {
console.log(a)
}
}
var f = f1()
function f2(fn) {
var a = 200
fn()
}
f2(f) // 100
3-10 Область действия и замыкания — решение проблем
Поговорите о понимании переменного продвижения
- Определения переменных
- Объявление функции (обратите внимание на отличие от функциональных выражений)
иллюстрироватьthisНесколько разных сценариев использования
- Выполнить как конструктор
- Выполнить как свойство объекта
- Выполнить как обычную функцию
-
call,apply,bind
Создать 10<a>Метка, при нажатии на которую появится соответствующий серийный номер
// 这是一个错误的写法
var 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)
}
// 这是正确的写法
var i
for(i = 0; i < 10; i++) {
(function(i) {
var a = document.createElement('a')
a.innerHTML = i + '<br>'
a.addEventListener('click', function(e) {
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
})(i)
}
Если вы понимаете масштаб
- свободная переменная
- Цепочка областей видимости, т. е. поиск свободных переменных
- Два сценария закрытия
Применение замыканий в реальной разработке
// 闭包实际应用中主要用于封装变量,收敛权限
function isFirstLoad() {
var _list = []
return function(id) {
if (_list.indexOf(id) >= 0) {
return false
} else {
_list.push(id)
return true
}
}
}
// 使用
var firstLoad = isFirstLoad()
console.log(firstLoad(10)) // true
console.log(firstLoad(10)) // false
console.log(firstLoad(20)) // true
// 你在 isFirstLoad 函数外,根本不可能修改掉 _list 的值
3-11 Scope and Closures — Демонстрация кода решения проблем
без
Глава 4. Основы JS (Часть 2)
4-1 Асинхронный и однопоточный — что такое асинхронный
тема
- В чем разница между синхронным и асинхронным? Приведите пример синхронного и асинхронного соответственно
- Письменный тестовый вопрос о setTimeout
- Каковы сценарии, в которых внешний интерфейс использует асинхронность?
Точка знаний
- Что такое асинхронный (по сравнению с синхронным)
- Внешний интерфейс с использованием асинхронных сценариев
- Асинхронный и однопоточный
что такое асинхронный
- Блокировать последующее выполнение кода синхронно
- Асинхронный не блокирует выполнение программы
console.log(100)
setTimeout(function() {
console.log(200)
}, 1000)
console.log(300)
Контрастная синхронизация
console.log(100)
alert(200) // 1 秒之后手动点击确认
console.log(300)
Когда вам нужен асинхронный
- в случае ожидания
- не может быть как в ожидании
alertта самая блокирующая программа - Следовательно, все «ожидающие случаи» должны быть асинхронными.
Внешний интерфейс с использованием асинхронных сценариев
- задания на время,
setTimeout,setInterval - Сетевой запрос, запрос Ajax, динамический
<img>нагрузка - привязка события
// Ajax 请求
console.log('start')
$.get('./data1.json', function(data1) {
console.log(data1)
})
console.log('end')
// 动态 <img> 加载
console.log('start')
var img = document.createElement('img')
img.onload = function() {
console.log('loaded')
}
img.src = '/xxx.png'
console.log('end')
// 事件绑定
console.log('start')
document.getElementById('btn1').addEventListener('click', function() {
alert('clicked')
})
console.log('end')
4-2 Асинхронный и однопоточный — что такое асинхронный код Демонстрация
без
4-3 Асинхронный и однопоточный — однопоточный
console.log(100)
setTimeout(function() {
console.log(200)
})
console.log(300)
- выполнить строку 1, вывести 100
- воплощать в жизнь
setTimeoutПосле этого пройти вsetTimeoutФункция будет временно сохранена и не будет выполняться немедленно (однопоточная функция, не может делать две вещи одновременно) - выполнить строку 5, вывести 300
- После того, как все программы будут выполнены и находятся в состоянии ожидания, они сразу же увидят, есть ли что-то временно сохраненное для выполнения.
- Если вы найдете функцию во временно сохраненном setTimeout, вы можете выполнить ее немедленно, не дожидаясь времени.
один поток
- JS — это однопоточный язык, то есть вы можете делать только одно дело за раз, если есть два дела одновременно, то другое будет стоять в очереди первым, я закончу это дело первым, если нет асинхронный, будет блокировка.
- Поскольку JS — это один поток, его нельзя заблокировать из-за выполнения кода, которому нужно ждать во время выполнения кода, поэтому JS сначала выполнит (синхронный) код, которому не нужно ждать, а затем обработает асинхронный код. Если выполнение асинхронного кода достигнуто условие, он будет выполнен
4-4 Асинхронный и однопоточный — ответы
В чем разница между синхронным и асинхронным? Приведите пример синхронного и асинхронного соответственно
- Синхронный блокирует выполнение кода, а асинхронный нет.
-
alertсинхронный,setTimeoutасинхронный
Письменный тестовый вопрос о setTimeout
console.log(1)
setTimeout(function() {
console.log(2)
}, 0)
console.log(3)
setTimeout(function() {
console.log(4)
}, 1000)
console.log(5)
// 1
// 3
// 5
// 2
// 4 ,一秒后
Каковы сценарии, в которых внешний интерфейс использует асинхронность?
- задания на время,
setTimeout,setInterval - Сетевой запрос, запрос Ajax, динамический
<img>нагрузка - привязка события
Основные моменты
- разница между асинхронным и синхронным
- Асинхронные и однопоточные отношения
- Сценарии асинхронного использования во внешнем интерфейсе
4-5 Другие точки знаний - дата и математика
тема
- Получать
2020-02-24дата в формате - Получить случайное число, требующее строкового формата той же длины
- Напишите дженерик, который перебирает объекты и массивы.
forEachфункция
Точка знаний
- Date
- Math
- API-интерфейс массива
- API объекта
Date
Date.now() // 获取当前时间毫秒数
var dt = new Date()
dt.getTime() // 获取毫秒数
dt.getFullYear() // 年
dt.getMonth() // 月(0-11)
dt.getDate() // 日(1-31)
dt.getHours() // 时(0-23)
dt.getMinutes() // 分(0-59)
dt.getSeconds() // 秒(0-59)
Math
Math.random() // 获取随机数
4-6 Другие точки знаний - API массивов и объектов
API-интерфейс массива
-
forEach, перебирает все элементы -
every, чтобы определить, все ли элементы удовлетворяют условиям -
some, чтобы определить, удовлетворяет ли хотя бы один элемент условию -
sort, Сортировать -
map, который собирает элементы для создания нового массива -
filter, фильтровать элементы, соответствующие условию
// forEach
var arr = [1, 2, 3]
arr.forEach(function(item, index) {
// 遍历数组的所有元素
console.log(index, item)
})
// 0 1
// 1 2
// 2 3
// every
var arr = [1, 2, 3]
var result = arr.every(function(item, index) {
// 用来判断所有的数组元素,都满足条件
if (item < 4) {
return true
}
})
console.log(result) // true
// some
var arr = [1, 2, 3]
var result = arr.some(function(item, index) {
// 用来判断只要有一个数组元素满足条件
if (item < 2) {
return true
}
})
console.log(result) // true
// sort
var arr = [1, 4, 2, 3, 5]
var result = arr.sort(function(a, b) {
// 从小到大排序
return a - b // 从大到小排序 return b - a
})
console.log(result) // [1, 2, 3, 4, 5]
// map
var arr = [1, 2, 3]
var result = arr.map(function(item, index) {
// 将元素重新组装并返回
return '<b>' + item + '</b>'
})
console.log(result) // ["<b>1</b>", "<b>2</b>", "<b>3</b>"]
// filter
var arr = [1, 2, 3]
var result = arr.filter(function(item, index) {
// 通过某一个条件过滤数组
if (item >= 2) {
return true
}
})
console.log(result) // [2, 3]
API объекта
var obj = {
x: 100,
y: 200,
z: 300
}
var key
for (key in obj) {
// 注意这里的 hasOwnProperty ,在将原型链的时候讲过了
if (obj.hasOwnProperty(key)) {
console.log(key, obj[key])
}
}
// x 100
// y 200
// z 300
4-7 Другие точки знаний — Демонстрация кода точек знаний
без
4-8 Другие точки знаний - ответы
Получать2020-02-24дата в формате
function formatDate(dt) {
if (!dt) {
dt = new Date()
}
var year = dt.getFullYear()
var month = dt.getMonth() + 1
var date = dt.getDate()
return year + '-' + month.toString().padStart(2, '0') + '-' + date.toString().padStart(2, '0')
}
formatDate(new Date()) // "2021-02-24"
Получить случайное число, требующее строкового формата той же длины
var random = Math.random()
random = random + '0000000000'
random = random.slice(0, 10)
console.log(random)
Напишите дженерик, который перебирает объекты и массивы.forEachфункция
function forEach(obj, fn) {
var key
if (obj instanceof Array) {
obj.forEach(function(item, index) {
fn(index, item)
})
} else {
for (key in obj) {
fn(key, obj[key])
}
}
}
var arr = [1, 2, 3]
forEach(arr, function(key, value) {
console.log(key, value)
})
// 0 1
// 1 2
// 2 3
var obj = {
x: 100,
y: 200
}
forEach(obj, function(key, value) {
console.log(key, value)
})
// x 100
// y 200
Основные моменты
- Date
- Math
- API-интерфейс массива
- API объекта
4-9 Другие точки знаний — Демонстрация кода
Глава 5 Веб-API JS (часть 1)
5-1 От основ к JS Web API
Ознакомьтесь с основами JS
- Типы переменных и вычисления
- Прототипы и цепочки прототипов
- Закрытие и объем
- Асинхронный и однопоточный
- Другие (такие как Date , Math , различные распространенные API)
- Особенности: на первый взгляд кажется, что он не используется для разработки кода на работе.
- Встроенные функции: объект, массив, логический, строка ...
- Встроенный объект: Math, JSON...
- Мы даже всплываем предложение на веб-странице
Hello Worldне может быть достигнуто
JS Web API
- Основы JS: стандарт ECMA262
- Веб-API JS: стандарт W3C
Положения о JS в стандарте W3C:
- Манипуляции с DOM
- Операции со спецификациями
- привязка события
- Ajax-запросы (включая протокол http)
- место хранения
Всплывающее окно страницыwindow.alert(123), браузер должен сделать
- определить
windowглобальная переменная, тип объекта - определить его
alertсвойство, значение свойства является функцией
получить элементdocument.getElementById(id), браузер требует
- определить
documentглобальная переменная, тип объекта - Определить это А.
getElementByIdсвойство, значение свойства является функцией
Но стандарт W3C ничего не говорит об основах JS.
- Независимо от типа переменной, прототипа, области действия и асинхронности
- Просто определите API и глобальные переменные для страниц манипулирования JS в браузере.
Всестороннее рассмотрение, что такое встроенные глобальные функции и объекты в JS?
- Объект, массив, логическое значение, строка, математика, JSON и т. д.
- только что упомянутое окно, документ
- Затем идут все неопределенные глобальные переменные, которые продолжают упоминаться, например
navigator.userAgent
Суммировать
Часто говорят, что JS (Browser Executed JS) состоит из двух частей.
- Основы JS (стандарт ECMA262)
- Веб-API JS (стандарт W3C)
5-2 суть ДОМ
DOM, полное название Объектная модель документа
тема
- Какой базовой структурой данных является DOM?
- Каковы общие API для манипулирования DOM?
- В чем разница между атрибутом и свойством узла DOM?
Точка знаний
- суть ДОМ
- Управление узлами DOM
- Структура DOM операции
суть ДОМ
<?xml version="1.0" encoding="utf-8"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend</body>
<other>
<a></a>
<b></b>
</other>
</note>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<p>this is p</p>
</div>
</body>
</html>
Суть DOM: после того, как браузер получает HTML-код, DOM структурирует HTML-код во что-то, что может распознать браузер и JS.
HTML-код — это просто строка, но браузер уже структурировал строку в древовидную структуру.
5-3 Операции с DOM-узлом
DOM можно понимать так: браузер структурирует HTML-код, который он получает, в модель, которую браузер может распознать и которой может манипулировать JS.
Управление узлами DOM
- Получить узел DOM
- Свойство, свойство объекта JS
- Атрибут , атрибут HTML-тега
Получить узел DOM
var div1 = document.getElementById('div1') // 元素
var divList = document.getElementsByTagName('div') // 集合
console.log(divList.length)
console.log(divList[0])
var containerList = document.getElementsByClassName('container') // 集合
var pList = document.querySelectorAll('p') // 集合
Свойство, свойство объекта JS
var pList = document.querySelectorAll('p')
var 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) // "P"
console.log(p.nodeType) // 1
Атрибут , атрибут HTML-тега
var pList = document.querySelectorAll('p')
var p = pList[0]
p.getAttribute('data-name')
p.setAttribute('data-name', 'imooc')
p.getAttribute('style')
p.setAttribute('style', 'font-size: 30px;')
5-4 Работа с узлом DOM — демонстрация кода
без
5-5 Управление структурой DOM
Управление структурой DOM
- новый узел
- получить родительский элемент
- получить дочерний элемент
- удалить узел
новый узел
var div1 = document.getElementById('div1')
// 添加新节点
var p = document.createElement('p')
p.innerHTML = 'new p'
div1.appendChild(p) // 添加新创建的元素
// 移动已有节点
var p4 = document.getElementById('p4')
div1.appendChild(p4)
Получить родительские и дочерние элементы
var div1 = document.getElementById('div1')
var parent = div1.parentNode
var children = div1.childNodes
удалить узел
div1.removeChild(children[0])
5-6 Управление структурой DOM — демонстрация кода
без
5-7 Управление структурой DOM — ответы
Какой базовой структурой данных является DOM?
Ответ: дерево
Каковы общие API для манипулирования DOM?
отвечать:
- Получите узел DOM, а также свойство и атрибут узла
- получить родительский узел, получить дочерний узел
- добавить узел, удалить узел
В чем разница между атрибутом и свойством узла DOM?
отвечать:
- Свойство — это просто модификация свойств объекта JS.
- Атрибут — это модификация атрибутов тега HTML.
Основные моменты
- суть ДОМ
- Управление узлами DOM
- Управление структурой DOM
5-8 Операция со спецификацией
тема
- Как определить тип браузера
- Разбить части URL
Точка знаний
navigatorsrceenlocationhistory
navigator & screen
// navigator
var ua = navigator.userAgent
var isChrome = ua.indexOf('Chrome')
console.log(isChrome) // 81
// screen
console.log(screen.width) // 1920
console.log(screen.height) // 1080
location & history
// location ,以 http://localhost:8080/login?username=negrochn&password=123456#mid=1 为例
console.log(location.href) // http://localhost:8080/login?username=negrochn&password=123456#mid=1
console.log(location.protocol) // http:
console.log(location.host) // localhost:8080
console.log(location.hostname) // localhost
console.log(location.port) // 8080
console.log(location.pathname) // /login
console.log(location.search) // ?username=negrochn&password=123456
console.log(location.hash) // #mid=1
// history
history.back()
history.forward()
5-9 Работа со спецификацией — демонстрация кода
без
Глава 6 Веб-API JS (часть 2)
6-1 События
тема
- Напишите общую функцию прослушивания событий
- Описать процесс всплытия событий
- Как привязать событие к каждому изображению на странице, которая загружает изображения в бесконечном раскрывающемся списке
Точка знаний
- Общая привязка событий
- всплывающее окно событий
- играет роль
Общая привязка событий
var btn = document.getElementById('btn1')
btn.addEventListener('click', function(e) {
console.log('clicked')
})
function bindEvent(elem, type, fn) {
elem.addEventListener(type, fn)
}
var a = document.getElementById('link1')
bindEvent(a, 'click', function(e) {
e.preventDefault() // 阻止默认行为
alert('clicked')
})
Совместимость с более ранними версиями IE
- Использование более низкой версии IE
attachEventСобытия привязки, не такие, как в стандарте W3C - Использование более ранней версии IE было очень небольшим, и многие веб-сайты больше не поддерживают ее.
- Рекомендуется совместимость с младшими версиями IE: просто разберитесь, не нужно вникать
- Если вы встретите требовательное интервью с более низкой версией IE, решительно сдавайтесь.
всплывающее окно событий
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡</title>
</head>
<body>
<div id="div1">
<p id="p1">激活</p>
<p id="p2">取消</p>
<p id="p3">取消</p>
<p id="p4">取消</p>
</div>
<div id="div2">
<p id="p5">取消</p>
<p id="p6">取消</p>
</div>
<script>
function bindEvent(elem, type, fn) {
elem.addEventListener(type, fn)
}
var p1 = document.getElementById('p1')
var body = document.body
bindEvent(p1, 'click', function(e) {
e.stopPropagation()
alert('激活')
})
bindEvent(body, 'click', function(e) {
alert('取消')
})
</script>
</body>
</html>
играет роль
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡</title>
</head>
<body>
<div id="div1">
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<!-- 会随时新增更多 a 标签 -->
</div>
<script>
var div1 = document.getElementById('div1')
div1.addEventListener('click', function(e) {
var target = e.target
if (target.nodeName === 'A') {
alert(target.innerHTML)
}
})
</script>
</body>
</html>
Улучшить функцию общего события привязки
function bindEvent(elem, type, selector, fn) {
if (fn == null) {
fn = selector
selector = null
}
elem.addEventListener(type, function(e) {
var target
if (selector) {
target = e.target
if (target.matches(selector)) {
fn.call(target, e)
}
} else {
fn(e)
}
})
}
// 使用代理
var div1 = document.getElementById('div1')
bindEvent(div1, 'click', 'a', function(e) {
console.log(this.innerHTML)
})
// 不使用代理
var a = document.getElementById('a1')
bindEvent(div1, 'click', function(e) {
console.log(a.innerHTML)
})
Преимущества прокси
- код краткий
- Уменьшите использование памяти браузера
6-2 События — Демонстрация кода
без
6-3 События - Ответы
Напишите общую функцию прослушивания событий
отвечать:
function bindEvent(elem, type, selector, fn) {
if (fn == null) {
fn = selector
selector = null
}
elem.addEventListener(type, function(e) {
let target
if (selector) {
target = e.target
if (target.matches(selector)) {
fn.call(target, e)
}
} else {
fn(e)
}
})
}
Описать процесс всплытия событий
отвечать:
- Древовидная структура DOM
- всплывающее окно событий
- перестань пузыриться
- всплывающее приложение
Как привязать событие к каждому изображению на странице, которая загружает изображения в бесконечном раскрывающемся списке
отвечать:
- использовать прокси
- Два преимущества прокси (краткий код, уменьшение использования памяти браузером)
Основные моменты
- Общая привязка событий
- всплывающее окно событий
- агент событий
6-4 Ajax - XMLHttpRequest
тема
- Напишите Ajax, не полагаясь на сторонние библиотеки
- Несколько реализаций междоменного
Точка знаний
- XMLHttpRequest
- Описание кода состояния
- перекрестный домен
XMLHttpRequest
var xhr = new XMLHttpRequest()
xhr.open('GET', '/api', false)
xhr.onreadystatechange = function() {
// 这里的函数异步执行
if (xhr.readyState == 4) {
if (xhr.status == 200) {
alert(xhr.responseText)
}
}
}
xhr.send(null)
Проблемы совместимости с IE
- Младшая версия IE использует ActiveXObject, что не совпадает со стандартом W3C.
- Использование более ранней версии IE было очень небольшим, и многие веб-сайты больше не поддерживают ее.
- Рекомендуется совместимость с младшими версиями IE: просто разберитесь, не нужно вникать
- Если вы встретите требовательное интервью с более низкой версией IE, решительно сдавайтесь.
readyState
- 0 - не инициализирован, метод send() не вызывался
- 1 - Загрузка, вызывается метод send(), запрос отправляется
- 2 - Загрузка завершена, метод send() выполнен, и все содержимое ответа получено
- 3 - Интерактивный, анализирующий содержимое ответа
- 4 - Готово, содержимое ответа анализируется и может быть вызвано на стороне клиента
status
- 1XX - Информация, сервер получил запрос и запрашивающей стороне необходимо продолжить операцию
- 2XX - Успех, операция успешно получена и обработана
- 3XX — перенаправление, для выполнения запроса требуются дальнейшие действия.
- 4XX - Ошибка клиента, запрос содержит синтаксическую ошибку или запрос не может быть выполнен
- 5XX — Ошибка сервера, сервер обнаружил ошибку при обработке запроса
| код состояния | английское описание | Китайское описание |
|---|---|---|
| 100 | Continue | Продолжать. Клиент должен продолжить выполнение своего запроса. |
| 200 | OK | Запрос выполнен успешно. |
| 204 | No Content | Без содержания. Сервер успешно обработал, но не вернул содержимого. |
| 206 | Partial Content | Часть. Сервер успешно обработал часть запроса GET. |
| 301 | Moved Permanently | Переехать навсегда. Запрашиваемый ресурс был постоянно перемещен на новый URI, возвращенная информация будет включать в себя новый URI, а браузер будет автоматически направлен на новый URI. |
| 302 | Found | Временный переезд. Клиенты должны продолжать использовать старый URI. |
| 304 | Not Modified | Без изменений. Запрошенный ресурс не был изменен, и ресурс не будет возвращен, когда сервер вернет этот код состояния. |
| 307 | Temporary Redirect | Временная переадресация. Перенаправление с использованием GET-запроса. |
| 400 | Bad Request | В клиентском запросе есть синтаксическая ошибка, которую сервер не может понять. |
| 401 | Unauthorized | Запрос требует аутентификации пользователя. |
| 403 | Forbidden | Сервер понимает запрос запрашивающего клиента, но отказывается выполнять запрос. |
| 404 | Not Found | Сервер не смог найти ресурс (веб-страницу) по запросу клиента. |
| 500 | Internal Server Error | Внутренняя ошибка сервера, невозможно выполнить запрос. |
| 502 | Bad Gateway | Сервер, работающий в качестве шлюза или прокси, получил недопустимый ответ от удаленного сервера при попытке выполнить запрос. |
| 503 | Service Unavailable | Из-за перегрузки или обслуживания системы сервер временно не может обработать запрос клиента. |
6-5 «Аякс» — кросс-домен
что такое кросс домен
- Браузер имеет политику того же происхождения, которая не позволяет Ajax получать доступ к другим интерфейсам домена.
- Междоменные условия: протокол, доменное имя, порт, если есть разница, то междоменное
- Есть три вкладки, которые позволяют загружать ресурсы из разных источников.
-
<img src=xxx>, используемый для статистики RBI, веб-сайт статистики может быть другим доменом -
<link href=xxx>, вы можете использовать CDN -
<script src=xxx>, вы можете использовать CDN для JSONP
-
Междоменные соображения
- Все междоменные запросы должны быть разрешены поставщиком информации.
- Если его можно получить без разрешения, это уязвимость в политике браузера того же происхождения.
Принцип реализации JSONP
- нагрузкаcoding.IMO OC.com/lesson/115. …
- Не обязательно файл 115.html на стороне сервера
- Сервер может динамически генерировать файл и возвращать его по запросу.
- По аналогии,
<script src="http://coding.imooc.com/api.js"> - Например, вашему веб-сайту необходим доступ к интерфейсу сети MOOC через домены.
- МООК дает вам адресcoding.imooc.com/api.js
- Формат возврата содержимого, такой как
callback({ x: 100, y: 200 })(может быть динамически сгенерирован)
<script>
window.callback = function(data) {
// 这是我们跨域得到的信息
console.log(data)
}
</script>
<script src="http://coding.imooc.com/api.js"></script>
<!-- 以上将返回 callback({ x: 100, y: 200 }) -->
Сервер устанавливает заголовок http
- Еще один лаконичный способ решения междоменной проблемы требует, чтобы сервер выполнял
- Но как взаимодействующая сторона мы должны знать этот метод
- Это тенденция к решению междоменных проблем в будущем.
// 注意:不同后端语言的写法可能不一样
// 第二个参数填写允许跨域的域名称,不建议直接写 *
response.setHeader('Access-Control-Allow-Origin', 'http://a.com, http://b.com')
response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With')
response.setHeader('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
// 接收跨域的 Cookie
response.setHeader('Access-Control-Allow-Credentials', 'true')
Напишите Ajax, не полагаясь на сторонние библиотеки
var xhr = new XMLHttpRequest()
xhr.open('GET', '/api', false)
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
alert(xhr.responseText)
}
}
}
xhr.send(null)
Несколько реализаций междоменного
- JSONP
- Настройка HTTP-заголовка на стороне сервера
Основные моменты
- XMLHttpRequest
- код состояния
- перекрестный домен
6-6 Хранение
тема
- Пожалуйста, опишите разницу между Cookie, sessionStorage и localStorage?
Точка знаний
- Cookie
- sessionStorage и localStorage
Cookie
- Изначально используется для связи на стороне клиента и на стороне сервера.
- Но у него есть функция локального хранилища, поэтому он "позаимствован"
- использовать
document.cookieполучить и изменить
Недостатки файлов cookie для хранения
- Хранилища слишком мало, всего 4 КБ
- Переносятся все http запросы, что повлияет на оперативность получения ресурсов
- API прост и должен быть инкапсулирован для использования.
document.cookie
локальное хранилище и хранилище сессий
- HTML5 предназначен для хранения, до 5 МБ
- API прост и удобен в использовании,
getItem(key),setItem(key, value) - В скрытом режиме iOS Safari localStorage.getItem сообщит об ошибке, рекомендуется использовать инкапсуляцию try-catch единообразно
Пожалуйста, опишите разницу между Cookie, sessionStorage и localStorage?
- емкость
- стоит ли нести его в запросе
- простота использования API
Глава 7. Среда разработки
7-1 Введение
О среде разработки
- Интервьюер хочет понять опыт интервьюируемого через среду разработки
- Среда разработки, которая лучше всего отражает эффективность работы
- Будет в основном в форме чата, а не конкретных вопросов
Среда разработки содержит
- IDE (эффективность написания кода)
- Git (управление версиями кода, совместная разработка несколькими людьми)
- Модульный JS
- упаковочный инструмент
- Онлайн-процесс отката
7-2 IDE
IDE
- WebStorm
- Sublime
- Код VS (рекомендуется)
- Atom
7-3 Git — общие команды
Git
- Формальные проекты требуют управления версиями кода
- Большой проект требует многопользовательской разработки
- Git и Linux — один автор
- Сетевой сервер Git, например github
- Как правило, код компании не является открытым исходным кодом и имеет собственный сервер Git.
- Настройка 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 xxx, создать новую ветку/переключиться на другую ветку -
git merge xxx, скопируйте предыдущую ветку сюда
7-4 Git — Демонстрация кода
без
7-5 Git — Демонстрация кода Многопользовательская совместная работа
многопользовательская разработка
- Чтобы написать свои собственные функции, вы можете создать свою собственную ветку вместо того, чтобы вносить изменения в основную ветку, и, наконец, объединить ее.
шаг
-
git checkout -b dev, создать ветку разработки -
vi a.jsИзмените содержимое (vi — это команда Linux,git statusПроверьте, не было ли оно изменено,git diffсмотрите измененный контент) git add .git commit -m 'update dev'-
git push origin dev, зафиксируйте в ветке dev удаленного репозитория - Через полмесяца сливаем в ветку master
-
git checkout master, переключиться на основную ветку -
git pull origin master, для скачивания файлов из ветки master удаленного репозитория -
git merge dev, скопируйте изменения из ветки dev в ветку master -
git push origin master, зафиксируйте в главной ветке удаленного репозитория
Дополнительные команды
-
cat 文件名, чтобы просмотреть содержимое файла -
git diff, просмотреть измененный контент -
git branch, чтобы увидеть ветку и в какой ветке она находится в данный момент -
git status, чтобы увидеть, был ли файл изменен -
vi 文件, создайте новый файл и откройте файл -
esc + :wq, выйдите и сохраните файл
7-6 Модульный - AMD
Не используйте модульную
// util.js
function getFormatDate(date, type) {
// type === 1 返回 2021-03-06
// type === 2 返回 2021年3月6日
// ...
}
// a-util.js
function aGetFormatDate(date) {
// 要求返回 2021年3月6日格式
return getFormatDate(date, 2)
}
// a.js
var dt = new Date()
console.log(aGetFormatDate(dt))
<script src="util.js"></script>
<script src="a-util.js"></script>
<script src="a.js"></script>
<!-- 1. 这些代码中的函数必须是全局变量,才能暴露给使用方。全局变量污染。 -->
<!-- 2. a.js 知道要引用 a-util.js ,但是他知道还需要依赖于 util.js 吗 -->
AMD
- require.js
- Глобальный
defineфункция - Глобальный
requireфункция - Зависимый JS будет загружаться автоматически и асинхронно
использовать require.js
// util.js
define(function() {
return {
getFormatDate: function(date, type) {
if (type === 1) {
return '2021-03-06'
} else if (type === 2) {
return '2021年3月6日'
}
}
}
})
// a-util.js
define(['./util.js'], function(util) {
return {
aGetFormatDate: function(date) {
return util.getFormatDate(date, 2)
}
}
})
// a.js
define(['./a-util.js'], function(aUtil) {
return {
printDate: function(date) {
console.log(aUtil.aGetFormatDate(date))
}
}
})
// main.js
require(['./a.js'], function(a) {
var date = new Date()
a.printDate(date)
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AMD</title>
</head>
<body>
<script src="https://cdn.bootcdn.net/ajax/libs/require.js/2.3.6/require.min.js" data-main="./main.js"></script>
</body>
</html>
7-7 Модульность — демонстрация кода AMD
без
7-8 Модульность — CommonJS
CommonJS
- Модульная спецификация Node.js в настоящее время активно используется во внешнем интерфейсе по следующим причинам:
- Плагины и библиотеки, от которых зависит разработка интерфейса, можно получить из npm.
- Высокоавтоматизированные инструменты сборки делают использование npm очень дешевым.
- CommonJS не загружает JS асинхронно, а загружает его синхронно за один раз
Используйте CommonJS
// util.js
module.exports = {
getFormatDate: function(date, type) {
if (type === 1) {
return '2021-03-06'
} else if (type === 2) {
return '2021年3月6日'
}
}
}
// a-util.js
var util = require('util.js')
module.exports = {
aGetFormatDate: function(date) {
return util.getFormatDate(date, 2)
}
}
Сценарии использования AMD и CommonJS
- Нужно асинхронно загружать JS, используйте AMD
- После использования npm рекомендуется использовать CommonJS
Основные моменты
- AMD
- CommonJS
- Разница между двумя
7-9 Инструменты сборки — установка Node.js
7-10 Инструменты сборки — установка Webpack
7-11 Инструменты сборки — Настройка Webpack
7-12 Инструменты сборки — Использование jQuery
7-13 Инструменты сборки — Минимизированный JS
7-14 Онлайн-откат — процесс онлайн-отката
7-15 линейная рулона - Linux Basic Command
Глава 8 Операционная среда
8-1 Введение
Рабочая среда
- Браузер может получить содержимое страницы, перейдя по ссылке
- По рисованию и рендерингу, показывая окончательный вид страницы
- Какие вопросы нам необходимо рассмотреть на протяжении всего процесса?
Точка знаний
- Загрузка страницы
- оптимизация производительности
- безопасность
8-2 Загрузка страницы — процесс рендеринга
тема
- Подробный процесс от ввода URL до получения HTML
-
window.onloadа такжеDOMContentLoadedразница
Точка знаний
- Форма загружаемого ресурса
- Процесс загрузки ресурса
- Процесс, с помощью которого браузер отображает страницу
Форма загружаемого ресурса
- Введите URL (или перейдите на страницу), чтобы загрузить HTML
- Загружать статические ресурсы в HTML
Процесс загрузки ресурса
- Браузер получает IP-адрес доменного имени от DNS-сервера.
- Отправьте HTTP-запрос на машину с этим IP-адресом
- Сервер получает, обрабатывает и возвращает HTTP-запрос
- Браузер получает возвращаемый контент
Процесс, с помощью которого браузер отображает страницу
- Создание дерева DOM на основе структуры HTML
- Создание CSSOM из CSS
- Интегрируйте DOM и CSSOM для формирования дерева рендеринга
- Начать рендеринг и отображение в соответствии с деревом рендеринга
- встретить
<script>, выполнит и заблокирует рендеринг
8-3 Загрузка страницы — несколько примеров
Зачем вставлять CSS в голову?
О: Обязательно сначала загрузите CSS, а затем выполните рендеринг, иначе он будет рендериться дважды, и взаимодействие с пользователем будет плохим.
Зачем ставить JS внизу тела?
О: Это не будет блокировать процесс рендеринга и улучшит производительность.
window.onloadа такжеDOMContentLoaded
window.addEventListener('load', function() {
// 页面的全部资源加载完才会执行,包括图片、视频等
})
document.addEventListener('DOMContentLoaded', function() {
// DOM 渲染完即可执行,此时图片、视频还可能没有加载完
})
8-4 Загрузка страницы - Ответы
Подробный процесс от ввода URL до получения HTML
- Браузер получает IP-адрес доменного имени от DNS-сервера.
- Отправьте HTTP-запрос на машину с этим IP-адресом
- Сервер получает, обрабатывает и возвращает HTTP-запрос
- Браузер получает возвращаемый контент
window.onloadа такжеDOMContentLoadedразница
- После загрузки будут выполнены все ресурсы страницы, включая картинки, видео и т.д.
- DOM может быть выполнен после рендеринга, в это время картинки и видео еще не загружены.
8-5 Оптимизация производительности — стратегия оптимизации
оптимизация производительности
- Это комплексная проблема сама по себе
- Стандартного ответа нет, если вы хотите быть очень исчерпывающим, вы можете написать книгу
- Сосредоточьтесь только на основных магазинах, для интервью
в общем
- Используйте больше памяти, кэша или другие методы
- Меньше вычислений ЦП, меньше сети
когда начать
- Загружать страницы и статические ресурсы
- рендеринг страницы
Оптимизация загрузки ресурсов
- Сжатие и объединение статических ресурсов
- Кэширование статических ресурсов
- Используйте CDN для более быстрой загрузки ресурсов
- Рендеринг с использованием серверной части SSR, данные выводятся непосредственно в HTML
Оптимизация рендеринга
- CSS спереди, JS сзади
- Ленивая загрузка (ленивая загрузка изображения, дополнительная загрузка раскрывающегося списка)
- Сократите операции DOM, кэшируйте запросы DOM и выполняйте несколько операций вместе, насколько это возможно.
- регулирование событий
- Выполняйте операции заранее, например DOMContentLoaded.
8-6 Оптимизация производительности — несколько примеров
Консолидация ресурсов
<script src=a.js></script>
<script src=b.js></script>
<script src=c.js></script>
<script src="abc.js"></script>
тайник
- Управление кешем по имени ссылки
- Название ссылки меняется только при изменении содержимого
CDN
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
Рендеринг с бэкендом SSR
- Теперь Vue/React предлагает такую концепцию
- На самом деле JSP/PHP/ASP относятся к внутреннему рендерингу.
ленивая загрузка
<img id="img1" src="preview.png" data-realsrc="abc.png" />
<script>
var img1 = document.getElementById('img1')
img1.src = img1.getAttribute('data-realsrc')
</script>
Кэшировать DOM-запросы
// 未缓存 DOM 查询
var i
for (i = 0; i < document.getElementByTagName('p').length; i++) {
}
// 缓存了 DOM 查询
var pList = document.getElementByTagName('p')
var i
for (i = 0; i < pList.length; i++) {
}
Объединить вставку DOM
var listNode = document.getElementById('list')
// 要插入 10 个 li 标签
var frag = document.createDocumentFragment()
var x, li
for (x = 0; x < 10; x++) {
li = document.createElement('li')
li.innerHTML = 'List item ' + x
frag.appendChild(li)
}
listNode.appendChild(frag)
регулирование событий
var textarea = document.getElementById('text')
var timeoutid
textarea.addEventListener('keyup', function() {
if (timeoutid) {
clearTimeout(timeoutid)
}
timeoutid = setTimeout(function() {
// 触发 change 事件
}, 100)
})
действовать рано
window.addEventListener('load', function() {
// 页面的全部资源加载完才会执行,包括图片、视频等
})
document.addEventListener('DOMContentLoaded', function() {
// DOM 渲染完即可执行,此时图片、视频还可能没有加载完
})
8-7 Безопасность — XSS
Точка знаний
- XSS-атака с межсайтовым запросом
- Подделка межсайтовых запросов XSRF
XSS
- Напишите статью в блоге Sina и одновременно тайком вставьте абзац
<script> - В коде атаки получите cookie и отправьте его на свой сервер
- Опубликовать блог, кто-то просматривает содержимое блога
- отправит файл cookie зрителя на сервер злоумышленника
- Ключевые слова замены внешнего интерфейса, такие как replace
<для<,>для> - замена серверной части
8-8 Безопасность — XSRF
XSRF
- Вы вошли на сайт магазина и просматриваете товары
- Платежный интерфейс этого веб-сайта — xxx.com/pay?id=100 , но верификации нет.
- Затем вы получаете электронное письмо, скрывающее
<img src="xxx.com/pay?id=100" /> - Когда вы проверяете свою электронную почту, вы незаметно заплатили за нее
- Увеличьте процесс проверки, такой как ввод отпечатка пальца, пароля, кода подтверждения SMS
8-9 Навыки интервью
резюме
- Кратко и лаконично, с упором на менеджеров проектов и решения
- Поместите свой личный блог в свое резюме и регулярно поддерживайте и обновляйте блог.
- Включите личные проекты с открытым исходным кодом в свое резюме и поддерживайте проекты с открытым исходным кодом
- Не подделывайте свое резюме, сохраняйте свои способности и опыт подлинными
во время интервью
- Как вы относитесь к сверхурочной работе? Работать сверхурочно — это как брать деньги взаймы, а не помогать бедным
- Не бросайте вызов интервьюеру, не проверяйте интервьюера
- Научитесь удивлять интервьюера, но не слишком
- Если у вас есть вопрос, на который вы не можете ответить, скажите, что вы знаете
- Расскажите о своих слабостях — просто расскажите о том, чему вы научились в последнее время.
Глава 9 Моделирование реальных вопросов
-
varа такжеlet,constразницаотвечать:
-
varсинтаксис ES5,let,constсинтаксис ES6,varпеременный наддув -
varа такжеletпеременная, модифицируемая,constпостоянна и не может быть изменена -
let,constимеет блочную область действия,varнет
-
-
typeofкакие типы возвращаютсяотвечать:
- неопределенный, строка, число, логическое значение, символ
- объект (примечание,
typeof null === 'object') - function
-
Перечисление принуждения и неявных преобразований типов
отвечать:
- Обязательный:
parseInt,parseFloat,toStringЖдать - Неявный: if , логические операции, == , + объединение строк
- Обязательный:
-
Сравнение глубины рукописного ввода, имитирующее lodash
isEqualотвечать:
// 判断是否是对象或数组 function isObject(obj) { return typeof obj === 'object' && obj !== null } function isEqual(obj1, obj2) { if (!isObject(obj1) || !isObject(obj2)) { // 值类型(注意,参与 equal 的一般不会是函数) return obj1 === obj2 } if (obj1 === obj2) { return true } // 两个都是对象或数组,而且不相等 // 1. 先取出 obj1 和 obj2 的 keys ,比较个数 const obj1Keys = Object.keys(obj1) const obj2Keys = Object.keys(obj2) if (obj1Keys.length !== obj2Keys.length) { return false } // 2. 以 obj1 为基准,和 obj2 一次递归比较 for (let key in obj1) { if (!isEqual(obj1[key], obj2[key])) { return false } } // 3. 全相等 return true } const obj1 = { a: 100, b: { x: 100, y: 200 } } const obj2 = { a: 100, b: { x: 100, y: 200 } } console.log(obj1 === obj2) // false console.log(isEqual(obj1, obj2)) // true -
splitа такжеjoinразницаотвечать:
'1-2-3'.split('-') // [1, 2, 3] [1, 2, 3].join('-') /// '1-2-3' -
массив
pop,push,unshift,shiftчто делатьотвечать:
- Какова функция?
- Каково возвращаемое значение?
- Повлияет ли это на исходный массив?
const arr = [10, 20, 30, 40] const result = arr.pop() console.log(result, arr) // 40, [10, 20, 30]const arr = [10, 20, 30, 40] const result = arr.push(50) // 返回 length console.log(result, arr) // 5, [10, 20, 30, 40, 50]const arr = [10, 20, 30, 40] const result = arr.unshift(5) // 返回 length console.log(result, arr) // 5, [5, 10, 20, 30, 40]const arr = [10, 20, 30, 40] const result = arr.shift() console.log(result, arr) // 10, [20, 30, 40]Чистая функция: 1. не изменяет исходный массив 2. возвращает массив
// 纯函数 const arr = [10, 20, 30, 40] const cArr = arr.concat([50, 60, 70]) // [10, 20, 30, 40, 50, 60, 70] const mArr = arr.map(item => item * 10) // [100, 200, 300, 400] const fArr = arr.filter(item => item > 20) // [30, 40] const sArr = arr.slice() // [10, 20, 30, 40] // 非纯函数 // push 、pop 、shift 、unshift // forEach // some every reduce -
множество
sliceа такжеspliceразницаотвечать:
- функциональная разница,
sliceэто ломтик,spliceсращивает - Параметры и возвращаемые значения
- Это чистая функция?
const arr = [10, 20, 30, 40, 50] // slice 是纯函数 const sliceArr = arr.slice(1, 4) // splice 不是纯函数 const spliceArr = arr.splice(1, 2, 'a', 'b', 'c') console.log(arr, spliceArr) // [10, "a", "b", "c", 40, 50],[20, 30] - функциональная разница,
-
[10, 20, 30].map(parseInt)Каков результат возврата?отвечать:
-
mapпараметры и возвращаемое значение -
parseIntпараметры и возвращаемое значение
[10, 20, 30].map(parseInt) // 相当于 [10, 20, 30].map((item, index) => { return parseInt(item, index) }) // 分解为 parseInt(10, 0) // 10 parseInt(20, 1) // NaN parseInt(30, 2) // NaN -
-
В чем разница между получением и публикацией запроса Ajax?
отвечать:
- get обычно используется для операций запроса, а post обычно используется для операций отправки.
- Параметр get наваривается на url, а пост помещается в тело запроса (объем данных может быть больше)
- Безопасность, сообщение легко предотвратить CSRF
-
Разница между вызовом функции и применением?
отвечать:
fn.call(this, p1, p2, p3) fn.apply(this, arguments) -
Что такое делегирование события (делегирование)?
отвечать:
function bindEvent(elem, type, selector, fn) { if (fn == null) { fn = selector selector = null } elem.addEventListener(type, function(e) { var target if (selector) { target = e.target if (target.matches(selector)) { fn.call(target, e) } } else { fn(e) } }) } // 使用代理 var div1 = document.getElementById('div1') bindEvent(div1, 'click', 'a', function(e) { console.log(this.innerHTML) }) // 不使用代理 var a = document.getElementById('a1') bindEvent(div1, 'click', function(e) { console.log(a.innerHTML) }) -
Что такое замыкание и каковы его характеристики? Каковы негативные эффекты?
отвечать:
- Обзор области действия и свободных переменных
- Просмотрите сценарий приложения закрытия: передается как параметр, возвращается как возвращаемое значение.
- Обзор: поиск свободных переменных должен происходить там, где функция определена (а не там, где она выполняется)
- Воздействие: переменная будет находиться в памяти и не будет освобождена. Не путайте с замыканиями
-
Как остановить всплытие событий и поведение по умолчанию?
отвечать:
event.stopPropagation()event.preventDefault()
-
Как найти, добавить, удалить, переместить узлы DOM?
отвечать:
-
getElementById,getElementsByTagName,getElementsByClassName,querySelectorAll -
appendChild(добавить и переместить) removeChild-
parentNode,childNodes
-
-
Как уменьшить манипуляции с DOM?
отвечать:
- Кэшировать результаты запроса DOM
- Несколько манипуляций с DOM, объединенных в одну вставку
-
Объясните, как работает JSONP и почему это не совсем Ajax?
отвечать:
- Политика одного и того же источника в браузере (на сервере нет политики одного и того же источника) и междоменная
- Какие теги HTML могут обходить междоменные домены?
- Как работает JSONP
-
documentРазница между нагрузкой и готовностьюотвечать:
window.addEventListener('load', function() { // 页面的全部资源加载完才会执行,包括图片、视频等 }) document.addEventListener('DOMContentLoaded', function() { // DOM 渲染完即可执行,此时图片、视频还可能没有加载完 }) -
==а также===разницаотвечать:
-
==попробую преобразовать тип -
===строгое равенство - Какие сценарии будут использоваться
==?
-
-
Разница между объявлением функции и выражением функции
отвечать:
- объявление функции
function fn() {} - функциональное выражение
const fn = function() {} - Объявления функций предварительно загружаются перед выполнением кода, в то время как выражения функций не загружаются.
- объявление функции
-
new Object()а такжеObject.create()разницаотвечать:
-
{}Эквивалентноnew Object(), прототип естьObject.prototype -
Object.create(null)нет прототипа -
Object.crate({...})Можно указать архетипы.
const obj1 = { a: 10, b: 20, sum() { return this.a + this.b } } const obj2 = new Object({ a: 10, b: 20, sum() { return this.a + this.b } }) const obj3 = new Object(obj1) console.log(obj1 === obj2) // false console.log(obj1 === obj3) // true const obj4 = Object.create(null) // {} ,但没有原型 const obj5 = new Object() // {} const obj6 = Object.create(obj1) // 创建一个空对象,把空对象的原型指向 obj1 console.log(obj1 === obj6) // false console.log(obj1 === obj6.__proto__) // true -
-
о
thisназвание сценыconst User = { count: 1, getCount: function() { return this.count } } console.log(User.getCount()) // 1 const func = User.getCount console.log(func()) // undefined -
Сценарные вопросы о области действия и свободных переменных (1)
let i for (i = 1; i <= 3; i++) { setTimeout(function() { console.log(i) }, 0) } // 4 // 4 // 4 -
Строка суждения начинается с буквы, за которой следует буквенно-цифровое подчеркивание, и имеет длину от 6 до 30.
отвечать:
const reg = /^[a-zA-Z]\w{5,29}$/ -
Сценарные вопросы о области действия и свободных переменных (2)
let a = 100 function test() { alert(a) // 100 a = 10 alert(a) // 10 } test() alert(a) // 10 -
рукописная строка
trimметод обеспечения совместимости браузераотвечать:
String.prototype.trim = function() { return this.replace(/^\s+/, '').replace(/\s+$/, '') } // (原型、this 、正则表达式) -
Как получить максимальное значение среди нескольких чисел
отвечать:
function max() { const nums = Array.prototype.slice.call(arguments) // 变为数组 let max = -Infinity nums.forEach(n => { if (n > max) { max = n } }) return max } // 或者使用 Math.max() -
Как реализовать наследование с помощью JS?
отвечать:
- Наследование класса
- наследование прототипа
-
Как перехватывать исключения в JS-программах?
отвечать:
// 第一种方式 try { // TODO } catch(error) { console.error(error) // 手动捕获 } finally { // TODO } // 第二种方式 // 自动捕获 window.onerror = function(message, source, lineNum, colNum, error) { // 第一,对跨域的 JS ,如 CDN 的不会有详细的报错信息 // 第二,对于压缩的 JS ,还要配合 SourceMap 反查到未压缩代码的行、列 } -
Что такое JSON?
отвечать:
- JSON — это формат данных, по сути, строка
- Формат JSON такой же, как и структура объектов JS, которая более удобна для языка JS.
-
window.JSONглобальный объект,JSON.stringifyа такжеJSON.parse
-
Получить текущие параметры URL страницы
отвечать:
- традиционный способ, найти
location.search - новый API,
URLSearchParams
// 传统方式 function query(name) { const search = location.search.substr(1) const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i') const res = search.match(reg) if (res === null) { return null } return res[2] }// URLSearchParams function query(name) { const search = location.search const p = new URLSearchParams(search) return p.get(name) } - традиционный способ, найти
-
Разбирать параметры URL в объекты JS
отвечать:
// 传统方式,分析 search function query2Obj() { const res = {} const search = location.search.substr(1) // 去掉前面的 ? search.split('&').forEach(paramStr => { const arr = paramStr.split('=') const [key, val] = arr res[key] = val }) return res }// 使用 URLSearchParams function query2Obj() { const res = {} const pList = new URLSearchParams(location.search) pList.forEach((val, key) => { res[key] = val }) return res } -
Рукописный массив faltern с учетом нескольких уровней
отвечать:
function flat(arr) { // 验证 arr 中,还有没有深层数组 const isDeep = arr.some(item => item instanceof Array) if (!isDeep) { return arr } return flat(Array.prototype.concat.apply([], arr)) } const res = flat([1, 2, [3, 4], [5, [6, 7]]]) console.log(res) // [1, 2, 3, 4, 5, 6, 7] -
Дедупликация массива
отвечать:
- Традиционный способ, обход элементов один за другим для сравнения и дедупликации.
- Использовать набор
- Учитывайте вычислительную эффективность
// 传统方式 function unique(arr) { const res = [] arr.forEach(item => { if (res.indexOf(item) < 0) { res.push(item) } }) return res } console.log(unique([1, 2, 3, 1, 2, 3, 4])) // 1 2 3 4// 使用 Set(无序、不重复) function unique(arr) { const set = new Set(arr) return [...set] } console.log(unique([1, 2, 3, 1, 2, 3, 4])) // 1 2 3 4 -
рукописная глубокая копия
отвечать:
function deepClone(obj = {}) { // 如果不是数组或对象,直接返回 if (typeof obj !== 'object' || 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 } // 注意 Object.assign 不是深拷贝 -
Ввести РАФ (
requestAnimationFrame)отвечать:
- Для плавной анимации частота обновления должна составлять 60 кадров в секунду, что составляет 16,67 мс для однократного обновления представления.
-
setTimeoutЧтобы обновить частоту вручную, в то время как браузер RAF автоматически управляет - В фоновых вкладках или скрытых фреймах RAF приостанавливается, пока
setTimeoutвсе еще выполнять
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>setTimeout</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script> <style> #div1, #div2 { width: 100px; height: 50px; margin-bottom: 20px; background-color: red; } </style> </head> <body> <div id="div1">setTimeout</div> <div id="div2">requestAnimateFrame</div> <script> const $div1 = $('#div1') let curWidth = 100 const maxWidth = 640 function animate() { curWidth += 3 $div1.css('width', curWidth) if (curWidth < maxWidth) { setTimeout(animate, 16.7) } } animate() const $div2 = $('#div2') let curWidth2 = 100 function animate2() { curWidth2 += 3 $div2.css('width', curWidth2) if (curWidth2 < maxWidth) { window.requestAnimationFrame(animate2) } } animate2() </script> </body> </html> -
Как оптимизировать производительность интерфейса? Какие аспекты обычно учитываются?
отвечать:
- Принцип: используйте больше памяти, кеша, сокращайте вычислительные ресурсы и сетевые запросы.
- Направление: загрузка страницы, рендеринг страницы, беглость работы страницы