Цель этой статьи — записать вопросы, возникающие на собеседовании, в том числе общие, подверженные ошибкам и важные моменты знаний в js.
Разница между window.onload и document.ready
window.onload是在页面中包含图片在内的素有元素全部加载完成;
document.ready是文档结构加载完成,但不包含图片,其他媒体文件;
在jQuery中会看到$(function(){})和$(document).ready(function(){}),是在DOM树加载完成之后执行;
window.onload是在DOM树加载完以及所有文件加载完成才执行,因此慢于document.ready。
Дедупликация массива
var arr = ['a','bb','22','a','yuci','haha','22'];
- Метод set() es6
var unique = new Set(arr);
console.log(Array.from(unique));
- использовать push()
var arr2 = [];
for(var i = 0; i < arr.length; i++) {
(function(i) {
if(arr2.indexOf(arr[i]) == -1) { //不包含某个值则返回-1
arr2.push(arr[i]);
}
}(i))
}
console.log(arr2);
//如果当前数组的第i项在当前数组中第一次出现的位置不是i,那么表示第i项是重复的,忽略掉。否则存入结果数组
var arr3 = [arr[0]];
for(var i = 1; i < arr.length; i++) {
(function(i) {
if(arr.indexOf(arr[i]) == i) {
arr3.push(arr[i]);
}
}(i))
}
console.log(arr3);
- Сортировка для удаления соседних повторяющихся элементов
var arrSort = arr.sort();
var arr4 = [];
for(let i = 0; i< arrSort.length; i++) {
if(arrSort[i] != arrSort[i+1]) {
arr4.push(arrSort[i]);
}
}
console.log(arr4);
- использовать сращивание ()
var len = arr.length;
for(let i = 0; i < len; i++) {
for(let j = i + 1; j < len; j++) {
if(arr[i] === arr[j]) {
arr.splice(i,1);
len--;
j--;
}
}
}
console.log(arr);
делегация мероприятия
Благодаря всплыванию событий, когда несколько элементов имеют одно и то же событие, привяжите событие к родительскому элементу.
var oUl = document.getElementById('oul');
oUl.addEventListener('click', function(e) {
var e = e||window.event;
var tar = e.target;
if(tar.nodeName === 'LI') {
alert(tar.innerHTML);
}
})
Для получения более подробной информации см.:делегация мероприятия
Определить тип переменной
typeof() используется для оценки простых данных;
判断一个变量是对象还是数组使用instanceof,constructor或Object.prototype.toString.call();
Для получения более подробной информации см.:Определить тип данных
Синхронный и асинхронный (краткое объяснение)
同步:由于js单线程,同步任务都在主线程上排队执行,前面任务没执行完成,后面的任务会一直等待;
异步:不进入主线程,进入任务队列,等待主线程任务执行完成,开始执行。最基础的异步操作setTimeout和setInterval,等待主线程任务执行完,在开始执行里面的函数;
Для получения более подробной информации см.:механизм запуска js
Несколько случаев возврата false
ложь, ноль, 0, "", не определено, NaN
разница значений типов js
存储地:
简单数据类型:存储在栈中;
引用数据类型:存储在堆中,在栈中存储了指针,指向存储在堆中的地址,解释器会先检索在栈中的地址,从堆中获得实体;
大小:
简单数据类型:大小固定,占用空间小,频繁使用,所以存储在栈中;
引用数据类型:大小不固定,占用空间大;
Закрытие
何为闭包:有权访问另一个作用域中变量的函数
闭包特性:可实现函数外访问函数内变量,外层变量可以不被垃圾回收机制回收
为什么?怎么解决?
for(var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
Выходными результатами являются все 10, потому что анонимная функция не выполняется каждый раз, когда значение передается во время цикла for(), что эквивалентно выполнению function(){console.log(i);} 10 раз, и я становится 10 в конце цикла, поэтому на выходе все 10;
Используйте замыкания для обертывания самовыполняющихся анонимных функций:
for(var i = 0; i < 10; i++) {
(function(j) {
setTimeout(function() {
console.log(j);
}, 1000);
})(i);
}
Внешняя анонимная функция выполняется немедленно, присваивая i в качестве параметра и присваивая его j , Поскольку она выполняется немедленно, каждый раз через цикл выводятся разные значения.
Если внешняя переменная, на которую ссылаются, не используется повторно, она займет больше памяти, чем другие функции.Неправильное использование может легко привести к утечке памяти.
указатель на это
全局范围:指向window(严格模式下不存在全局变量,指向undefined);
普通函数调用:指向window;
对象方法调用:指向最后调用它的对象;
构造函数调用:指向new出来的对象;
显示设置this:call,apply方法显示将this指向第一个参数指明的对象
что именно сделал новый
创建一个新对象foo;
并将它的__proto__指向其构造函数的prototype,foo.__proto__ = Foo.prototype;
动态将this指向新对象,Foo.apply(foo,arguments);
执行函数体中的代码;
放回新对象foo;
Прототипы и цепочки прототипов
Создание функции создаст для нее свойство-прототип, указывающее на объект-прототип функции, а объект-прототип автоматически получит свойство-конструктор, указывающее на функцию, в которой находится свойство-прототип.
Function.prototype.a = "a";
Object.prototype.b = "b";
function Person(){}
console.log(Person); //function Person()
let p = new Person();
console.log(p); //Person {} 对象
console.log(p.a); //undefined
console.log(p.b); //b
p.__proto__ === Person.prototype;Person.prototype.constructor === Person
При вызове метода или поиске свойства он сначала вызывается и ищется сам в себе, если у него нет свойства или метода, то поиск будет вызываться в его свойстве __proto__, то есть в прототипе его конструктора , Вызовите поиск, если в конструкторе нет такого метода свойства, он будет искать в неявном прототипе конструктора до нуля и, таким образом, сформировать цепочку прототипов.
Подробнее о прототипах см.Прототипы и цепочки прототипов
Наследование
Наследование цепочки прототипов:
Прототип Child() используется как экземпляр Parent() для наследования свойств метода Parent().
Поскольку все экземпляры наследуют свойство метода прототипа, после того как один экземпляр изменяет значение свойства прототипа, все экземпляры вызывают изменение значения свойства.
function Parent() {}
Parent.prototype.parentSay = function() {
return 'i am parent';
}
function Child() {}
Child.prototype.childSay = function() {
return 'i am child';
}
Child.prototype = new Parent();
var par = new Parent();
var kid = new Child();
console.log(kid.parentSay()); //i am parent
Наследование конструктора:
Вызовите конструктор родительского класса, вызвав или применив внутри конструктора подкласса
Невозможно повторно использовать функции
function People() {
this.name = ['zhangsan','lisi','wangwu'];
}
function Person() {
People.call(this);
}
var per1 = new Person();
per1.name.push('zhanliu');
console.log(per1.name); //["zhangsan", "lisi", "wangwu", "zhanliu"]
var per2 = new Person();
console.log(per2.name); //["zhangsan", "lisi", "wangwu"]
Наследование композиции:
Сочетание наследования цепочки прототипов и наследования конструктора — наиболее часто используемый шаблон наследования.
Цепочка прототипов наследует общие свойства и методы, а конструктор наследует свойства экземпляра.
function People(num) {
this.num = num;
this.name = ['zhangsan','lisi','wangwu'];
}
People.prototype.numCount = function() {
console.log(this.num);
}
function Person(num) {
People.call(this, num);
}
//继承方式
Person.prototype = new People();
Person.prototype.constructor = Person;
var per1 = new Person(10);
per1.name.push('zhaoliu');
console.log(per1.name); //["zhangsan", "lisi", "wangwu", "zhanliu"]
per1.numCount(); //10
var per2 = new Person(20);
console.log(per2.name); //["zhangsan", "lisi", "wangwu"]
per2.numCount(); //20
Дополнительные методы наследования см.Наследование
Общие методы массивов
Измените исходный массив:
尾部删除pop(),尾部添加push(),头部删除shift(),头部添加unshift(),排序sort(),颠倒数组元素reverse(),删除或插入元素splice();
не изменяет группу элементов:
合并数组concat(),拼接数组元素join(),截取元素slice(),indexOf(),lastIndexOf(),toString()
Для более подробного обзора методов массива см.:Резюме метода массива массива
хранилище данных
Cookie:用于客户端与服务端通信,也具有本地存储的功能
localStorage,sessionStorage:专门用于存储
区别:
大小:Cookie容量为4K,因为用于客户端与服务端通信,所有http都携带,如果太大会降低效率; localStorage,sessionStorage大小为5M。
失效时间:Cookie会在浏览器关闭时删除,除非主动设置删除时间;localStorage一直都在直到用户主动删除或清除浏览器缓存;sessionStorage在浏览器关闭时删除。
Заключительные замечания:
Если есть ошибка, поправьте меня