前端杂学录(四)

 1.JSON.parse() 和 JSON.stringify()

JSON.stringify()

  • 功能:将 JavaScript 对象或值转换为 JSON 字符串。
  • 语法
JSON.stringify(value[, replacer[, space]]);
  • 参数

    • value:要转换的 JavaScript 值(通常是对象或数组)。
    • replacer(可选):可以是一个函数或数组,用于控制哪些值应该被包含在 JSON 字符串中。
    • space(可选):用于添加空格以便更好地格式化输出的字符串。
  • 返回:返回一个 JSON 字符串。

  • 示例

const obj = {
    name: "Alice",
    age: 25,
    hobbies: ["reading", "traveling"]
};

const jsonString = JSON.stringify(obj);
console.log(jsonString); 
// 输出: {"name":"Alice","age":25,"hobbies":["reading","traveling"]}

JSON.parse()

  • 功能:将 JSON 字符串转换为 JavaScript 对象。
  • 语法
JSON.parse(text[, reviver]);
  • 参数

    • text:要解析的 JSON 字符串。
    • reviver(可选):一个函数,可以在解析过程中对每个键值进行处理。
  • 返回:返回一个 JavaScript 对象或值。

  • 示例

const jsonString = '{"name":"Alice","age":25,"hobbies":["reading","traveling"]}';
const obj = JSON.parse(jsonString);
console.log(obj); 
// 输出: { name: 'Alice', age: 25, hobbies: [ 'reading', 'traveling' ] }

注意事项

  1. 格式要求

    • 在使用 JSON.parse() 时,输入的字符串必须是有效的 JSON 格式,否则将抛出 SyntaxError
    • JSON 字符串中的键必须用双引号包围。
  2. 数据类型

    • JSON.stringify() 会将 JavaScript 对象转换为字符串,支持的类型包括对象、数组、字符串、数字、布尔值和 null
    • JSON.parse() 将字符串解析为 JavaScript 对象,支持的类型包括对象、数组、字符串、数字、布尔值和 null
  3. 循环引用

    • JSON.stringify() 不支持包含循环引用的对象,会抛出 TypeError
    • JSON.parse() 不涉及循环引用。

2.Object.create()、Object.defineProperty()、Object.keys() 等方法。

1. Object.create()

  • 功能:创建一个新对象,使用指定的原型对象和可选的属性对象。
  • 语法
Object.create(proto[, propertiesObject]);
  • 参数

    • proto:新创建对象的原型。
    • propertiesObject(可选):一个对象,可以为新对象定义属性。
  • 返回:返回一个新对象。

  • 示例

const animal = {
    eats: true
};

const rabbit = Object.create(animal);
console.log(rabbit.eats); // 输出: true
console.log(rabbit); // 输出: {},没有直接属性

2. Object.defineProperty()

  • 功能:直接在一个对象上定义一个新属性,或修改一个现有属性,并返回该对象。
  • 语法
Object.defineProperty(obj, prop, descriptor);
  • 参数

    • obj:要在其上定义属性的对象。
    • prop:要定义或修改的属性的名称。
    • descriptor:描述符对象,描述属性的特性。
  • 返回:返回对象本身。

  • 示例

const obj = {};
Object.defineProperty(obj, 'name', {
    value: 'Alice',
    writable: false, // 不可写
    enumerable: true, // 可枚举
    configurable: false // 不可配置
});

console.log(obj.name); // 输出: Alice
obj.name = 'Bob'; // 无法修改,因为 writable 为 false
console.log(obj.name); // 仍然输出: Alice

3. Object.keys()

  • 功能:返回一个数组,包含对象自身可枚举属性的键名(不包括原型链上的属性)。
  • 语法
Object.keys(obj);
  • 参数

    • obj:要获取其可枚举属性名的对象。
  • 返回:一个数组,包含对象的可枚举属性名。

  • 示例

const obj = {
    name: 'Alice',
    age: 25,
    job: 'Developer'
};

const keys = Object.keys(obj);
console.log(keys); // 输出: ["name", "age", "job"]

总结

  • Object.create():用于创建一个新对象,指定原型。
  • Object.defineProperty():用于定义或修改对象的属性,可以控制属性的特性(如可写、可枚举等)。
  • Object.keys():用于获取对象的可枚举属性的键名数组。

3.模板字符串

