1、什么是html 它的作用是什么,html5的新特性和改进
HTML是超文本标记语言,适用于创建网页的标准标记语言。他可以被所有浏览器解析,并用于构建网页的结构和内容。 HTML的主要作用是定义网页的结构和内容。 例如使用h1-h6标签定义标题,使用p来定义段落
html5的新特性
-
新的语义元素:HTML5 引入了一些新的语义元素,如
<article>
、<section>
、<nav>
、<header>
、<footer>
、<aside>
和<figure>
,这些元素可以使网页的结构更清晰,更易于理解。 -
表单改进:HTML5 提供了新的输入类型(如
email
、date
、time
、url
、search
等)和新的表单元素(如<datalist>
、<output>
等),以支持更复杂的用户输入。 -
图形和多媒体元素:HTML5 引入了
<canvas>
元素,用于在网页上绘制图形,以及<video>
和<audio>
元素,用于在网页上播放视频和音频。 -
Web 存储:HTML5 提供了 Web Storage API 和 IndexedDB API,用于在浏览器上存储数据,这使得可以创建更复杂的离线应用程序。
-
地理位置:HTML5 提供了 Geolocation API,用于获取用户的地理位置。
-
Web Workers 和 Web Sockets:HTML5 提供了 Web Workers API 和 Web Sockets API,用于支持在后台运行任务和实时通信。
-
拖放 API:HTML5 提供了拖放 API,用于在网页上实现拖放功能。
2、标准盒子模型(宽即是宽,高即是高)box-sizing: content-box;
怪异盒子模型(宽=width+border+padding)box-sizing:border-box;
3.说说JavaScript中的数据类型?存储上的差别?
在 JavaScript 中,有两种主要的数据类型:原始类型(Primitive Types)和对象类型(Object Types)。
原始类型包括:
- Number:用于表示数字,包括整数和浮点数。
- String:用于表示文本数据,由零个或多个字符组成。
- Boolean:有两个值,
true
和false
,用于表示逻辑真或假。 - Null:有一个值,
null
,表示没有值或没有对象。 - Undefined:有一个值,
undefined
,表示变量已声明但未赋值。 - Symbol:(ES6 引入)表示唯一的标识符。
- BigInt:(ES10 引入)用于表示大于
2^53 - 1
的整数。
对象类型包括:
- Object:用于存储键值对的集合。
- Array:用于存储有序的值的集合。
- Function:可执行的代码块。
- Date:用于处理日期和时间的内置对象。
- RegExp:用于处理正则表达式的内置对象。
- Map, Set, WeakMap, WeakSet:(ES6 引入)用于存储集合的内置对象。
- Promise:(ES6 引入)用于处理异步操作的内置对象。
在存储上的差别:
原始类型的值存储在栈(Stack)中,它们的大小固定,所以可以快速查找变量。当你访问一个原始类型的变量,实际上访问的是存储在栈中的那个值。
对象类型的值存储在堆(Heap)中,它们的大小不固定,所以存储在堆中的地址。当你访问一个对象类型的变量,实际上访问的是存储在栈中的地址,这个地址指向堆中的对象。
当你把一个原始类型的值赋给另一个变量,实际上是在栈中创建了那个值的一个副本。但当你把一个对象类型的值赋给另一个变量,实际上是在栈中创建了那个地址的一个副本,这个地址指向堆中的同一个对象。因此,改变一个变量会影响到另一个变量。
4.什么是闭包(Closure)?它有什么作用和优缺点?
在 JavaScript 中,闭包是一个函数与其词法环境的组合。这个环境包含了闭包创建时所在作用域中的任何局部变量。简单来说,闭包就是一个函数记住并访问其外部作用域的变量,即使它在外部作用域外部执行。
闭包有三个特性:
- 函数嵌套函数。
- 内部函数可以引用外部函数的变量。
- 变量的值始终保持在内存中。(闭包的一个重要特性是它可以“记住”创建它的环境。这意味着,即使外部函数已经返回并且其执行上下文已经从执行栈中弹出,闭包仍然可以访问外部函数的变量。这是因为这些变量被存储在内存中,不会随着函数的结束而被清除。)
作用:
-
数据封装和私有变量:闭包可以用来模拟私有变量,因为闭包的内部变量对外部是不可见的,只能通过闭包提供的函数来访问。
-
创建特权方法:在对象和构造函数中,可以使用闭包来创建公有方法,这些方法可以访问到私有变量。(
function Person(name, age) {
// 私有变量
let _name = name;
let _age = age;
// 特权方法
this.getName = function() {
return _name;
};
this.getAge = function() {
return _age;
};
}
const john = new Person('John', 30);
console.log(john.getName()); // 输出:John
console.log(john.getAge()); // 输出:30)在这个例子中,
_name
和_age
是Person
构造函数的私有变量,它们不能直接从外部访问。但我们可以通过闭包创建特权方法getName
和getAge
,这些方法可以访问到_name
和_age
。 -
维持状态:闭包可以记住并访问其创建时的环境,这意味着它可以在多次调用之间维持状态。例子便于理解(
function makeCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter1 = makeCounter();
const counter2 = makeCounter();
console.log(counter1()); // 输出:1
console.log(counter1()); // 输出:2
console.log(counter2()); // 输出:1
console.log(counter1()); // 输出:3
console.log(counter2()); // 输出:2)
优点:
-
模块化和信息隐藏:闭包可以帮助我们创建模块,这些模块可以隐藏内部实现细节,只暴露出需要的接口。
-
维持状态:闭包可以在函数执行完毕后仍然记住和访问外部作用域的变量,这对于异步编程和回调函数非常有用。
缺点:
-
内存消耗:由于闭包会持有外部作用域的变量,所以如果不正确地使用闭包,可能会导致内存泄漏。
-
性能问题:创建闭包需要系统动态创建对象和存储空间,这会比普通函数调用有更大的开销。
-
复杂性:过度使用闭包可能会导致代码难以理解和维护。
闭包的应用场景:
- 数据隐藏和封装:闭包可以用来创建私有变量,这些变量只能通过提供的公有方法访问,而不能直接访问。这是一种模拟面向对象编程中的私有属性的方法
function createCounter() {
let count = 0;
return {
increment: function() {
count++;
},
getCount: function() {
return count;
}
};
}
const counter = createCounter();
counter.increment();
console.log(counter.getCount()); // 输出 1
2.创建工厂和构造函数:闭包可以用来创建可以维持自己状态的对象和函数。
function createAdder(x) {
return function(y) {
return x + y;
};
}
const add5 = createAdder(5);
console.log(add5(2)); // 输出 7
3.在异步编程中维持状态:在异步编程中,闭包可以用来在回调函数中访问外部作用域的变量。在 下面的例子中,闭包用来在 setTimeout 的回调函数中访问循环变量 i。如果不使用闭包,那么所有的回调函数都会访问到同一个 i,即循环结束后的 i。
for (var i = 0; i < 5; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, i * 1000);
})(i);
}
4.实现节流和防抖:闭包可以用来实现函数的节流(throttle)和防抖(debounce),这在处理频繁触发的事件(如滚动、输入、点击等)时非常有用。
5.防抖和节流的应用
防抖:用户点击了好多次,只执行最后一次。例如,如果用户在输入框中连续输入文字,我们可能只想在用户停止输入后执行一次函数,而不是每次输入一个字符就执行一次。
// 防抖
function debounce(func, wait) {
let timeout;
return function() {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, arguments), wait);
};
}
// 使用例子
window.addEventListener('scroll', debounce(function() {
console.log('Debounce: Scrolling');
}, 250));
防抖函数接受两个参数:一个是要执行的函数 func
,另一个是等待时间 wait
。它返回一个新的函数,这个新函数在每次调用时都会清除之前的定时器并设置一个新的定时器。如果在 wait
时间内没有再次调用这个新函数,那么定时器到期时就会执行 func
函数。这就实现了防抖的效果。
节流:每隔一段时间只会执行一次
// 节流
function throttle(func, wait) {
let lastTime = 0;
return function() {
let now = Date.now();
if (now - lastTime > wait) {
lastTime = now;
func.apply(this, arguments);
}
};
}
window.addEventListener('scroll', throttle(function() {
console.log('Throttle: Scrolling');
}, 250));