模板字符串(Template Strings)是 JavaScript 中的一种字符串字面量,可以方便地创建多行字符串以及嵌入表达式。模板字符串使用反引号(`)包裹,具有以下几个主要特性:

1. 多行字符串

使用模板字符串,可以轻松创建多行字符串,而不需要使用换行符或字符串连接符。

const multiLineString = `这是一个多行字符串。
它可以包含换行,而不需要使用 \n。`;
console.log(multiLineString);

2. 字符串插值

模板字符串支持内嵌表达式,使用 ${} 语法,可以将变量或表达式的值嵌入字符串中。

const name = 'Alice';
const age = 25;
const greeting = `你好,我叫 ${name},我今年 ${age} 岁。`;
console.log(greeting); // 输出: 你好,我叫 Alice,我今年 25 岁。

3. 嵌套模板字符串

模板字符串也支持嵌套,可以在字符串中包含其他模板字符串。

const user = {
    name: 'Alice',
    age: 25
};

const message = `用户信息: ${`姓名: ${user.name}, 年龄: ${user.age}`}`;
console.log(message); // 输出: 用户信息: 姓名: Alice, 年龄: 25

4. 标签模板字符串

标签模板字符串允许你定义一个函数来处理模板字符串。你可以在函数中访问模板字符串的内容和插值。

function customTag(strings, ...values) {
    return strings.reduce((result, str, i) => {
        return result + str + (values[i] ? `<b>${values[i]}</b>` : '');
    }, '');
}

const name = 'Alice';
const age = 25;
const output = customTag`你好,我叫 ${name},我今年 ${age} 岁。`;
console.log(output); 
// 输出: 你好,我叫 <b>Alice</b>,我今年 <b>25</b> 岁。

4.解构赋值

解构赋值(Destructuring Assignment)是 JavaScript 中的一种简洁的语法,用于从数组或对象中提取值,并将其分配给变量。它使得代码更加简洁和易读。

1. 数组解构赋值

可以从数组中提取值并将其赋值给变量。

示例:
const arr = [1, 2, 3];

// 解构赋值
const [a, b, c] = arr;

console.log(a); // 输出: 1
console.log(b); // 输出: 2
console.log(c); // 输出: 3
忽略某些值:
const arr = [1, 2, 3];

// 只提取第一个和第三个值
const [first, , third] = arr;

console.log(first); // 输出: 1
console.log(third); // 输出: 3
默认值:

如果数组中的某个值是 undefined,可以指定默认值。

const arr = [1];

// b 将会是 2,因为 arr[1] 是 undefined
const [a, b = 2] = arr;

console.log(a); // 输出: 1
console.log(b); // 输出: 2

2. 对象解构赋值

可以从对象中提取属性并将其赋值给变量。

示例:
const obj = { x: 1, y: 2 };

// 解构赋值
const { x, y } = obj;

console.log(x); // 输出: 1
console.log(y); // 输出: 2
重命名变量:

可以在解构时重命名变量。

const obj = { x: 1, y: 2 };

// 重命名变量
const { x: a, y: b } = obj;

console.log(a); // 输出: 1
console.log(b); // 输出: 2
默认值:

同样可以为对象的属性指定默认值。

const obj = { x: 1 };

// y 将会是 2,因为 obj.y 是 undefined
const { x, y = 2 } = obj;

console.log(x); // 输出: 1
console.log(y); // 输出: 2

3. 嵌套解构赋值

可以对嵌套的数组或对象进行解构赋值。

数组嵌套:
const arr = [1, [2, 3]];

const [a, [b, c]] = arr;

console.log(a); // 输出: 1
console.log(b); // 输出: 2
console.log(c); // 输出: 3
对象嵌套:
const obj = {
    user: {
        name: 'Alice',
        age: 25
    }
};

const { user: { name, age } } = obj;

console.log(name); // 输出: Alice
console.log(age); // 输出: 25

4. 函数参数解构

解构赋值可以用于函数参数,使得函数参数更易于管理。

function greet({ name, age }) {
    console.log(`你好,我叫 ${name},今年 ${age} 岁。`);
}

const user = { name: 'Alice', age: 25 };

greet(user); // 输出: 你好,我叫 Alice,今年 25 岁。

5.扩展运算符

扩展运算符(Spread Operator)是 JavaScript 中的一种语法,允许可迭代对象(如数组或字符串)在需要多个元素的地方展开。扩展运算符使用三个点(...)表示,提供了简洁的方式来处理数组和对象。

1. 数组的扩展

示例:合并数组

可以使用扩展运算符将多个数组合并为一个数组。

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

const combined = [...arr1, ...arr2];
console.log(combined); // 输出: [1, 2, 3, 4, 5, 6]
示例:复制数组

可以创建数组的浅拷贝。

const arr = [1, 2, 3];
const copy = [...arr];

console.log(copy); // 输出: [1, 2, 3]
console.log(copy === arr); // 输出: false,两个数组不同
示例:添加元素

可以在数组的开头或结尾添加元素。

const arr = [2, 3, 4];
const newArr = [1, ...arr, 5];

console.log(newArr); // 输出: [1, 2, 3, 4, 5]

2. 对象的扩展

扩展运算符也可以用来创建对象的浅拷贝或合并对象。

示例:合并对象
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };

const merged = { ...obj1, ...obj2 };
console.log(merged); // 输出: { a: 1, b: 3, c: 4 }

在合并对象时,如果有相同的属性,后面的对象的属性值会覆盖前面的。

示例:复制对象
const obj = { a: 1, b: 2 };
const copy = { ...obj };

console.log(copy); // 输出: { a: 1, b: 2 }
console.log(copy === obj); // 输出: false,两个对象不同

3. 函数调用中的扩展

扩展运算符可以用于将数组展开为函数参数。

示例:
const numbers = [1, 2, 3, 4];

function sum(x, y, z, w) {
    return x + y + z + w;
}

const result = sum(...numbers);
console.log(result); // 输出: 10

4. 字符串的扩展

扩展运算符可以将字符串转换为数组。

const str = "Hello";
const chars = [...str];

console.log(chars); // 输出: ['H', 'e', 'l', 'l', 'o']

6.map、reduce、filter 的所有用法,其他高阶函数

1. map()

  • 功能:创建一个新数组,包含通过调用提供的函数处理过的每个元素。
  • 语法
const newArray = array.map(callback(currentValue[, index[, array]])[, thisArg]);
  • 参数

    • callback:对每个数组元素执行的函数。
    • currentValue:当前处理的元素。
    • index(可选):当前元素的索引。
    • array(可选):调用 map 的数组。
    • thisArg(可选):执行回调时的 this 值。
  • 示例

const numbers = [1, 2, 3, 4];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // 输出: [2, 4, 6, 8]

2. reduce()

  • 功能:对数组中的每个元素执行一个 reducer 函数,累计结果,最终返回单个值。
  • 语法
const result = array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]);
  • 参数

    • callback:对每个元素执行的函数。
    • accumulator:累计值。
    • currentValue:当前处理的元素。
    • index(可选):当前元素的索引。
    • array(可选):调用 reduce 的数组。
    • initialValue(可选):第一次调用回调函数时 accumulator 的值。
  • 示例

const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 输出: 10

3. filter()

  • 功能:创建一个新数组,包含通过提供的函数测试的所有元素。
  • 语法
const newArray = array.filter(callback(element[, index[, array]])[, thisArg]);
  • 参数

    • callback:对每个元素执行的函数。
    • element:当前处理的元素。
    • index(可选):当前元素的索引。
    • array(可选):调用 filter 的数组。
    • thisArg(可选):执行回调时的 this 值。
  • 示例

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // 输出: [2, 4]

其他常用的高阶函数

  1. find()

    • 功能:返回数组中满足提供的测试函数的第一个元素的值,找不到则返回 undefined
    • 示例
    const numbers = [1, 2, 3, 4, 5];
    const firstEven = numbers.find(num => num % 2 === 0);
    console.log(firstEven); // 输出: 2
    
  2. some()

    • 功能:检测数组中是否至少有一个元素满足提供的测试函数,返回 true 或 false
    • 示例
    const numbers = [1, 2, 3, 4, 5];
    const hasEven = numbers.some(num => num % 2 === 0);
    console.log(hasEven); // 输出: true
    
  3. every()

    • 功能:检测数组中的所有元素是否都满足提供的测试函数,返回 true 或 false
    • 示例
    const numbers = [2, 4, 6, 8];
    const allEven = numbers.every(num => num % 2 === 0);
    console.log(allEven); // 输出: true
    
  4. forEach()

    • 功能:对数组的每个元素执行提供的函数,没有返回值。
    • 示例
    const numbers = [1, 2, 3];
    numbers.forEach(num => console.log(num * 2));
    // 输出: 2, 4, 6
    
  5. sort()

    • 功能:对数组元素进行排序,原地改变数组。
    • 示例
    const numbers = [4, 2, 3, 1];
    numbers.sort((a, b) => a - b);
    console.log(numbers); // 输出: [1, 2, 3, 4]

7.JavaScript提供的正则表达式API

1. 创建正则表达式

1.1 字面量语法
const regex = /pattern/flags;
组成部分
  1. /pattern/

    • pattern 是你想要匹配的字符串模式,可以是字符、字符类、量词、分组等。例如,/abc/ 匹配字符串 "abc"。
  2. flags(可选):

    • flags 是用于修改正则表达式行为的选项,通常是一个或多个字母,表示不同的标志。常见的标志包括:
      • g:全局匹配(global),查找所有匹配项,而不是找到第一个就停止。
      • i:不区分大小写(ignore case),匹配时忽略字母的大小写。
      • m:多行匹配(multiline),使 ^ 和 $ 能够匹配每一行的开始和结束,而不仅仅是整个字符串的开始和结束。
      • s:允许 . 匹配换行符(dotall)。
      • u:启用 Unicode 匹配(unicode)。
      • y:粘性匹配(sticky),只有在字符串的当前位置匹配时才会有效。

        

示例
// 匹配所有字母 a 的字符串,不区分大小写
const regex = /a/i;

// 匹配字符串中的所有数字
const globalRegex = /\d/g;

// 匹配多行字符串中的每一行
const multilineRegex = /^Hello/m;
使用示例
  1. 测试字符串
const str = "Hello World!";
const regex = /hello/i; // 不区分大小写
console.log(regex.test(str)); // 输出: true
  1. 查找匹配项
const text = "abc abc abc";
const regex = /abc/g; // 全局匹配
const matches = text.match(regex);
console.log(matches); // 输出: ["abc", "abc", "abc"]
  1. 替换字符串
const text = "Hello World!";
const regex = /world/i; // 不区分大小写
const newText = text.replace(regex, "Universe");
console.log(newText); // 输出: "Hello Universe!"
1.2 构造函数
const regex = new RegExp('pattern', 'flags');

2. 常用方法

2.1 test()

用于测试字符串是否匹配正则表达式,返回布尔值。

const regex = /hello/;
console.log(regex.test('hello world')); // true
2.2 exec()

用于执行匹配,返回匹配结果的数组或 null

const regex = /(\w+) (\w+)/;
const result = regex.exec('John Doe');
console.log(result); // ["John Doe", "John", "Doe"]
  • /(\w+) (\w+)/
    • /:表示正则表达式的开始和结束。
    • (\w+):第一个捕获组,匹配一个或多个字母、数字或下划线(\w 表示字母、数字或下划线,+ 表示一次或多次)。
    • :一个空格字符,用于分隔两个单词。
    • (\w+):第二个捕获组,匹配另一个一个或多个字母、数字或下划线。

3. 字符串方法

3.1 String.prototype.match()

返回与正则表达式匹配的结果。

const str = 'The quick brown fox';
const result = str.match(/\w+/g);
console.log(result); // ["The", "quick", "brown", "fox"]
  • /\w+/g
    • /:表示正则表达式的开始和结束。
    • \w+
      • \w:匹配任何字母、数字或下划线(相当于 [A-Za-z0-9_])。
      • +:表示匹配前面的元素一次或多次,即匹配一个或多个字符。
    • g:全局标志(global),表示在整个字符串中查找所有匹配,而不仅仅是第一个。
3.2 String.prototype.replace()

根据正则表达式替换字符串中的内容。

const str = 'Hello World';
const newStr = str.replace(/World/, 'JavaScript');
console.log(newStr); // "Hello JavaScript"
3.3 String.prototype.search()

返回匹配正则表达式的第一个索引位置,未找到时返回 -1。

const str = 'Hello World';
const index = str.search(/World/);
console.log(index); // 6
3.4 String.prototype.split()

根据正则表达式分割字符串。

const str = 'one, two, three';
const parts = str.split(/,\s*/);
console.log(parts); // ["one", "two", "three"]
  • /,\s*/
    • /:表示正则表达式的开始和结束。
    • ,:匹配逗号字符。
    • \s*
      • \s:匹配任何空白字符(包括空格、制表符、换行符等)。
      • *:表示匹配前面的元素零次或多次,即可以匹配零个或多个空白字符。

8.使用正则表达式(邮箱校验、URL解析、去重等)解决常见问题

1. 邮箱校验

邮箱格式是一个非常典型的正则表达式应用场景。一个有效的邮箱通常由用户名部分、"@" 符号以及域名部分组成。

示例:邮箱校验
function validateEmail(email) {
    const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
    return emailRegex.test(email);
}

console.log(validateEmail('example@test.com'));  // true
console.log(validateEmail('invalid-email'));      // false
解释:
  • ^[a-zA-Z0-9._%+-]+: 匹配邮箱用户名部分,可以包含字母、数字、点、下划线、百分号、加号和减号。
  • @[a-zA-Z0-9.-]+: 匹配 "@" 符号及域名部分。
  • \.[a-zA-Z]{2,}$: 匹配顶级域名,至少包含 2 个字母。

2. URL 解析

解析 URL 可以帮助提取协议、域名、路径等信息。通过正则表达式,可以从 URL 中轻松提取这些部分。

示例:URL 解析
function parseURL(url) {
    const urlRegex = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([\/\w .-]*)*\/?$/;
    const result = url.match(urlRegex);
    return result ? {
        protocol: result[1] || 'http',
        domain: result[2],
        tld: result[3],
        path: result[4] || '/'
    } : null;
}

console.log(parseURL('https://www.example.com/path/to/resource'));
// 输出:
// {
//   protocol: 'https://',
//   domain: 'www.example',
//   tld: 'com',
//   path: '/path/to/resource'
// }
解释:
  • ^(https?:\/\/)?: 匹配协议部分(http://https://),? 表示可选。
  • ([\da-z.-]+): 匹配域名部分,可以是字母、数字、点和连字符。
  • \.([a-z.]{2,6}): 匹配顶级域名(如 .com.net),字符长度为 2 到 6。
  • ([\/\w .-]*)*: 匹配路径部分,可以包含 /、字母、数字、点、空格和连字符。
  • \/?: 匹配可选的末尾斜杠。

3. 数组去重

虽然正则表达式本身不能直接对数组进行操作,但可以用它来清理或提取特定的字符串,再结合其他 JavaScript 方法达到去重的效果。

示例:字符串去重

假设我们有一个包含重复字符串的数组,使用正则表达式结合 JavaScript 来清除多余的空格和去重。

function deduplicateAndTrim(arr) {
    const cleanArray = arr.map(item => item.replace(/\s+/g, '').toLowerCase());
    return [...new Set(cleanArray)];
}

const data = [' apple ', 'Apple', 'orange ', ' ORANGE  ', 'Banana'];
console.log(deduplicateAndTrim(data)); // ['apple', 'orange', 'banana']
解释:
  • item.replace(/\s+/g, ''): 通过正则表达式去除字符串中的所有空格。
  • new Set(): 利用 Set 数据结构来去除数组中的重复项。

4. 提取电话号码

提取字符串中的电话号码也是正则表达式的常见应用。电话号码的格式可能包括国家代码、区号和连字符等。

示例:提取电话号码
function extractPhoneNumbers(text) {
    const phoneRegex = /(\+?\d{1,4}[-.\s]?)?\(?\d{2,4}\)?[-.\s]?\d{3,4}[-.\s]?\d{4}/g;
    return text.match(phoneRegex);
}

const text = "Call me at (123) 456-7890 or +1-800-555-1234.";
console.log(extractPhoneNumbers(text));  // ['(123) 456-7890', '+1-800-555-1234']
解释:
  • (\+?\d{1,4}[-.\s]?)?: 匹配可选的国家代码部分,包含 + 号及 1 到 4 位数字,可能以连字符、点或空格分隔。
  • \(?\d{2,4}\)?: 匹配区号,允许有圆括号包裹。
  • [-.\s]?: 匹配连字符、点或空格。
  • \d{3,4}: 匹配 3 到 4 位数字。
  • [-.\s]?: 匹配连字符、点或空格。

5. 校验身份证号(中国大陆)

中国大陆的身份证号码格式是 18 位,前 17 位是数字,第 18 位可能是数字或 X

示例:校验身份证号
function validateIDCard(idCard) {
    const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/;
    return idCardRegex.test(idCard);
}

console.log(validateIDCard('110105199003076519'));  // true
console.log(validateIDCard('12345678901234567X'));  // true
解释:
  • ^[1-9]\d{5}: 匹配地区码,6 位数字,且首位不能为 0。
  • (18|19|20)\d{2}: 匹配出生年份,范围为 1800-2099 年。
  • (0[1-9]|1[0-2]): 匹配月份。
  • (0[1-9]|[12]\d|3[01]): 匹配日期。
  • \d{3}: 匹配顺序号。
  • (\d|X)$: 匹配最后一位校验码,可以是数字或 X

9.JavaScript异常处理的方式,统一的异常处理方案

1. 常见的异常处理方式

1.1 try...catch

try...catch 语句用于捕获在 try 块中抛出的异常,并在 catch 块中处理它。

1.2 throw

可以使用 throw 语句主动抛出异常。

1.3 finally

finally 块用于无论是否抛出异常都会执行的代码,常用于清理工作。

2. 统一的异常处理方案

使用全局错误处理

通过 window.onerror 可以捕获全局未处理的异常。

10.从规范的角度理解HTML

1. HTML 规范

HTML 规范是由万维网联盟(W3C)和网页内容可访问性指南(WCAG)制定的标准。它定义了 HTML 的语法、标签、属性及其使用方式。

2. 文档结构

  • DOCTYPE 声明:每个 HTML 文档应以 <!DOCTYPE html> 开头,告诉浏览器文档类型。
  • 根元素 <html>:整个文档的根元素,包含 <head><body>
  • 头部 <head>:包含文档的元数据(如标题、字符集、样式链接等)。
  • 主体 <body>:文档的可见内容,包含所有页面元素。

3. 标签的使用

  • 语义化标签:使用符合内容意义的标签,如 <header><footer><article> 等,以提高可访问性和 SEO。
  • 自闭合标签:对于自闭合标签(如 <img><br>),必须确保它们正确关闭。
  • 属性规范:标签的属性需使用小写字母,并遵循规范格式,如 althref

4. 可访问性和兼容性

  • 可访问性:使用适当的标签和属性(如 alttitle)来增强可访问性,确保屏幕阅读器和其他辅助工具能正确解析页面内容。
  • 跨浏览器兼容性:遵循规范可以确保在不同浏览器和设备上有一致的表现,减少渲染问题。

5. 最佳实践

  • 结构化内容:使用语义化标签和适当的标题层级,确保内容结构清晰。
  • 验证 HTML:使用 W3C 的 HTML 验证工具检查代码,确保符合规范。
  • 保持更新:跟随 HTML 规范的最新版本(如 HTML5),使用新的功能和特性。

11.如何从分类和语义的角度使用标签

1. HTML 标签的分类

1.1 文档结构标签
  • <!DOCTYPE>: 定义文档类型,必须在 HTML 文档的最顶部。
  • <html>: 根元素,所有 HTML 内容的父元素。
  • <head>: 包含元数据,如 <title><meta><link><style>
  • <body>: 网页的主体部分,包含所有可见内容。
1.2 语义标签
  • <header>: 定义文档或节的头部,通常包含导航和标题。
  • <footer>: 定义文档或节的底部,通常包含版权信息和联系方式。
  • <main>: 定义文档的主要内容,确保文档的主内容区域。
  • <article>: 表示独立的内容单元,如博客文章或新闻项。
  • <section>: 表示文档中的一个主题区域,通常包含标题。
  • <nav>: 表示导航链接的区域。
1.3 其他常用标签
  • 段落标签<p>,用于定义段落。
  • 列表标签<ul>(无序列表)、<ol>(有序列表)、<li>(列表项)。
  • 链接标签<a>,用于创建超链接。
  • 图像标签<img>,用于插入图像。
  • 表格标签<table><tr><td><th>,用于定义表格。

2. 从语义角度使用标签

使用语义标签可以增强网页的可读性和可访问性,使搜索引擎更容易理解内容。以下是一些最佳实践:

2.1 使用适当的标题标签
  • 使用 <h1><h6> 标签按层级组织标题。
  • 确保 <h1> 只出现一次,通常用于文档的主标题。
2.2 组织内容
  • 使用 <article><section> 来组织内容,使每个部分的目的明确。
  • 例如,使用 <section> 来划分不同主题,使用 <article> 来表示具体的内容单元。
2.3 提供可访问的链接和图像
  • <a><img> 标签中提供 hrefalt 属性,以便搜索引擎和辅助技术更好地理解内容。
    <a href="https://example.com" title="Visit Example">Visit Example</a>
    <img src="image.jpg" alt="Description of the image">
    

12.常用页面标签的默认样式

1. 标题标签(<h1><h6>

  • 默认样式
    • <h1>: 大号加粗文本,通常为 2em 或更大。
    • <h2>: 略小于 <h1>,通常为 1.5em。
    • <h3>: 较小,通常为 1.17em。
    • <h4>: 更小,通常为 1em。
    • <h5>: 通常为 0.83em。
    • <h6>: 最小,通常为 0.67em。
  • 默认间距:通常在上下方都有较大的外边距(margin)。

2. 段落标签(<p>

  • 默认样式
    • 字体大小:通常为 1em。
    • 字体加粗:不加粗。
  • 默认间距:通常有上下外边距,通常为 1em。

3. 列表标签(<ul><ol><li>

  • 默认样式
    • <ul>: 通常有默认的左内边距(padding)和项目符号(如圆点)。
    • <ol>: 默认的有序列表,通常有数字作为项目符号。
    • <li>: 列表项的字体样式与段落类似,通常有上下外边距。

4. 链接标签(<a>

  • 默认样式
    • 字体颜色:通常为蓝色。
    • 下划线:通常带有下划线。
  • 默认状态:悬停(hover)状态通常改变颜色。

5. 图像标签(<img>

  • 默认样式
    • 图像为块级元素,默认没有边距和内边距。

6. 表格标签(<table><tr><td><th>

  • 默认样式
    • <table>: 通常没有边框,但有一些内边距。
    • <th>: 通常加粗并居中。
    • <td>: 默认不加粗,但有内边距。
    • <table>:包裹整个表格。
    • <tr>:用于定义每一行。
    • <th>:用于定义表头单元格,通常在第一行。
    • <td>:用于定义数据单元格,包含实际的数据。

7. 块级与行内元素

  • 块级元素:如 <div><h1><p>,默认宽度为 100%,每个元素会在新行开始。
  • 行内元素:如 <span><a><img>,默认宽度为内容的宽度,不会在新行开始。

 13.块级与行内元素

块级元素

特性

  • 块级元素通常在新行开始,并占据整个行的宽度。
  • 它们可以包含其他块级元素和行内元素。
  • 常用于构建页面的结构。

常见的块级元素

  • <div>
  • <h1><h2><h3><h4><h5><h6>(标题元素)
  • <p>(段落)
  • <ul><ol><li>(无序和有序列表)
  • <blockquote>(引用)
  • <table>(表格)

行内元素

特性

  • 行内元素不会在新行开始,它们仅占据其内容所需的宽度。
  • 行内元素只能包含文本和其他行内元素,不能包含块级元素。
  • 常用于文本格式化。

常见的行内元素

  • <span>
  • <a>(链接)
  • <strong>(加粗文本)
  • <em>(斜体文本)
  • <img>(图片)
  • <br>(换行)

块级与行内元素的对比

特性块级元素行内元素
是否换行
占据空间占据整行宽度仅占据内容宽度
能包含的元素可以包含其他块级和行内元素仅能包含行内元素
常用场景布局、结构文本格式化、链接

14.CSS中常用页面标签的自带属性

1. 块级元素

<div>
  • 默认样式
    • display: block;
    • 占满可用宽度。
    • 上下外边距(margin)可以影响布局。
<h1><h2><h3>...
  • 默认样式
    • display: block;
    • 不同的标题标签有不同的默认字体大小(例如,h1 最大,h6 最小)。
    • 上下外边距通常较大。
<p>
  • 默认样式
    • display: block;
    • 上下外边距(margin)通常有默认值(如 margin-top 和 margin-bottom)。
<ul><ol><li>
  • 默认样式
    • display: block;(对于 ul 和 ol
    • display: list-item;(对于 li
    • 默认有内边距(padding)和外边距。

2. 行内元素

<span>
  • 默认样式
    • display: inline;
    • 不产生换行。
<a>
  • 默认样式
    • display: inline;
    • 默认有下划线(text-decoration: underline;)。
    • 默认颜色通常为蓝色。
<strong><em>
  • 默认样式
    • strong:通常加粗文本(font-weight: bold;)。
    • em:通常斜体文本(font-style: italic;)。

3. 表格元素

<table>
  • 默认样式
    • display: table;
    • 默认没有边框。
    • 单元格的边距和内边距通常为 0。
<tr><td><th>
  • 默认样式
    • trdisplay: table-row;
    • tddisplay: table-cell;
    • thdisplay: table-cell;,通常加粗且居中。
    • 默认的单元格内边距(padding)。

4. 表单元素

<input><textarea>
  • 默认样式
    • display: inline-block;(对于 input
    • display: block;(对于 textarea
    • 默认的边框和内边距。
<button>
  • 默认样式
    • display: inline-block;
    • 默认的背景色、边框、内边距等。

15.HTML 标签在不同浏览器中的差异

1. 标题标签(<h1><h6>

  • 差异点
    • 各个浏览器对标题标签的默认字体大小和行高略有不同,尤其是标题的上下 外边距(margin)
    • 某些浏览器可能会对 <h1><h6> 的默认 字体加粗程度 有轻微不同。

2. 段落标签(<p>

  • 差异点
    • 不同浏览器可能会为段落标签添加不同大小的 上下外边距(margin)
    • 字体的 行高(line-height) 可能略有不同。

3. 列表标签(<ul><ol><li>

  • 差异点
    • 列表符号列表项的缩进 可能在不同浏览器中有所不同。例如:
      • Chrome 和 Firefox 对无序列表(<ul>)的项目符号可能会有所区别,符号的形状和位置稍有不同。
      • 有序列表(<ol>)的编号和项目符号的对齐方式可能略有差异。
    • 内边距(padding)外边距(margin) 也可能有差异。

4. 链接标签(<a>

  • 差异点
    • 链接颜色下划线的显示 在不同浏览器中表现略有不同。某些浏览器会将链接颜色设置为较深或较浅的蓝色,而一些浏览器可能在 悬停状态:hover)下去掉下划线。
    • 已访问过的链接颜色(:visited)也可能在不同浏览器中呈现不同的默认值。

5. 图像标签(<img>

  • 差异点
    • 图像的 内边距(padding)外边距(margin) 可能在不同浏览器中有所差异。比如,有些浏览器可能会在图像周围添加少量的默认边距,而另一些不会。
    • 某些浏览器可能对 响应式布局 中的图像处理方式有所不同,尤其是当你没有明确设置图像的宽度或高度时。

6. 表格标签(<table><tr><td><th>

  • 差异点
    • 不同浏览器对表格的默认 边框(border) 处理方式不同。比如,有些浏览器会默认隐藏表格的边框,而有些可能会显示细线边框。
    • 表格单元格的 内边距(padding)外边距(margin) 可能会有所不同,尤其是在没有显式设置时。
    • 表格标题单元格(<th> 的默认对齐方式和加粗可能会有差异,尽管大多数浏览器默认会将标题居中并加粗。

7. 表单元素(<input><button><select> 等)

  • 差异点
    • 表单控件(如文本输入框、按钮、选择框等)的 外观 是浏览器之间差异最大的部分。每个浏览器对表单元素的样式(尤其是按钮、单选框、复选框、下拉框等)的渲染会有很大差异。
      • 例如,按钮的样式在 Chrome、Firefox、Safari 和 IE 中都不同,有些浏览器会使用系统默认按钮样式。
      • 占位符文本 的样式在浏览器中差异较大,Chrome 和 Safari 中的占位符默认是灰色,而 Firefox 中则可能更暗。
    • 单选按钮复选框 的大小和形状也有明显差异。

8. 块级与行内元素

  • 差异点
    • 在块级和行内元素的 内边距外边距 上,不同浏览器有时会有微小的处理差异。比如,<div><span> 在某些浏览器中可能会被应用不同的上下外边距。

9. 浏览器差异的典型例子

  • IE/Edge:老版本的 IE 对默认样式的处理经常与现代浏览器有较大不同。IE 可能会对某些元素应用更多的内边距和外边距,甚至在处理 盒模型(box model)上会有兼容性问题。
  • Firefox:在某些表单元素和按钮的渲染上,Firefox 可能会显得更“素”,不像 Chrome 或 Safari 那样有系统自带的样式效果。
  • Safari:Safari 对按钮和表单控件的默认样式通常比较有“苹果风”,即表现出较多的圆角和渐变效果。

10. 解决浏览器样式差异的方式

为了避免不同浏览器默认样式带来的差异,通常可以采取以下措施:

  1. CSS 重置(Reset CSS):通过重置所有标签的默认样式,确保跨浏览器的一致性。

    • 如 Eric Meyer 的 Reset CSS:
      * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
      }
      
  2. 标准化样式(Normalize CSS):保留有用的默认样式,但消除浏览器之间不必要的差异。

    • normalize.css 这一工具可以让不同浏览器中显示尽可能一致:
      html {
          line-height: 1.15; /* 1 */
          -webkit-text-size-adjust: 100%; /* 2 */
      }
      
  3. 自定义样式:为每一个需要的元素应用明确的样式定义,确保其在所有浏览器中的一致表现。

16.webkit

常见的 -webkit- 样式属性

  1. -webkit-transition

    • 用于定义元素的过渡效果。
    • 示例:
    .box {
        transition: all 0.5s;
        -webkit-transition: all 0.5s; /* Safari 和旧版 Chrome */
    }
    
  2. -webkit-transform

    • 用于应用2D或3D转换。
    • 示例:
    .box {
        transform: rotate(45deg);
        -webkit-transform: rotate(45deg); /* Safari 和旧版 Chrome */
    }
    
  3. -webkit-border-radius

    • 用于定义元素的圆角边框。
    • 示例:
    .box {
        border-radius: 10px;
        -webkit-border-radius: 10px; /* Safari 和旧版 Chrome */
    }
    
  4. -webkit-box-shadow

    • 用于添加阴影效果。
    • 示例:
    .box {
        box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.5);
        -webkit-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.5); /* Safari 和旧版 Chrome */
    }
    
  5. -webkit-animation

    • 用于定义动画效果。
    • 示例:
    @keyframes example {
        from { opacity: 0; }
        to { opacity: 1; }
    }
    
    .fade-in {
        animation: example 2s;
        -webkit-animation: example 2s; /* Safari 和旧版 Chrome */
    }
    

使用前缀的注意事项

  • 兼容性:由于浏览器的不断更新,许多早期需要前缀的属性现在在主流浏览器中已经得到了良好的支持。因此,通常建议使用无前缀的标准属性,除非你需要支持较旧的浏览器。

  • 渐进增强:对于需要使用前缀的属性,可以优先使用无前缀的属性,然后再使用带前缀的属性作为后备方案。

示例代码

以下是一个示例,展示了如何使用 -webkit- 前缀与标准属性一起应用样式。

.box {
    width: 100px;
    height: 100px;
    background-color: blue;
    border-radius: 10px; /* 标准属性 */
    -webkit-border-radius: 10px; /* Safari 和旧版 Chrome */
    transition: all 0.5s; /* 标准属性 */
    -webkit-transition: all 0.5s; /* Safari 和旧版 Chrome */
}

.box:hover {
    background-color: red;
    transform: scale(1.2); /* 标准属性 */
    -webkit-transform: scale(1.2); /* Safari 和旧版 Chrome */
}

17.处理浏览器兼容问题的方式

1. CSS 重置或标准化

不同浏览器对 HTML 元素的默认样式存在差异,使用 CSS 重置或标准化样式可以确保所有浏览器呈现一致的样式。

  • Reset CSS:重置浏览器的所有默认样式,将元素的样式初始化为统一的基准值。

    • 例如 Eric Meyer’s Reset CSS。
    • 示例:
      * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
      }
      
  • Normalize CSS:保留有用的默认样式,但消除浏览器之间不必要的差异。

    • 例如 Normalize.css。
    • 示例:
      html {
          line-height: 1.15;
          -webkit-text-size-adjust: 100%;
      }
      

2. 使用 CSS 前缀

由于 CSS 新特性在不同浏览器的实现时间不同,某些 CSS 属性需要添加 厂商前缀 才能在某些浏览器中正常工作。

  • 常见前缀

    • -webkit-:适用于 Chrome、Safari、iOS 浏览器等。
    • -moz-:适用于 Firefox。
    • -o-:适用于早期版本的 Opera。
    • -ms-:适用于 Internet Explorer 和 Edge。
  • 示例

    .example {
        -webkit-border-radius: 10px;
        -moz-border-radius: 10px;
        border-radius: 10px;
    }
    
  • 自动化工具:可以使用工具如 Autoprefixer,它可以自动为 CSS 添加合适的前缀。

3. JavaScript Polyfill 和 Shim

新版本的 JavaScript 特性在某些旧浏览器中不支持,可以通过 polyfillshim 来提供支持。

  • Polyfill:为旧浏览器提供对新功能的模拟实现。
    • 例如使用 Babel Polyfill 来支持 ES6+ 语法和功能。
  • Shim:通过修改浏览器原生 API 或使用旧的浏览器功能模拟新的 API。
    • 例如,Object.assign() 在早期浏览器不支持

4. 检测和处理浏览器特性

使用 特性检测 而不是依赖浏览器版本判断来决定功能的可用性,可以更好地处理兼容性问题。

  • Modernizr:一个库,用于检测浏览器是否支持某些 HTML5 和 CSS3 特性。

5. 条件注释(仅适用于 IE)

Internet Explorer 6-9 支持 条件注释,可以用于加载特定版本的 IE 的样式或脚本。

  • 但这种方式主要用于支持旧版本 IE,现在不建议使用,而是推荐通过现代化工具处理 IE 的兼容性问题。

6. CSS Fallback(后备方案)

为不支持新 CSS 属性的浏览器提供后备方案。通常是先写旧的属性,再写新的特性,这样新浏览器可以使用新特性,而旧浏览器会使用旧的。

7. Graceful Degradation(优雅降级)和 Progressive Enhancement(渐进增强)

  • 优雅降级:即首先设计复杂的功能,然后为不支持这些功能的旧浏览器提供一个简单但可用的版本。
  • 渐进增强:即首先设计一个适用于所有浏览器的基本功能,然后为现代浏览器添加更多的高级功能和样式。

8. 跨浏览器测试

在开发过程中,确保在多个浏览器中进行测试非常重要。可以使用一些跨浏览器测试工具:

  • 浏览器开发工具:每个浏览器都提供了开发者工具,方便调试兼容性问题。
  • 跨浏览器测试平台:如 BrowserStackSauce Labs 允许开发者在虚拟环境中测试各种浏览器和设备。

9. 使用 Babel 转译 JavaScript

Babel 是一个 JavaScript 编译器,可以将 ES6+ 语法转换为 ES5,以便旧版本浏览器可以运行。

10. 使用 Polyfills.io

Polyfill.io 是一个按需加载 polyfill 的服务,自动为需要的浏览器提供所需的 polyfill,而无需加载所有 polyfill 文件。

嗨!很高兴回答你关于Python的NumPy库的问题。NumPy是一个强大的科学计算库,提供了高性能的数组对象和各种功能丰富的数学函数。 首先,你可以使用以下命令安装NumPy库: ```python pip install numpy ``` 一旦安装完成,你可以在Python脚本中导入NumPy库: ```python import numpy as np ``` 现在让我们来看一些NumPy的常用功能。 1. 创建NumPy数组: - 使用`np.array()`函数从Python列表或元组创建数组。 - 使用`np.zeros()`创建一个元素全为0的数组。 - 使用`np.ones()`创建一个元素全为1的数组。 - 使用`np.random`模块生成随机数组。 2. 数组操作: - 通过索引访问和修改数组的元素。 - 使用切片操作提取子数组。 - 使用数组的形状、大小和维度等属性。 3. 数学函数: - NumPy提供了丰富的数学函数,例如平方根(`np.sqrt()`)、指数函数(`np.exp()`)、对数函数(`np.log()`)等。 - 通过在数组上应用这些函数,可以进行元素级别的数学操作。 4. 数组运算: - NumPy支持基本的数组运算,如加法、减法、乘法和除法。 - 这些运算可以在两个数组之间进行,也可以在数组和标量之间进行。 5. 线性代数: - NumPy提供了许多线性代数操作的函数,如矩阵乘法(`np.dot()`)、矩阵求逆(`np.linalg.inv()`)、特征值和特征向量(`np.linalg.eig()`)等。 这只是NumPy库的一小部分功能,但对于进行科学计算和数据分析来说非常重要。你可以参考NumPy官方文档以了解更多详细信息:https://numpy.org/doc/ 希望这些信息能帮助你开始学习NumPy库!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

真的不想学习啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值