28:js字符串操作方法大全?包含ES6方法?
答:
JavaScript字符串操作方法大全:
- charAt():返回指定位置的字符。
- charCodeAt():返回指定位置字符的Unicode编码。
- concat():连接两个或多个字符串。
- indexOf():返回字符串中指定文本首次出现的位置。
- lastIndexOf():返回字符串中指定文本最后一次出现的位置。
- match():查找一个或多个正则表达式的匹配。
- replace():替换与正则表达式匹配的子串。
- search():查找与正则表达式匹配的子串。
- slice():提取字符串的片断,并在新的字符串中返回被提取的部分。
- split():把字符串分割为字符串数组。
- substr():从起始索引号提取字符串中指定数目的字符。
- substring():提取字符串中两个指定的索引号之间的字符。
- toLowerCase():把字符串转换为小写。
- toUpperCase():把字符串转换为大写。
- trim():去除字符串两端的空白字符。
16:字符串长度
17:字符串连接
18:字符串截取
19:字符串查找
20:字符串替换
21:字符串大小写转换
22:字符串分割
23:字符串去除空格
24:字符串转数组
25:字符串反转
26:字符串比较
27:字符串转义
28:字符串转数字
29:数字转字符串
30:字符串包含
31:字符串重复
32:字符串填充
33:字符串模板
34:字符串匹配
35:字符串搜索
36:字符串获取指定位置字符
37:字符串比较
38:字符串去重
1. charAt()返回指定位置的字符
// 1. charAt()
let str = "Hello World!";
console.log(str.charAt(0)); // H
2. charCodeAt()返回指定位置字符的Unicode编码
// 2. charCodeAt()
let str = "Hello World!";
console.log(str.charCodeAt(0)); // 72
3. concat()连接两个或多个字符串
// 3. concat()
let str1 = "Hello";
let str2 = "World";
console.log(str1.concat(" ", str2)); // Hello World
4. indexOf():返回字符串中指定文本首次出现的位置。
// 4. indexOf()
let str = "Hello World!";
console.log(str.indexOf("o")); // 4
5. lastIndexOf():返回字符串中指定文本最后一次出现的位置。
// 5. lastIndexOf()
let str = "Hello World!";
console.log(str.lastIndexOf("o")); // 7
6. match():查找一个或多个正则表达式的匹配。
// 6. match()
let str = "Hello World!";
console.log(str.match(/o/g)); // [ 'o', 'o' ]
7. replace():替换与正则表达式匹配的子串。
// 7. replace()
let str = "Hello World!";
console.log(str.replace("World", "JavaScript")); // Hello JavaScript!
8. search():查找与正则表达式匹配的子串。
// 8. search()
let str = "Hello World!";
console.log(str.search(/World/)); // 6
9. slice():提取字符串的片断,并在新的字符串中返回被提取的部分。
// 9. slice()
let str = "Hello World!";
console.log(str.slice(0, 5)); // Hello
10. split():把字符串分割为字符串数组。
// 10. split()
let str = "Hello World!";
console.log(str.split(" ")); // [ 'Hello', 'World!' ]
11. substr():从起始索引号提取字符串中指定数目的字符。
// 11. substr()
let str = "Hello World!";
console.log(str.substr(6, 6)); // World!
12. substring():提取字符串中两个指定的索引号之间的字符。
// 12. substring()
let str = "Hello World!";
console.log(str.substring(6, 11)); // World
13. toLowerCase():把字符串转换为小写。
// 13. toLowerCase()
let str = "Hello World!";
console.log(str.toLowerCase()); // hello world!
14. toUpperCase():把字符串转换为大写。
// 14. toUpperCase()
let str = "Hello World!";
console.log(str.toUpperCase()); // HELLO WORLD!
15. trim():去除字符串两端的空白字符。
// 15. trim()
let str3 = " Hello World! ";
console.log(str3.trim()); // Hello World!
16:字符串长度
// 字符串长度
var str = "Hello World!";
console.log(str.length); // 12
17:字符串连接
// 字符串连接
var str1 = "Hello";
var str2 = "World!";
console.log(str1.concat(str2)); // HelloWorld!
18:字符串截取
// 字符串截取
var str3 = "Hello World!";
console.log(str3.slice(0, 5)); // Hello
console.log(str3.substring(0, 5)); // Hello
console.log(str3.substr(0, 5)); // Hello
19:字符串查找
// 字符串查找
var str4 = "Hello World!";
console.log(str4.indexOf("World")); // 6
console.log(str4.lastIndexOf("l")); // 9
20:字符串替换
// 字符串替换
var str5 = "Hello World!";
console.log(str5.replace("World", "JavaScript")); // Hello JavaScript!
21:字符串大小写转换
// 字符串大小写转换
var str6 = "Hello World!";
console.log(str6.toUpperCase()); // HELLO WORLD!
console.log(str6.toLowerCase()); // hello world!
22:字符串分割
// 字符串分割
var str7 = "Hello,World!";
console.log(str7.split(",")); // ["Hello", "World!"]
21: 字符串去除空格
// 字符串去除空格
var str8 = " Hello World! ";
console.log(str8.trim()); // Hello World!
22: 字符串转数组
// 字符串转数组
var str9 = "Hello World!";
console.log(Array.from(str9)); // ["H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d", "!"]
23: 字符串反转
// 字符串反转
var str10 = "Hello World!";
console.log(str10.split("").reverse().join("")); // !dlroW olleH
24: 字符串比较
// 字符串比较
var str11 = "Hello World!";
var str12 = "hello world!";
console.log(str11.localeCompare(str12)); // 1
console.log(str11.localeCompare(str11)); // 0
console.log(str12.localeCompare(str11)); // -1
25: 字符串转义
// 字符串转义
var str13 = "Hello "World"!";
console.log(str13); // Hello "World"!
26: 字符串转数字
// 字符串转数字
var str14 = "123";
console.log(Number(str14)); // 123
console.log(parseInt(str14)); // 123
console.log(parseFloat(str14)); // 123
27: 数字转字符串
// 数字转字符串
var num = 123;
console.log(num.toString()); // "123"
console.log(String(num)); // "123"
28: 字符串包含
// 字符串包含
var str15 = "Hello World!";
console.log(str15.includes("World")); // true
console.log(str15.includes("JavaScript")); // false
29: 字符串重复
// 字符串重复
var str16 = "Hello";
console.log(str16.repeat(3)); // HelloHelloHello
30: 字符串填充
// 字符串填充
var str17 = "Hello";
console.log(str17.padStart(10, "123")); // 123123Hello
console.log(str17.padEnd(10, "123")); // Hello123123
31: 字符串模板
// 字符串模板
var name = "Tom";
var age = 18;
var str18 = `My name is ${name}, I am ${age} years old.`;
console.log(str18); // My name is Tom, I am 18 years old.
32: 字符串匹配
// 字符串匹配
var str20 = "Hello World!";
console.log(str20.match(/o/g)); // ["o", "o"]
33: 字符串搜索
// 字符串搜索
var str21 = "Hello World!";
console.log(str21.search(/o/)); // 4
34: 字符串获取指定位置字符
// 字符串获取指定位置字符
var str22 = "Hello World!";
console.log(str22.charAt(0)); // H
console.log(str22.charAt(6)); // W
35: 字符串比较
// 字符串比较
var str24 = "Hello World!";
var str25 = "hello world!";
console.log(str24 == str25); // false
console.log(str24.toUpperCase() == str25.toUpperCase()); // true
36: 字符串去重
// 字符串去重
var str33 = "Hello World!";
console.log([...new Set(str33)].join("")); // Helo Wrd!
28.1:ES6新增的字符串操作方法:
- startsWith():判断字符串是否以指定的字符开头。
- endsWith():判断字符串是否以指定的字符结尾。
- includes():判断字符串是否包含指定的字符。
- repeat():重复指定次数的字符串。
- padStart():在字符串的开头填充指定的字符,使字符串达到指定的长度。
- padEnd():在字符串的结尾填充指定的字符,使字符串达到指定的长度。
- trimStart():去除字符串开头的空白字符。
- trimEnd():去除字符串结尾的空白字符。
1. startsWith():判断字符串是否以指定的字符开头。
// 1. startsWith()
const str1 = 'Hello World';
console.log(str1.startsWith('Hello')); // true
console.log(str1.startsWith('World')); // false
2. endsWith():判断字符串是否以指定的字符结尾。
// 2. endsWith()
const str2 = 'Hello World';
console.log(str2.endsWith('Hello')); // false
console.log(str2.endsWith('World')); // true
3. includes():判断字符串是否包含指定的字符。
// 3. includes()
const str3 = 'Hello World';
console.log(str3.includes('Hello')); // true
console.log(str3.includes('JavaScript')); // false
4. repeat():重复指定次数的字符串。
// 4. repeat()
const str4 = 'Hello';
console.log(str4.repeat(3)); // 'HelloHelloHello'
5. padStart():在字符串的开头填充指定的字符,使字符串达到指定的长度。
// 5. padStart()
const str5 = 'Hello';
console.log(str5.padStart(10, '0')); // '00000Hello'
6. padEnd():在字符串的结尾填充指定的字符,使字符串达到指定的长度。
// 6. padEnd()
const str6 = 'Hello';
console.log(str6.padEnd(10, '0')); // 'Hello00000'
7. trimStart():去除字符串开头的空白字符。
// 7. trimStart()
const str7 = ' Hello World ';
console.log(str7.trimStart()); // 'Hello World '
8. trimEnd():去除字符串结尾的空白字符。
// 8. trimEnd()
const str8 = ' Hello World ';
console.log(str8.trimEnd()); // ' Hello World'
// 字符串常用方法
let str = 'hello world';
console.log(str.length); // 11
console.log(str.charAt(0)); // h
console.log(str.charCodeAt(0)); // 104
console.log(str.concat('!', '!', '!')); // hello world!!!
console.log(str.indexOf('o')); // 4
console.log(str.lastIndexOf('o')); // 7
console.log(str.slice(3, 7)); // lo w
console.log(str.substring(3, 7)); // lo w
console.log(str.substr(3, 7)); // lo worl
console.log(str.replace('world', 'javascript')); // hello javascript
console.log(str.toUpperCase()); // HELLO WORLD
console.log(str.toLowerCase()); // hello world
console.log(str.split(' ')); // ['hello', 'world']
// ES6新增方法
let str2 = 'hello world';
console.log(str2.startsWith('hello')); // true
console.log(str2.endsWith('world')); // true
console.log(str2.includes('o')); // true
console.log(str2.repeat(3)); // hello worldhello worldhello world
console.log(str2.padStart(20, 'x')); // xxxxxxxxhello world
console.log(str2.padEnd(20, 'x')); // hello worldxxxxxxxx
29:JS中的Array.splice()和Array.slice()方法有什么区别?
答:
Array.splice() 方法会修改原数组,它可以从数组中添加或删除元素,并返回被删除的元素。
而 Array.slice() 方法不会修改原数组,它会返回一个新的数组,包含从开始到结束(不包括结束)选择的数组中的元素。
Array.splice() 示例
// Array.splice() 示例
const fruits = ['apple', 'banana', 'orange'];
fruits.splice(1, 1, 'grape', 'peach');
console.log(fruits); // ['apple', 'grape', 'peach', 'orange']
Array.slice() 示例
// Array.slice() 示例
const animals = ['cat', 'dog', 'elephant', 'lion'];
const slicedAnimals = animals.slice(1, 3);
console.log(slicedAnimals); // ['dog', 'elephant']
console.log(animals); // ['cat', 'dog', 'elephant', 'lion']
30:ES6普通函数和箭头函数的区别?什么是箭头函数?
答:
ES6普通函数和箭头函数的区别?
ES6普通函数和箭头函数的区别在于箭头函数没有自己的this,它的this是继承自外层作用域的this。箭头函数的语法更加简洁,可以省略function关键字和return关键字。箭头函数适用于一些简单的函数,而普通函数则适用于复杂的函数。
ES6普通函数和箭头函数
ES6普通函数和箭头函数的区别在于箭头函数没有自己的this,它的this是继承自外层作用域的this。箭头函数的语法更加简洁,可以省略function关键字和return关键字。箭头函数适用于一些简单的函数,而普通函数则适用于复杂的函数。
什么是箭头函数?
箭头函数是一种ES6语法中的函数,它没有自己的this,而是继承自外层作用域的this。箭头函数的语法更加简洁,可以省略function关键字和return关键字。箭头函数适用于一些简单的函数,而普通函数则适用于复杂的函数
ES6普通函数
// ES6普通函数
function regularFunction(a, b) {
return a + b;
}
ES6箭头函数
// ES6箭头函数
const arrowFunction = (a, b) => a + b;
箭头函数的this指向外层作用域的this
// 箭头函数的this指向外层作用域的this
const obj = {
name: 'Alice',
sayName: function() {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
obj.sayName(); // 输出:Alice
31: js 有哪些内置对象?JS中有哪些内置函数?
答:
JS中有很多内置对象,包括但不限于:
1:Object 对象
2:Array 数组
3:String 字符串
4:Number 数字
5:Boolean 布尔值
6:Date 日期
7:RegExp 正则表达式
8:Math 数学函数
9:JSON 用于将 JavaScript 对象转换为字符串,以便于存储或传输。
- Object 对象
const person = {
name: 'John',
age: 30,
hobbies: ['reading', 'traveling'],
address: {
street: '123 Main St',
city: 'New York',
state: 'NY'
}
};
- Array 数组
const numbers = [1, 2, 3, 4, 5];
const fruits = ['apple', 'banana', 'orange'];
- String 字符串
const greeting = 'Hello World';
- Number 数字
const age = 30;
- Boolean 布尔值
const isStudent = true;
- Date 日期
const today = new Date();
- RegExp 正则表达式
const pattern = /[a-z]+/;
- Math 数学函数
const result = Math.pow(2, 3);
- JSON
const personJSON = '{"name":"John","age":30,"hobbies":["reading","traveling"],"address":{"street":"123 Main St","city":"New York","state":"NY"}}';
const personObj = JSON.parse(personJSON);
JS中还有其他内置对象,如:
1: Map:Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
2: Set:Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
3: WeakMap:WeakMap 对象是一组键/值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的。
4: WeakSet:WeakSet 对象允许你将弱引用对象存储在一个集合中。
5: Promise:Promise 对象用于表示一个异步操作的最终完成 (或失败),及其结果值。
6: Proxy:Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。
7: Reflect:Reflect 对象提供了一些能够对任意对象进行操作的方法,而这些方法与 Proxy 处理程序的方法相同。
8: Symbol:Symbol 对象是 ES6 引入的一种新的原始数据类型,表示独一无二的值。
9: ArrayBuffer:ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。
10: DataView:DataView 对象提供了一个 API,用于读写 ArrayBuffer 对象中的二进制数据。
11: SharedArrayBuffer:SharedArrayBuffer 对象用来表示一个通用的、固定长度的原始二进制数据缓冲区,类似于 ArrayBuffer 对象,但它可以被多个进程共享。
12: Atomics:Atomics 对象提供了一组静态方法,用于对 SharedArrayBuffer 对象进行原子操作。
13: Intl:Intl 对象提供了一组 API,用于支持不同地区和语言的国际化。
14: WebAssembly:WebAssembly 是一种新型的低级编程语言,可以在现代 Web 浏览器中运行。
1: Map Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值
// Map Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值
const map = new Map();
map.set('key1', 'value1');
map.set('key2', 'value2');
console.log(map.get('key1')); // output: "value1"
2: Set Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用
// Set
const set = new Set();
set.add('value1');
set.add('value2');
console.log(set.has('value1')); // output: "true"
3: WeakMap WeakMap 对象是一组键/值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的
// WeakMap
const weakMap = new WeakMap();
const obj = {};
weakMap.set(obj, 'value');
console.log(weakMap.get(obj)); // output: "value"
4: WeakSet WeakSet 对象允许你将弱引用对象存储在一个集合中。
// WeakSet=
const weakSet = new WeakSet();
const obj = {};
weakSet.add(obj);
console.log(weakSet.has(obj)); // output: "true"
5: Promise Promise 对象用于表示一个异步操作的最终完成 (或失败),及其结果值
// Promise
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('resolved');
}, 1000);
});
promise.then((value) => {
console.log(value); // output: "resolved"
});
6: Proxy Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)
// Proxy
const target = {};
const handler = {
get: function(target, prop) {
return prop in target ? target[prop] : 'default';
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.foo); // output: "default"
7: Reflect Reflect 对象提供了一些能够对任意对象进行操作的方法,而这些方法与 Proxy 处理程序的方法相同
// Reflect
const obj = { foo: 'bar' };
Reflect.set(obj, 'foo', 'baz');
console.log(obj.foo); // output: "baz"
8: Symbol Symbol 对象是 ES6 引入的一种新的原始数据类型,表示独一无二的值。
// Symbol
const sym = Symbol('mySymbol');
console.log(sym); // output: "Symbol(mySymbol)"
9: ArrayBuffer ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区
// ArrayBuffer
const buffer = new ArrayBuffer(8);
console.log(buffer.byteLength); // output: "8"
10: DataView DataView 对象提供了一个 API,用于读写 ArrayBuffer 对象中的二进制数据
// DataView
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setInt8(0, 1);
console.log(view.getInt8(0)); // output: "1"
11: SharedArrayBuffer SharedArrayBuffer 对象用来表示一个通用的、固定长度的原始二进制数据缓冲区,类似于 ArrayBuffer 对象,但它可以被多个进程共享
// SharedArrayBuffer
const sharedBuffer = new SharedArrayBuffer(8);
console.log(sharedBuffer.byteLength); // output: "8"
12: Atomics Atomics 对象提供了一组静态方法,用于对 SharedArrayBuffer 对象进行原子操作
// Atomics
const buffer = new SharedArrayBuffer(8);
const arr = new Int32Array(buffer);
arr[0] = 1;
Atomics.add(arr, 0, 2);
console.log(arr[0]); // output: "3"
13: Intl Intl 对象提供了一组 API,用于支持不同地区和语言的国际化
// Intl
const date = new Date();
const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
console.log(new Intl.DateTimeFormat('en-US', options).format(date)); // output: "Thursday, September 2, 2021"
14: WebAssembly WebAssembly 是一种新型的低级编程语言,可以在现代 Web 浏览器中运行
// WebAssembly
const buffer = new ArrayBuffer(16);
const uint8 = new Uint8Array(buffer);
uint8.set([0x61, 0x73, 0x6d, 0x01]);
const module = new WebAssembly.Module(buffer);
console.log(module instanceof WebAssembly.Module); // output: "true"
31.1 JS中也有很多内置函数,包括但不限于:
1:parseInt():将字符串转换为整数。
2:parseFloat():将字符串转换为浮点数。
3:isNaN():检查一个值是否是NaN。
4:isFinite():检查一个值是否是有限数。
5:encodeURI():对URI进行编码。
6:decodeURI():对URI进行解码。
7:encodeURIComponent():对URI组件进行编码。
8:decodeURIComponent():对URI组件进行解码。
9:eval():将字符串作为代码来执行。
10:alert():在浏览器中显示一个警告框。
11:prompt():在浏览器中显示一个提示框,提示用户输入文本。
12:confirm():在浏览器中显示一个确认框,提示用户确认或取消。
13:setTimeout():在指定的时间后执行一次函数。
14:setInterval():每隔指定的时间执行一次函数。
1:parseInt():将字符串转换为整数
// parseInt() 代码示例
let num1 = parseInt("123");
let num2 = parseInt("123.45");
let num3 = parseInt("hello");
console.log(num1); // 123
console.log(num2); // 123
console.log(num3); // NaN
2:parseFloat():将字符串转换为浮点数。
// parseFloat() 代码示例
let num4 = parseFloat("123");
let num5 = parseFloat("123.45");
let num6 = parseFloat("hello");
console.log(num4); // 123
console.log(num5); // 123.45
console.log(num6); // NaN
3:isNaN():检查一个值是否是NaN。
// isNaN() 代码示例
console.log(isNaN(123)); // false
console.log(isNaN("hello")); // true
4:isFinite():检查一个值是否是有限数。
// isFinite() 代码示例
console.log(isFinite(123)); // true
console.log(isFinite(Infinity)); // false
5:encodeURI():对URI进行编码。
// encodeURI() 代码示例
let url1 = "https://www.example.com/?name=张三&age=18";
let encodedUrl1 = encodeURI(url1);
console.log(encodedUrl1); // https://www.example.com/?name=%E5%BC%A0%E4%B8%89&age=18
6:decodeURI():对URI进行解码。
// decodeURI() 代码示例
let encodedUrl2 = "https://www.example.com/?name=%E5%BC%A0%E4%B8%89&age=18";
let url2 = decodeURI(encodedUrl2);
console.log(url2); // https://www.example.com/?name=张三&age=18
7:encodeURIComponent():对URI组件进行编码。
// encodeURIComponent() 代码示例
let url3 = "https://www.example.com/?name=张三&age=18";
let encodedUrl3 = encodeURIComponent(url3);
console.log(encodedUrl3); // https%3A%2F%2Fwww.example.com%2F%3Fname%3D%E5%BC%A0%E4%B8%89%26age%3D18
8:decodeURIComponent():对URI组件进行解码。
// decodeURIComponent() 代码示例
let encodedUrl4 = "https%3A%2F%2Fwww.example.com%2F%3Fname%3D%E5%BC%A0%E4%B8%89%26age%3D18";
let url4 = decodeURIComponent(encodedUrl4);
console.log(url4); // https://www.example.com/?name=张三&age=18
9:eval():将字符串作为代码来执行。
// eval() 代码示例
let x = 10;
let y = 20;
let result = eval("x + y");
console.log(result); // 30
10:alert():在浏览器中显示一个警告框。
// alert() 代码示例
alert("Hello World!");
11:prompt():在浏览器中显示一个提示框,提示用户输入文本。
// prompt() 代码示例
let name = prompt("What is your name?");
console.log(name);
12:confirm():在浏览器中显示一个确认框,提示用户确认或取消。
// confirm() 代码示例
let result = confirm("Are you sure you want to delete this file?");
console.log(result);
13:setTimeout():在指定的时间后执行一次函数。
// setTimeout() 代码示例
setTimeout(function() {
console.log("Hello World!");
}, 3000);
14:setInterval():每隔指定的时间执行一次函数。
// setInterval() 代码示例
let count = 0;
let intervalId = setInterval(function() {
count++;
console.log(count);
if (count === 10) {
clearInterval(intervalId);
}
}, 1000);
JS中还有其他内置函数,如:
1: console.log():输出信息到控制台
2: console.warn():输出警告信息到控制台
3: console.error():输出错误信息到控制台
4: console.info():输出信息到控制台
5: console.table():以表格形式输出信息到控制台
6: console.time():计时器开始计时
7: console.timeEnd():计时器结束计时
8: console.group():将输出信息分组
9: console.groupEnd():结束输出信息分组
10: console.clear():清空控制台
11: Object.keys():返回对象的键名数组
12: Object.values():返回对象的键值数组
13: Object.entries():返回对象的键值对数组
14: Array.isArray():判断是否为数组
15: Array.from():将类数组对象转换为数组
16: Array.of():创建一个包含任意数量参数的数组
17: String.fromCharCode():将 Unicode 编码转为字符。
18: String.prototype.charAt():返回指定位置的字符。
19: String.prototype.concat():连接两个或多个字符串。
20: String.prototype.indexOf():返回字符串中指定文本首次出现的位置。
21: String.prototype.lastIndexOf():返回字符串中指定文本最后一次出现的位置。
22: String.prototype.slice():提取字符串的一部分,并返回一个新字符串。
23: String.prototype.split():把字符串分割为字符串数组。
24: String.prototype.toLowerCase():把字符串转换为小写。
25: String.prototype.toUpperCase():把字符串转换为大写。
26: Number.isNaN():确定传递的值是否为 NaN。
27: Number.isInteger():确定传递的值是否为整数。
28: Number.parseFloat():解析一个字符串并返回一个浮点数。
29: Number.parseInt():解析一个字符串并返回一个整数。
30: Math.abs():返回一个数的绝对值。
31: Math.ceil():返回一个数向上取整的值。
32: Math.floor():返回一个数向下取整的值。
33: Math.max():返回一组数中的最大值。
34: Math.min():返回一组数中的最小值。
35: Math.pow():返回一个数的指定次幂。
36: Math.random():返回一个介于0和1之间的随机数。
37: Date.now():返回当前时间的毫秒数。
38: Date.parse():将一个日期字符串转换为毫秒数。
39: Date.UTC():返回一个UTC时间的毫秒数。
40: RegExp.prototype.exec():在字符串中执行一个正则表达式匹配,并返回匹配结果。
41: RegExp.prototype.test():在字符串中测试一个正则表达式匹配,并返回布尔值。
42: JSON.parse():将一个JSON字符串转换为JavaScript对象。
43: JSON.stringify():将一个JavaScript对象转换为JSON字符串。
1: console.log():输出信息到控制台
// console.log()
console.log('Hello, world!');
2: console.warn():输出警告信息到控制台
// console.warn()
console.warn('This is a warning message.');
3: console.error():输出错误信息到控制台
// console.error()
console.error('This is an error message.');
4: console.info():输出信息到控制台
// console.info()
console.info('This is an informational message.');
5: console.table():以表格形式输出信息到控制台
// console.table()
console.table(['apple', 'banana', 'orange']);
6: console.time():计时器开始计时
console.time();
// some code to be timed
console.timeEnd();
7: console.timeEnd():计时器结束计时
console.timeEnd();
8: console.group():将输出信息分组
// console.group()
console.group('Group 1');
console.log('Message 1');
console.log('Message 2');
9: console.groupEnd():结束输出信息分组
console.groupEnd();
10: console.clear():清空控制台
// console.clear()
console.clear();
11: Object.keys():返回对象的键名数组
// Object.keys()
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.keys(obj));
12: Object.values():返回对象的键值数组
// Object.values()
console.log(Object.values(obj));
13: Object.entries():返回对象的键值对数组
// Object.entries()
console.log(Object.entries(obj));
14: Array.isArray():判断是否为数组
// Array.isArray()
console.log(Array.isArray([1, 2, 3]));
15: Array.from():将类数组对象转换为数组
// Array.from()
console.log(Array.from('hello'));
16: Array.of():创建一个包含任意数量参数的数组
// Array.of()
console.log(Array.of(1, 2, 3));
17: String.fromCharCode():将 Unicode 编码转为字符。
// String.fromCharCode()
console.log(String.fromCharCode(65, 66, 67));
18: String.prototype.charAt():返回指定位置的字符。
// String.prototype.charAt()
const str = 'hello';
console.log(str.charAt(0));
19: String.prototype.concat():连接两个或多个字符串。
// String.prototype.concat()
console.log(str.concat(' world'));
20: String.prototype.indexOf():返回字符串中指定文本首次出现的位置。
// String.prototype.indexOf()
console.log(str.indexOf('l'));
21: String.prototype.lastIndexOf():返回字符串中指定文本最后一次出现的位置。
// String.prototype.lastIndexOf()
console.log(str.lastIndexOf('l'));
22: String.prototype.slice():提取字符串的一部分,并返回一个新字符串。
// String.prototype.slice()
console.log(str.slice(1, 3));
23: String.prototype.split():把字符串分割为字符串数组。
// String.prototype.split()
const str1 = 'apple,banana,orange';
console.log(str1.split(','));
24: String.prototype.toLowerCase():把字符串转换为小写。
// String.prototype.toLowerCase()
const str2 = 'HELLO';
console.log(str2.toLowerCase());
25: String.prototype.toUpperCase():把字符串转换为大写。
// String.prototype.toUpperCase()
const str3 = 'hello';
console.log(str3.toUpperCase());
26: Number.isNaN():确定传递的值是否为 NaN。
// Number.isNaN()
console.log(Number.isNaN(NaN));
console.log(Number.isNaN('hello'));
27: Number.isInteger():确定传递的值是否为整数。
// Number.isInteger()
console.log(Number.isInteger(5));
console.log(Number.isInteger(5.5));
28: Number.parseFloat():解析一个字符串并返回一个浮点数。
// Number.parseFloat()
console.log(Number.parseFloat('3.14'));
29: Number.parseInt():解析一个字符串并返回一个整数。
// Number.parseInt()
console.log(Number.parseInt('3'));
30: Math.abs():返回一个数的绝对值。
// Math.abs()
console.log(Math.abs(-5));
31: Math.ceil():返回一个数向上取整的值。
// Math.ceil()
console.log(Math.ceil(3.14));
32: Math.floor():返回一个数向下取整的值。
// Math.floor()
console.log(Math.floor(3.14));
33: Math.max():返回一组数中的最大值。
// Math.max()
console.log(Math.max(1, 2, 3));
34: Math.min():返回一组数中的最小值。
// Math.min()
console.log(Math.min(1, 2, 3));
35: Math.pow():返回一个数的指定次幂。
// Math.pow()
console.log(Math.pow(2, 3));
36: Math.random():返回一个介于0和1之间的随机数。
// Math.random()
console.log(Math.random());
37: Date.now():返回当前时间的毫秒数。
// Date.now()
console.log(Date.now());
38: Date.parse():将一个日期字符串转换为毫秒数。
// Date.parse()
console.log(Date.parse('2022-01-01'));
39: Date.UTC():返回一个UTC时间的毫秒数。
// Date.UTC()
console.log(Date.UTC(2022, 0, 1));
40: RegExp.prototype.exec():在字符串中执行一个正则表达式匹配,并返回匹配结果。
// RegExp.prototype.exec()
const regex = /hello/g;
const str4 = 'hello world';
console.log(regex.exec(str4));
41: RegExp.prototype.test():在字符串中测试一个正则表达式匹配,并返回布尔值。
// RegExp.prototype.test()
console.log(regex.test(str4));
42: JSON.parse():将一个JSON字符串转换为JavaScript对象。
// JSON.parse()
const json = '{"name":"John","age":30,"city":"New York"}';
console.log(JSON.parse(json));
43: JSON.stringify():将一个JavaScript对象转换为JSON字符串。
//JSON.stringify()
const obj = { name: 'John', age: 30, city: 'New York' };
console.log(JSON.stringify(obj));
32:javascript 创建对象的几种方式?
答:
- 使用对象字面量:直接使用{}创建对象,可以在{}中添加属性和方法。
- 使用构造函数:使用构造函数创建对象,可以在构造函数中定义属性和方法。
- 使用Object.create()方法:使用Object.create()方法创建对象,可以指定原型对象。
- 使用class关键字:使用class关键字创建对象,可以在类中定义属性和方法。
- 使用工厂函数:使用工厂函数创建对象,可以在函数中定义属性和方法并返回一个新的对象。
- 使用 ES6 箭头函数:使用箭头函数创建对象,可以在函数中定义属性和方法并返回一个新的对象。
代码示例
- 使用对象字面量:直接使用{}创建对象,可以在{}中添加属性和方法。
//1. 使用对象字面量
let obj1 = {name: 'John', age: 30};
- 使用构造函数:使用构造函数创建对象,可以在构造函数中定义属性和方法。
//2. 使用构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
let obj2 = new Person('John', 30);
- 使用Object.create()方法:使用Object.create()方法创建对象,可以指定原型对象。
//3. 使用Object.create()方法
let obj3 = Object.create(null);
- 使用class关键字:使用class关键字创建对象,可以在类中定义属性和方法。
//4. 使用class关键字
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
let obj4 = new Person('John', 30);
- 使用工厂函数:使用工厂函数创建对象,可以在函数中定义属性和方法并返回一个新的对象。
//5. 使用工厂函数
function createPerson(name, age) {
return {
name: name,
age: age
};
}
let obj5 = createPerson('John', 30);
- 使用 ES6 箭头函数:使用箭头函数创建对象,可以在函数中定义属性和方法并返回一个新的对象。
//6. 使用 ES6 箭头函数
const createPerson = (name, age) => ({name, age});
let obj6 = createPerson('John', 30);
33:JavaScript 实现继承的几种实现方式?js继承方式有哪些?
答:
- 原型链继承
- 构造函数继承
- 组合继承
- 原型式继承
- 寄生式继承
- 寄生组合式继承
1: 原型链继承
通过将子类的原型指向父类的实例来实现继承
缺点是所有子类实例共享同一个父类实例,容易造成修改父类实例的属性影响到所有子类实例
function Parent() {
this.name = 'parent';
}
Parent.prototype.sayName = function() {
console.log(this.name);
}
function Child() {
this.age = 18;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
2: 构造函数继承
通过在子类构造函数中调用父类构造函数来实现继承
缺点是无法继承父类原型上的属性和方法
function Parent() {
this.name = 'parent';
}
function Child() {
Parent.call(this);
this.age = 18;
}
3: 组合继承
通过将子类的原型指向父类的实例来继承父类原型上的属性和方法,同时在子类构造函数中调用父类构造函数来继承父类实例上的属性
缺点是会调用两次父类构造函数,造成性能浪费
function Parent() {
this.name = 'parent';
}
Parent.prototype.sayName = function() {
console.log(this.name);
}
function Child() {
Parent.call(this);
this.age = 18;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
4: 原型式继承
原型式继承是基于已有对象创建新对象的一种继承方式,它与原型链继承类似,但是不需要定义构造函数。原型式继承的实现方式是先创建一个空对象,然后将已有对象作为这个空对象的原型,最后返回这个空对象。这样,新对象就可以访问已有对象的属性和方法了。原型式继承的缺点是所有新对象都会共享原型对象的属性和方法,容易造成修改原型对象的属性影响到所有新对象。
function createObj(o) {
function F() {}
F.prototype = o;
return new F();
}
var parent = {
name: 'parent',
sayName: function() {
console.log(this.name);
}
};
var child = createObj(parent);
child.age = 18;
5: 寄生式继承
在原型式继承的基础上,增强了对象,返回一个新对象
缺点是无法实现复杂的继承关系
function createObj(o) {
function F() {}
F.prototype = o;
return new F();
}
function createChild(parent) {
var child = createObj(parent);
child.sayAge = function() {
console.log(this.age);
}
return child;
}
var parent = {
name: 'parent',
sayName: function() {
console.log(this.name);
}
};
var child = createChild(parent);
child.age = 18;
6: 寄生组合式继承
在组合继承的基础上,通过创建一个临时构造函数来继承父类原型上的属性和方法,避免了调用两次父类构造函数
function Parent() {
this.name = 'parent';
}
Parent.prototype.sayName = function() {
console.log(this.name);
}
function Child() {
Parent.call(this);
this.age = 18;
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
34:ES6中的Set、WeakSet、Map、WeakMap?
答:ES6中的Set、WeakSet、Map、WeakMap是四种新的数据结构。
Set是一种类似于数组的数据结构,但是成员的值都是唯一的,没有重复的值。
WeakSet与Set类似,但是成员都是弱引用,可以被垃圾回收机制回收,可以用来保存DOM节点,不容易造成内存泄漏。
Map是一种类似于对象的数据结构,也是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
WeakMap与Map类似,但是只接受对象作为键名(null除外),而且键名所指向的对象,不计入垃圾回收机制。
Set
// Set
let set = new Set();
set.add(1);
set.add(2);
set.add(3);
console.log(set); // Set {1, 2, 3}
WeakSet
// WeakSet
let weakSet = new WeakSet();
let obj = {};
weakSet.add(obj);
console.log(weakSet.has(obj)); // true
Map
// Map
let map = new Map();
map.set('name', 'John');
map.set('age', 30);
console.log(map); // Map { 'name' => 'John', 'age' => 30 }
WeakMap
// WeakMap
let weakMap = new WeakMap();
let key = {};
weakMap.set(key, 'value');
console.log(weakMap.get(key)); // 'value'
35:JavaScript怎么清空数组?
答:
myArray = [];
myArray.length = 0;
myArray.splice(0, myArray.length);
36:forEach,map和filter的区别?
答:
forEach是一个数组方法,它允许您对数组中的每个元素执行一个函数。
map也是一个数组方法,它允许您对数组中的每个元素执行一个函数,并返回一个新数组,其中包含每个元素的结果。
filter是一个数组方法,它允许您根据某些条件筛选数组中的元素,并返回一个新数组,其中包含符合条件的元素。
forEach示例
// forEach示例
const numbers = [1, 2, 3, 4, 5];
numbers.forEach((number) => {
console.log(number * 2);
});
map示例
// map示例
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map((number) => {
return number * 2;
});
console.log(doubledNumbers);
filter示例
// filter示例
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter((number) => {
return number % 2 === 0;
});
console.log(evenNumbers);
37:Es6 for in和for of的区别?
答:
for…in循环是用于遍历对象属性的,而for…of循环是用于遍历可迭代对象的元素的。
for…in循环返回的是对象的键名,而for…of循环返回的是对象的键值。
for...in循环示例
// for...in循环示例
const obj = {a: 1, b: 2, c: 3};
for (let prop in obj) {
console.log(prop); // 输出 'a', 'b', 'c'
}
for...of循环示例
// for...of循环示例
const arr = [1, 2, 3];
for (let val of arr) {
console.log(val); // 输出 1, 2, 3
}
38:prototype 和__proto__的关系是什么?
答:
prototype 是每个函数都有的一个属性,它指向该函数的原型对象。
而 proto 是每个对象都有的一个属性,它指向该对象的原型对象。也就是说,函数的 prototype 属性指向的是它实例化出来的对象的 proto 属性所指向的对象。
// 代码示例
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
}
const person1 = new Person('Alice');
person1.sayHello(); // 输出:Hello, my name is Alice
console.log(person1.__proto__ === Person.prototype); // 输出:true
console.log(Person.prototype.__proto__ === Object.prototype); // 输出:true
39:javascript 的 typeof 返回哪些数据类型?typeof返回的七种数据类型?
答:
JavaScript 的 typeof 返回以下七种数据类型:
- “undefined”
- “boolean”
- “number”
- “string”
- “bigint”
- “symbol”
- “object” (包括 null 和数组)
// 代码示例
console.log(typeof undefined); // 输出 "undefined"
console.log(typeof true); // 输出 "boolean"
console.log(typeof 42); // 输出 "number"
console.log(typeof "JavaScript"); // 输出 "string"
console.log(typeof BigInt(123)); // 输出 "bigint"
console.log(typeof Symbol("foo")); // 输出 "symbol"
console.log(typeof {name: "John", age: 30}); // 输出 "object"
console.log(typeof [1, 2, 3]); // 输出 "object"
console.log(typeof null); // 输出 "object"
40:js常用数组API方法汇总?
答:
- push():向数组末尾添加一个或多个元素,并返回新的长度。
- pop():删除并返回数组的最后一个元素。
- shift():删除并返回数组的第一个元素。
- unshift():向数组开头添加一个或多个元素,并返回新的长度。
- slice():返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝。
- splice():通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。
- concat():用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
- join():将数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。
- reverse():将数组中元素的位置颠倒,并返回该数组。
- sort():对数组元素进行排序,并返回该数组。
- indexOf():返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
- lastIndexOf():返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。
- filter():创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
- forEach():对数组的每个元素执行一次提供的函数。
- map():创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
- reduce():对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
- some():测试数组中是不是至少有1个元素通过了被提供的函数测试。
- every():测试一个数组内的所有元素是否都能通过某个指定函数的测试。
1. push() 向数组末尾添加一个或多个元素,并返回新的长度。
// 1. push() 向数组末尾添加一个或多个元素,并返回新的长度。
const arr1 = [1, 2, 3];
const length1 = arr1.push(4, 5);
console.log(arr1); // [1, 2, 3, 4, 5]
console.log(length1); // 5
2. pop() 删除并返回数组的最后一个元素。
// 2. pop() 删除并返回数组的最后一个元素。
const arr2 = [1, 2, 3];
const lastElement = arr2.pop();
console.log(arr2); // [1, 2]
console.log(lastElement); // 3
3. shift() 删除并返回数组的第一个元素
// 3. shift() 删除并返回数组的第一个元素
const arr3 = [1, 2, 3];
const firstElement = arr3.shift();
console.log(arr3); // [2, 3]
console.log(firstElement); // 1
4. unshift() 向数组开头添加一个或多个元素,并返回新的长度。
// 4. unshift() 向数组开头添加一个或多个元素,并返回新的长度。
const arr4 = [1, 2, 3];
const length4 = arr4.unshift(0, -1);
console.log(arr4); // [0, -1, 1, 2, 3]
console.log(length4); // 5
5. slice() 返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝。
// 5. slice() 返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝。
const arr5 = [1, 2, 3, 4, 5];
const slicedArr = arr5.slice(1, 4);
console.log(slicedArr); // [2, 3, 4]
6. splice() 通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。
// 6. splice() 通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。
const arr6 = [1, 2, 3, 4, 5];
const splicedArr = arr6.splice(2, 2, 6, 7);
console.log(arr6); // [1, 2, 6, 7, 5]
console.log(splicedArr); // [3, 4]
7. concat() 用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
// 7. concat() 用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
const arr7a = [1, 2, 3];
const arr7b = [4, 5, 6];
const concatenatedArr = arr7a.concat(arr7b);
console.log(concatenatedArr); // [1, 2, 3, 4, 5, 6]
8. join() 将数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。
// 8. join() 将数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。
const arr8 = [1, 2, 3];
const joinedString = arr8.join('-');
console.log(joinedString); // "1-2-3"
9. reverse()将数组中元素的位置颠倒,并返回该数组。
// 9. reverse()将数组中元素的位置颠倒,并返回该数组。
const arr9 = [1, 2, 3];
const reversedArr = arr9.reverse();
console.log(reversedArr); // [3, 2, 1]
10. sort()对数组元素进行排序,并返回该数组。
// 10. sort()对数组元素进行排序,并返回该数组。
const arr10 = [3, 1, 2];
const sortedArr = arr10.sort();
console.log(sortedArr); // [1, 2, 3]
11. indexOf()返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
// 11. indexOf()返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
const arr11 = [1, 2, 3, 4, 5];
const index1 = arr11.indexOf(3);
console.log(index1); // 2
12. lastIndexOf()返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。
// 12. lastIndexOf()返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。
const arr12 = [1, 2, 3, 4, 5, 3];
const index2 = arr12.lastIndexOf(3);
console.log(index2); // 5
13. filter() 创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
// 13. filter() 创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
const arr13 = [1, 2, 3, 4, 5];
const filteredArr = arr13.filter(num => num > 3);
console.log(filteredArr); // [4, 5]
14. forEach()对数组的每个元素执行一次提供的函数。
// 14. forEach()对数组的每个元素执行一次提供的函数。
const arr14 = [1, 2, 3];
arr14.forEach(num => console.log(num)); // 1, 2, 3
15. map() 创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
// 15. map() 创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
const arr15 = [1, 2, 3];
const mappedArr = arr15.map(num => num * 2);
console.log(mappedArr); // [2, 4, 6]
16. reduce() 对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
// 16. reduce() 对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
const arr16 = [1, 2, 3];
const reducedArr = arr16.reduce((acc, num) => acc + num, 0);
console.log(reducedArr); // 6
17. some() 测试数组中是不是至少有1个元素通过了被提供的函数测试。
// 17. some() 测试数组中是不是至少有1个元素通过了被提供的函数测试。
const arr17 = [1, 2, 3];
const someResult = arr17.some(num => num > 2);
console.log(someResult); // true
18. every() 测试一个数组内的所有元素是否都能通过某个指定函数的测试。
// 18. every() 测试一个数组内的所有元素是否都能通过某个指定函数的测试。
const arr18 = [1, 2, 3];
const everyResult = arr18.every(num => num > 0);
console.log(everyResult); // true
41:ES6常见的数组方法
答:
- Array.from() 将类数组对象或可遍历对象转换成真正的数组
- Array.of() 创建一个包含任意数量参数的数组
- Array.prototype.find() 返回数组中第一个满足条件的元素
- Array.prototype.findIndex() 返回数组中第一个满足条件的元素的索引
- Array.prototype.fill() 用指定的值填充数组
- Array.prototype.includes() 判断数组是否包含指定的元素
- Array.prototype.flat() 将嵌套的数组展开成一维数组
- Array.prototype.flatMap() 将嵌套的数组展开成一维数组,并对每个元素执行指定的操作
- Array.prototype.keys() 返回一个包含数组中每个索引键的迭代器对象
- Array.prototype.values() 返回一个包含数组中每个值的迭代器对象
- Array.prototype.entries() 返回一个包含数组中每个索引键值对的迭代器对象
- Array.prototype.copyWithin() 将数组中指定位置的元素复制到其他位置
- Array.prototype.sort() 对数组进行排序
- Array.prototype.reverse() 反转数组中的元素
- Array.prototype.join() 将数组中的元素转换成字符串并连接起来
- Array.prototype.concat() 将多个数组合并成一个数组
1. Array.from() 将类数组对象或可遍历对象转换成真正的数组
//1. Array.from() 将类数组对象或可遍历对象转换成真正的数组
const str = 'hello';
const arr = Array.from(str);
console.log(arr); // ['h', 'e', 'l', 'l', 'o']
2. Array.of() 创建一个包含任意数量参数的数组
//2. Array.of() 创建一个包含任意数量参数的数组
const arr1 = Array.of(1, 2, 3);
console.log(arr1); // [1, 2, 3]
3. Array.prototype.find() 返回数组中第一个满足条件的元素
//3. Array.prototype.find() 返回数组中第一个满足条件的元素
const arr2 = [1, 2, 3, 4, 5];
const result = arr2.find(item => item > 3);
console.log(result); // 4
4. Array.prototype.findIndex() 返回数组中第一个满足条件的元素的索引
//4. Array.prototype.findIndex() 返回数组中第一个满足条件的元素的索引
const arr3 = [1, 2, 3, 4, 5];
const index = arr3.findIndex(item => item > 3);
console.log(index); // 3
5. Array.prototype.fill() 用指定的值填充数组
//5. Array.prototype.fill() 用指定的值填充数组
const arr4 = [1, 2, 3, 4, 5];
arr4.fill(0, 2, 4);
console.log(arr4); // [1, 2, 0, 0, 5]
6. Array.prototype.includes() 判断数组是否包含指定的元素
//6. Array.prototype.includes() 判断数组是否包含指定的元素
const arr5 = [1, 2, 3, 4, 5];
console.log(arr5.includes(3)); // true
console.log(arr5.includes(6)); // false
7. Array.prototype.flat() 将嵌套的数组展开成一维数组
//7. Array.prototype.flat() 将嵌套的数组展开成一维数组
const arr6 = [1, [2, 3], [4, [5, 6]]];
console.log(arr6.flat()); // [1, 2, 3, 4, [5, 6]]
8. Array.prototype.flatMap() 将嵌套的数组展开成一维数组,并对每个元素执行指定的操作
//8. Array.prototype.flatMap() 将嵌套的数组展开成一维数组,并对每个元素执行指定的操作
const arr7 = [1, 2, 3];
const result2 = arr7.flatMap(item => [item * item * 2]);
console.log(result2); // [2, 8, 18]
9. Array.prototype.keys() 返回一个包含数组中每个索引键的迭代器对象
//9. Array.prototype.keys() 返回一个包含数组中每个索引键的迭代器对象
const arr8 = ['a', 'b', 'c'];
const keys = arr8.keys();
for (const key of keys) {
console.log(key); // 0, 1, 2
}
10. Array.prototype.values() 返回一个包含数组中每个值的迭代器对象
//10. Array.prototype.values() 返回一个包含数组中每个值的迭代器对象
const arr9 = ['a', 'b', 'c'];
const values = arr9.values();
for (const value of values) {
console.log(value); // 'a', 'b', 'c'
}
11. Array.prototype.entries() 返回一个包含数组中每个索引键值对的迭代器对象
//11. Array.prototype.entries() 返回一个包含数组中每个索引键值对的迭代器对象
const arr10 = ['a', 'b', 'c'];
const entries = arr10.entries();
for (const [index, value] of entries) {
console.log(index, value); // 0 'a', 1 'b', 2 'c'
}
12. Array.prototype.copyWithin() 将数组中指定位置的元素复制到其他位置
//12. Array.prototype.copyWithin() 将数组中指定位置的元素复制到其他位置
const arr11 = [1, 2, 3, 4, 5];
arr11.copyWithin(0, 3, 4);
console.log(arr11); // [4, 2, 3, 4, 5]
13. Array.prototype.sort() 对数组进行排序
//13. Array.prototype.sort() 对数组进行排序
const arr12 = [3, 1, 4, 2, 5];
arr12.sort();
console.log(arr12); // [1, 2, 3, 4, 5]
14. Array.prototype.reverse() 反转数组中的元素
//14. Array.prototype.reverse() 反转数组中的元素
const arr13 = [1, 2, 3, 4, 5];
arr13.reverse();
console.log(arr13); // [5, 4, 3, 2, 1]
15. Array.prototype.join() 将数组中的元素转换成字符串并连接起来
//15. Array.prototype.join() 将数组中的元素转换成字符串并连接起来
const arr14 = [1, 2, 3, 4, 5];
const str1 = arr14.join('-');
console.log(str1); // '1-2-3-4-5'
16. Array.prototype.concat() 将多个数组合并成一个数组
//16. Array.prototype.concat() 将多个数组合并成一个数组
const arr17. Array.prototype.slice() 返回一个新的数组,包含从开始到结束(不包括结束)的原数组中的元素
const arr16 = [1, 2, 3, 4, 5];
const newArr = arr16.slice(1, 3);
console.log(newArr); // [2, 3]
42:构造函数、原型链、继承简单理解?
答:
1:构造函数是一种特殊的函数,用于创建和初始化对象。构造函数的名称通常以大写字母开头,以便与其他函数区分开来。
2:原型链是 JavaScript 中实现继承的主要方法。每个对象都有一个原型对象,它充当了对象的模板,从而使对象可以共享属性和方法。
3:继承是一种创建新类的方式,它从现有类中派生出新类。在 JavaScript 中,可以使用原型链来实现继承。
1:构造函数
构造函数是一种特殊的函数,用于创建和初始化对象。构造函数的名称通常以大写字母开头,以便与其他函数区分开来。
// 构造函数
// 构造函数是一种特殊的函数,用于创建和初始化对象。构造函数的名称通常以大写字母开头,以便与其他函数区分开来。
function Person(name, age) {
this.name = name;
this.age = age;
}
2:原型链
原型链是 JavaScript 中实现继承的主要方法。每个对象都有一个原型对象,它充当了对象的模板,从而使对象可以共享属性和方法。
// 原型链
// 原型链是 JavaScript 中实现继承的主要方法。每个对象都有一个原型对象,它充当了对象的模板,从而使对象可以共享属性和方法。
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};
3: 继承
继承是一种创建新类的方式,它从现有类中派生出新类。在 JavaScript 中,可以使用原型链来实现继承。
// 继承
// 继承是一种创建新类的方式,它从现有类中派生出新类。在 JavaScript 中,可以使用原型链来实现继承。
function Student(name, age, grade) {
Person.call(this, name, age);
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.sayGrade = function() {
console.log(`I am in grade ${this.grade}.`);
};
const person = new Person('Alice', 25);
person.sayHello(); // Hello, my name is Alice and I am 25 years old.
const student = new Student('Bob', 18, 12);
student.sayHello(); // Hello, my name is Bob and I am 18 years old.
student.sayGrade(); // I am in grade 12.
43:js函数?
答:JavaScript函数是一段可重复使用的代码块,它接受输入,执行操作,然后返回结果。函数可以通过关键字function来定义,可以有参数和返回值。函数可以在代码中任何地方调用,使代码更加模块化和可维护。
function functionName(parameter1, parameter2, ...) {
// 函数体
return result;
}
// 例如,定义一个计算两个数之和的函数
function addNumbers(num1, num2) {
return num1 + num2;
}
// 调用函数并输出结果
console.log(addNumbers(5, 10)); // 输出 15
44:js循环遍历常用几种方法?JavaScript循环遍历你会用哪些?js字符串遍历对象?对象遍历那些?字符串遍历有那些?
答:
1:js循环遍历常用几种方法?
答:for循环、forEach、for in、for of、while循环等
1:for循环遍历
// for循环遍历
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
2:forEach循环遍历
// forEach循环遍历
arr.forEach(function(item) {
console.log(item);
});
3:for in循环遍历
// for in循环遍历
for (let key in obj) {
console.log(key + ': ' + obj[key]);
}
4:for of循环遍历
// for of循环遍历
for (let item of arr) {
console.log(item);
}
// while循环
let i = 0;
while (i < arr.length) {
console.log(arr[i]);
i++;
}
2:JavaScript循环遍历你会用哪些?
答:for循环、while循环、do-while循环、forEach()方法、for…in循环、for…of循环等。
1:使用for循环遍历数组
// 1:使用for循环遍历数组
const arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
2:使用while循环遍历数组
// 2:使用while循环遍历数组
let j = 0;
while (j < arr.length) {
console.log(arr[j]);
j++;
}
3:使用do-while循环遍历数组
// 3:使用do-while循环遍历数组
let k = 0;
do {
console.log(arr[k]);
k++;
} while (k < arr.length);
4:使用forEach()方法遍历数组
// 4:使用forEach()方法遍历数组
arr.forEach(function(item) {
console.log(item);
});
5:使用for…in循环遍历对象
// 5:使用for...in循环遍历对象
const obj = {a: 1, b: 2, c: 3};
for (let prop in obj) {
console.log(prop + ': ' + obj[prop]);
}
// 6:使用for...of循环遍历数组
for (let item of arr) {
console.log(item);
}
3:js字符串遍历对象?
答:JavaScript中的字符串是一种基本数据类型,表示文本数据。
字符串可以被视为字符数组,因此可以使用循环遍历字符串中的每个字符。
除此之外,JavaScript还提供了一些内置对象,如String、RegExp等,可以用于操作字符串。
遍历字符串可以使用for循环或者forEach方法,也可以使用for…of循环。
1:下面是一个使用for循环遍历字符串的例子:
// 下面是一个使用for循环遍历字符串的例子:
for (let i = 0; i < str.length; i++) {
console.log(str[i]);
}
2:下面是一个使用forEach方法遍历字符串的例子:
// 下面是一个使用forEach方法遍历字符串的例子:
str.split('').forEach(function(char) {
console.log(char);
});
3:下面是一个使用for…of循环遍历字符串的例子:
// 下面是一个使用for...of循环遍历字符串的例子:
for (let char of str) {
console.log(char);
}
4:对象遍历有那些?
答:
对象遍历有以下几种方式:
- for…in 循环:遍历对象的可枚举属性,包括自身属性和继承属性。
- Object.keys() 方法:返回对象自身的所有可枚举属性的键名组成的数组。
- Object.getOwnPropertyNames() 方法:返回对象自身的所有属性的键名组成的数组,包括不可枚举属性。
- Object.getOwnPropertySymbols() 方法:返回对象自身的所有 Symbol 类型的键名组成的数组。
- Reflect.ownKeys() 方法:返回对象自身的所有键名组成的数组,包括不可枚举属性和 Symbol 类型的键名。
以上是常用的对象遍历方法:
以上是常用的对象遍历方法。
// 示例对象
const obj = {
name: 'Alice',
age: 18,
[Symbol('gender')]: 'female'
};
- for…in 循环:遍历对象的可枚举属性,包括自身属性和继承属性。
// for...in 循环
for (let key in obj) {
console.log(key, obj[key]);
}
- Object.keys() 方法:返回对象自身的所有可枚举属性的键名组成的数组。
// Object.keys() 方法
const keys = Object.keys(obj);
console.log(keys);
- Object.getOwnPropertyNames() 方法:返回对象自身的所有属性的键名组成的数组,包括不可枚举属性。
// Object.getOwnPropertyNames() 方法
const propNames = Object.getOwnPropertyNames(obj);
console.log(propNames);
- Object.getOwnPropertySymbols() 方法:返回对象自身的所有 Symbol 类型的键名组成的数组。
// Object.getOwnPropertySymbols() 方法
const symbols = Object.getOwnPropertySymbols(obj);
console.log(symbols);
- Reflect.ownKeys() 方法:返回对象自身的所有键名组成的数组,包括不可枚举属性和 Symbol 类型的键名。
// Reflect.ownKeys() 方法
const allKeys = Reflect.ownKeys(obj);
console.log(allKeys);
5:字符串遍历有那些
答:字符串遍历可以使用for循环、while循环、forEach()方法、map()方法、filter()方法、reduce()方法等。
1:
// 使用for循环遍历字符串
let str = "hello world";
for(let i = 0; i < str.length; i++){
console.log(str[i]);
}
2: 使用while循环遍历字符串
// 使用while循环遍历字符串
let j = 0;
while(j < str.length){
console.log(str[j]);
j++;
}
3:使用forEach()方法遍历字符串
// 使用forEach()方法遍历字符串
str.split("").forEach(function(char){
console.log(char);
});
4:使用map()方法遍历字符串
// 使用map()方法遍历字符串
let charArray = str.split("").map(function(char){
return char;
});
console.log(charArray);
5:使用filter()方法遍历字符串
// 使用filter()方法遍历字符串
let filteredArray = str.split("").filter(function(char){
return char !== "l";
});
console.log(filteredArray);
6:使用reduce()方法遍历字符串
// 使用reduce()方法遍历字符串
let reducedString = str.split("").reduce(function(acc, char){
return acc + char.toUpperCase();
}, "");
console.log(reducedString);
45:js数组去重几种方法?
答:
1:使用 Set,利用 Set 数据结构的特性,去除重复元素。
2:使用 indexOf,遍历数组,判断元素是否已经存在于新数组中,不存在则添加。
3:使用 includes,遍历数组,判断元素是否已经存在于新数组中,不存在则添加。
4:使用 reduce,遍历数组,判断元素是否已经存在于新数组中,不存在则添加。
1:使用 Set,利用 Set 数据结构的特性,去除重复元素。
// 方法一:使用Set
let arr = [1, 2, 3, 3, 4, 4, 5];
let newArr = [...new Set(arr)];
console.log(newArr); // [1, 2, 3, 4, 5]
2:使用 indexOf,遍历数组,判断元素是否已经存在于新数组中,不存在则添加。
// 方法二:使用indexOf
let arr2 = [1, 2, 3, 3, 4, 4, 5];
let newArr2 = [];
for (let i = 0; i < arr2.length; i++) {
if (newArr2.indexOf(arr2[i]) === -1) {
newArr2.push(arr2[i]);
}
}
console.log(newArr2); // [1, 2, 3, 4, 5]
3:使用 includes,遍历数组,判断元素是否已经存在于新数组中,不存在则添加。
// 方法三:使用includes
let arr3 = [1, 2, 3, 3, 4, 4, 5];
let newArr3 = [];
for (let i = 0; i < arr3.length; i++) {
if (!newArr3.includes(arr3[i])) {
newArr3.push(arr3[i]);
}
}
console.log(newArr3); // [1, 2, 3, 4, 5]
4:使用 reduce,遍历数组,判断元素是否已经存在于新数组中,不存在则添加。
// 方法四:使用reduce
let arr4 = [1, 2, 3, 3, 4, 4, 5];
let newArr4 = arr4.reduce((prev, cur) => {
if (prev.indexOf(cur) === -1) {
prev.push(cur);
}
return prev;
}, []);
console.log(newArr4); // [1, 2, 3, 4, 5]
46:Proxy 与 Object.defineProperty 优劣对比?
答:
1:Proxy的优势:
- Proxy可以代理整个对象,而Object.defineProperty只能代理对象的某个属性
- Proxy可以代理数组,而Object.defineProperty无法代理数组
- Proxy可以代理动态增加的属性,而Object.defineProperty只能代理已经存在的属性
- Proxy可以代理删除属性的操作,而Object.defineProperty无法代理删除属性的操作
- Proxy可以代理函数调用,而Object.defineProperty无法代理函数调用
// Proxy
const obj = new Proxy({}, {
get(target, key, receiver) {
console.log(`getting ${key}`);
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
console.log(`setting ${key}`);
return Reflect.set(target, key, value, receiver);
}
});
obj.name = 'Tom'; // setting name
console.log(obj.name); // getting name
2:Object.defineProperty的优势:
- Object.defineProperty的兼容性更好,支持IE9及以上版本,而Proxy只支持现代浏览器
- Object.defineProperty的性能比Proxy更好,因为Proxy需要进行拦截和处理,而Object.defineProperty只需要在属性访问时进行处理
- Object.defineProperty可以代理属性的getter和setter,而Proxy无法代理属性的getter和setter
// Object.defineProperty
const obj2 = {};
Object.defineProperty(obj2, 'name', {
get() {
console.log('getting name');
return this._name;
},
set(value) {
console.log('setting name');
this._name = value;
}
});
obj2.name = 'Tom'; // setting name
console.log(obj2.name); // getting name
47:JS常见设计模式有哪些?
答:已经拆分到一个文件夹里面了;
48:JS中常见的异步任务?
答:
- AJAX请求
- 定时器
- Promise
- async/await
- 事件监听
- 回调函数
- Web Workers
- 文件读取
- 数据库操作
- 网络请求
1:AJAX请求示例
// AJAX请求示例
$.ajax({
url: 'example.com/api/data',
success: function(response) {
console.log(response);
},
error: function(error) {
console.log(error);
}
});
2:定时器示例:
// 定时器示例
setInterval(function() {
console.log('定时器执行');
}, 1000);
2:Promise示例
// Promise示例
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise执行成功');
}, 2000);
});
promise.then((result) => {
console.log(result);
}).catch((error) => {
console.log(error);
});
3:async/await示例
// async/await示例
async function fetchData() {
try {
const response = await fetch('example.com/api/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.log(error);
}
}
fetchData();
4:事件监听示例
// 事件监听示例
document.addEventListener('click', function(event) {
console.log('点击事件触发');
});
5:回调函数示例
// 回调函数示例
function fetchData(callback) {
$.ajax({
url: 'example.com/api/data',
success: function(response) {
callback(response);
},
error: function(error) {
console.log(error);
}
});
}
fetchData(function(data) {
console.log(data);
});
6:Web Workers示例
// Web Workers示例
const worker = new Worker('worker.js');
worker.postMessage('message');
worker.onmessage = function(event) {
console.log(event.data);
};
7: 文件读取示例
// 文件读取示例
const file = new FileReader();
file.readAsText('example.txt');
file.onload = function(event) {
console.log(event.target.result);
};
8:数据库操作示例
// 数据库操作示例
const db = openDatabase('mydb', '1.0', 'My database', 2 * 1024 * 1024);
db.transaction(function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS users (id unique, name, age)');
tx.executeSql('INSERT INTO users (id, name, age) VALUES (1, "John", 30)');
});
9:网络请求示例
// 网络请求示例
fetch('example.com/api/data')
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.log(error));
49:async await函数?
答:
async/await函数是ES2017引入的新特性,它是异步编程的一种解决方案。async/await函数是基于Promise实现的,它可以让我们以同步的方式编写异步代码,使得代码更加简洁易懂。async/await函数的语法非常简单,只需要在函数前面加上async关键字,然后在需要等待的异步操作前面加上await关键字即可。
// 示例代码
async function getData() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();
console.log(data);
} catch (error) {
console.log(error);
}
}
getData();
50:如何优化大量DOM元素的创建和修改
答:
- 使用文档片段(DocumentFragment)进行批量操作,减少DOM操作次数。
- 尽量减少样式的更改,可以使用CSS class来进行批量更改。
- 使用事件委托,将事件处理程序绑定到父元素上,减少事件处理程序的数量。
- 使用虚拟DOM技术,将DOM操作转化为JavaScript对象的操作,减少DOM操作次数。
- 使用Web Worker进行DOM操作,将DOM操作放在另一个线程中进行,减少主线程的负担。
- 使用innerHTML代替DOM操作,可以减少DOM操作次数。
- 使用requestAnimationFrame代替setTimeout或setInterval进行动画效果的实现,可以更加流畅地进行DOM操作。
- 使用缓存DOM元素,避免重复查询DOM元素,提高性能。
- 使用CSS3动画代替JavaScript动画,可以减少DOM操作次数。
- 使用Web Components技术,将DOM元素封装成自定义组件,提高代码的可重用性和可维护性。
- 使用虚拟列表技术,只渲染可见区域内的DOM元素,减少DOM操作次数。
- 使用CSS Grid或Flexbox布局,减少DOM元素的数量和复杂度,提高性能。
- 使用WebGL或Canvas技术,将DOM元素转化为图形进行渲染,提高性能。
- 使用WebAssembly技术,将DOM操作转化为高效的机器码进行执行,提高性能。
- 使用服务器端渲染(SSR)技术,将DOM操作放在服务器端进行,减少客户端的负担。
- 使用React、Vue等现代前端框架,利用其优化DOM操作的能力,提高性能和开发效率。
- 使用纯函数组件,避免不必要的DOM操作,提高性能。
- 使用shouldComponentUpdate或PureComponent等优化组件的渲染,避免不必要的DOM操作。
- 使用Immutable.js等不可变数据结构,避免不必要的DOM操作,提高性能。
- 使用Web Animations API等现代动画技术,提高动画效果的性能和流畅度。
- 使用分页或滚动加载技术,将大量DOM元素分批加载,减少一次性加载的DOM元素数量,提高性能。
- 使用Memoization技术,缓存计算结果,避免重复计算,提高性能。
- 使用Web Storage技术,将DOM元素缓存到本地存储中,减少网络请求,提高性能。
- 使用Web Components技术,将DOM元素封装成自定义组件,提高代码的可重用性和可维护性。
- 使用Web Workers技术,将DOM操作放在另一个线程中进行,减少主线程的负担。
- 使用CSS Sprite技术,将多个小图标合并成一张大图,减少网络请求,提高性能。
- 使用CSS3 Transitions和Transforms技术,实现动画效果,减少JavaScript操作DOM的次数,提高性能。
- 使用CSS3 Filters技术,实现图像处理效果,减少JavaScript操作DOM的次数,提高性能。
- 使用CSS3 Flexbox技术,实现布局,减少DOM元素的数量和复杂度,提高性能。
- 使用CSS3 Grid技术,实现布局,减少DOM元素的数量和复杂度,提高性能。
- 使用CSS3 Media Queries技术,实现响应式布局,减少DOM元素的数量和复杂度,提高性能。
- 使用CSS3 Selectors技术,实现选择器,减少JavaScript操作DOM的次数,提高性能。
- 使用CSS3 Animations技术,实现动画效果,减少JavaScript操作DOM的次数,提高性能。
- 使用CSS3 Transitions技术,实现动画效果,减少JavaScript操作DOM的次数,提高性能。
- 使用CSS3 Transforms技术,实现动画效果,减少JavaScript操作DOM的次数,提高性能。
- 使用CSS3 Flexbox技术,实现布局,减少DOM元素
// 创建文档片段
const fragment = document.createDocumentFragment();
// 创建1000个div元素
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
div.textContent = `这是第${i}个div元素`;
fragment.appendChild(div);
}
// 将文档片段插入到DOM中
document.body.appendChild(fragment);
// 修改1000个div元素的内容
const divs = document.querySelectorAll('div');
divs.forEach((div, index) => {
div.textContent = `这是修改后的第${index}个div元素`;
});
51:数组操作pop() push() shift() unshift() 有什么区别?
答:
1:pop() 方法从数组中删除最后一个元素,并返回该元素的值。
2:push() 方法将一个或多个元素添加到数组的末尾,并返回新数组的长度。
3:shift() 方法从数组中删除第一个元素,并返回该元素的值。
4:unshift() 方法将一个或多个元素添加到数组的开头,并返回新数组的长度。
区别:
pop() 和 push() 操作的是数组的末尾,而 shift() 和 unshift() 操作的是数组的开头。
pop() 和 shift() 操作会改变原数组的长度,而 push() 和 unshift() 操作不会改变原数组的长度。
push() 和 unshift() 操作可以添加多个元素,而 pop() 和 shift() 操作只能删除一个元素。
实现方法:
// pop()
let arr = [1, 2, 3];
let lastElement = arr.pop(); // lastElement = 3, arr = [1, 2]
// push()
let arr = [1, 2];
let newLength = arr.push(3, 4); // newLength = 4, arr = [1, 2, 3, 4]
// shift()
let arr = [1, 2, 3];
let firstElement = arr.shift(); // firstElement = 1, arr = [2, 3]
// unshift()
let arr = [2, 3];
let newLength = arr.unshift(0, 1); // newLength = 4, arr = [0, 1, 2, 3]
52:描述一下深浅克隆的方法?
答:
浅克隆:只复制对象的引用,而不是对象本身。当对象的属性值发生改变时,克隆出来的对象也会发生改变。
深克隆:复制对象本身,而不是对象的引用。当对象的属性值发生改变时,克隆出来的对象不会发生改变。可以使用JSON.parse(JSON.stringify(obj))或递归实现深克隆。
1:浅克隆
// 浅克隆
let obj1 = {a: 1, b: {c: 2}};
let obj2 = Object.assign({}, obj1);
console.log(obj2); // {a: 1, b: {c: 2}}
obj1.b.c = 3;
console.log(obj2); // {a: 1, b: {c: 3}}
2:深克隆 使用JSON.parse(JSON.stringify(obj))
// 深克隆
// 方法一:使用JSON.parse(JSON.stringify(obj))
let obj3 = {a: 1, b: {c: 2}};
let obj4 = JSON.parse(JSON.stringify(obj3));
console.log(obj4); // {a: 1, b: {c: 2}}
obj3.b.c = 3;
console.log(obj4); // {a: 1, b: {c: 2}}
3:递归实现深克隆
// 方法二:递归实现深克隆
function deepClone(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
let result = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = deepClone(obj[key]);
}
}
return result;
}
let obj5 = {a: 1, b: {c: 2}};
let obj6 = deepClone(obj5);
console.log(obj6); // {a: 1, b: {c: 2}}
obj5.b.c = 3;
console.log(obj6); // {a: 1, b: {c: 2}}
53:JavaScript是多线程还是单线程?为什么JavaScript是单线程?描述一下JS的单线程和事件机制?
1:JavaScript是多线程还是单线程?
答:JavaScript是单线程的。这意味着JavaScript代码只能在一个线程中运行,即主线程。这是因为JavaScript的设计初衷是为了在Web浏览器中运行,而Web浏览器是单线程的。JavaScript的单线程模型可以避免多线程编程中的一些问题,如死锁和竞态条件。但是,JavaScript可以使用异步编程模型来实现并发操作,例如使用回调函数、Promise和async/await等技术。
// 以下是一个简单的JavaScript代码示例
function countToTen() {
for (let i = 1; i <= 10; i++) {
console.log(i);
}
}
countToTen(); // 输出1到10的数字
2:为什么JavaScript是单线程?
答:JavaScript是单线程的原因是因为它的设计初衷是为了在浏览器中运行脚本,而浏览器是单线程的。如果JavaScript是多线程的,那么在浏览器中就会出现多个线程同时操作DOM,这样会导致DOM的状态不一致,从而引发各种问题。因此,JavaScript采用单线程模型,保证了DOM的状态一致性,同时也避免了多线程带来的复杂性。
function countDown(seconds) {
for (let i = seconds; i >= 0; i--) {
setTimeout(function() {
console.log(i);
}, (seconds - i) * 1000);
}
}
countDown(5);
3:描述一下JS的单线程和事件机制?
答:
JavaScript的单线程和事件机制的实现方法是通过事件循环机制来实现的。事件循环机制是JavaScript的核心机制之一,它负责管理事件队列和主线程的执行顺序。
当JavaScript执行代码时,它会将所有的同步任务按照顺序执行,如果遇到异步任务,它会将异步任务加入到事件队列中,等待主线程空闲时再执行。当主线程空闲时,它会从事件队列中取出一个事件,执行对应的回调函数,然后再次进入循环,直到事件队列为空。
事件循环机制的实现方法是通过一个叫做Event Loop的东西来实现的。Event Loop是一个循环,它不断地从事件队列中取出事件,执行对应的回调函数,然后再次进入循环,直到事件队列为空。在每次循环中,Event Loop会检查是否有新的事件加入到事件队列中,如果有,它会将新的事件加入到队列中,等待下一次循环执行。
总的来说,JavaScript的单线程和事件机制的实现方法是通过事件循环机制来实现的,它通过管理事件队列和主线程的执行顺序来保证代码的可靠性和简单性,同时也提供了一种高效的处理事件的方式。
// JS的单线程和事件机制
console.log("start"); // 执行同步代码,输出 "start"
setTimeout(function() { // 将回调函数注册到定时器队列中
console.log("setTimeout"); // 等待定时器到期后,将回调函数推入任务队列中,等待执行
}, 0);
Promise.resolve().then(function() { // 将回调函数注册到微任务队列中
console.log("Promise"); // 等待主线程空闲时,将回调函数推入任务队列中,等待执行
});
console.log("end"); // 执行同步代码,输出 "end"
// 主线程执行完同步代码后,会先执行微任务队列中的回调函数,再执行定时器队列中的回调函数
// 因此,输出顺序为 "start" -> "end" -> "Promise" -> "setTimeout"
54:js事件循环机制?
答:JavaScript事件循环机制是JavaScript的一种执行模型,它是JavaScript实现异步编程的基础。事件循环机制的核心是事件循环,它是一个不断循环的过程,用于监听事件队列中是否有事件需要处理。当事件队列中有事件时,事件循环会将事件取出并执行相应的回调函数。事件循环机制的优点是可以避免阻塞主线程,提高程序的响应速度。
console.log('start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('Promise');
});
console.log('end');
55: javascript中哪方法获取元素?
答:document.getElementById()方法可以通过元素的id属性获取元素。该方法返回一个对象,该对象代表具有指定id的HTML元素。如果没有找到具有指定id的元素,则返回null。
56:什么是全局变量?如何声明,使用有哪些问题?
答:
什么是全局变量?
全局变量是在程序的任何地方都可以访问的变量,它们的作用域是整个程序。在JavaScript中,如果变量在函数外部声明,则它是全局变量。全局变量可以在程序的任何地方被访问和修改,但是过多的全局变量会导致代码难以维护和调试。
全局变量?如何声明,使用有哪些问题?
在JavaScript中,声明全局变量的方法是在函数外部使用var、let或const关键字声明变量。全局变量的使用会带来一些问题,例如可能会被意外修改,可能会与局部变量重名,可能会导致命名冲突等。因此,应该尽量避免使用全局变量,而是使用局部变量或者将变量封装在函数中。
1:var全局变量
// 全局变量是在程序的任何地方都可以访问的变量,它们不是在函数内部声明的,而是在函数外部声明的。
// 在JavaScript中,可以使用var或let关键字声明全局变量。
// 但是,全局变量的使用可能会导致命名冲突和安全问题。
// 示例:
// 声明全局变量
var globalVar = "I am a global variable";
function foo() {
// 在函数内部访问全局变量
console.log(globalVar);
}
foo(); // 输出 "I am a global variable"
// 全局变量可能会被其他函数或代码意外修改,导致程序出现错误。
// 为了避免这种情况,可以使用闭包或命名空间等技术来限制全局变量的作用域。
2:let全局变量:
// let关键字声明全局变量
let globalVar = 'I am a global variable';
function testFunction() {
// 在函数内部使用let关键字声明同名变量
let globalVar = 'I am a local variable';
console.log(globalVar); // 输出:I am a local variable
}
testFunction();
console.log(globalVar); // 输出:I am a global variable
3:const关键字声明全局变量
// const关键字声明全局变量
const globalVar = 'I am a global variable';
function testFunction() {
// 在函数内部使用const关键字声明同名变量
const globalVar = 'I am a local variable';
console.log(globalVar); // 输出:I am a local variable
}
testFunction();
console.log(globalVar); // 输出:I am a global variable
57:解释JavaScript中定时器?说明定时器的缺点?
答:
JavaScript中的定时器是一种机制,它允许开发人员在指定的时间间隔后执行代码。定时器有两种类型:setInterval和setTimeout。
setInterval允许代码在指定的时间间隔内重复执行,
而setTimeout只允许代码在指定的时间间隔后执行一次。
定时器的缺点包括:
- 定时器可能会导致性能问题,因为它们会在后台运行,消耗计算资源。
- 定时器可能会导致代码的不稳定性,因为它们可能会与其他代码发生冲突,导致意外的结果。
- 定时器可能会导致代码的可读性和可维护性降低,因为它们可能会使代码变得复杂和难以理解。
1:使用setInterval每秒输出一次当前时间
// 代码示例
// 使用setInterval每秒输出一次当前时间
setInterval(() => {
const now = new Date();
console.log(`当前时间:${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`);
}, 1000);
定时器的另一个缺点是可能会导致内存泄漏,因为定时器会持续运行,直到被清除或页面被卸载。如果定时器没有被正确清除,它们可能会一直运行,导致内存泄漏。
2:使用setTimeout延迟3秒后输出一句话
// 使用setTimeout延迟3秒后输出一句话
setTimeout(() => {
console.log('3秒后输出这句话');
}, 3000);
58:js延迟(异步)加载的6种方式?
答:
- 使用defer属性
- 使用async属性
- 动态创建script标签
- 使用XMLHttpRequest对象异步加载
- 使用Web Workers
- 使用Intersection Observer API
1:使用defer属性
// 使用defer属性
<script defer src="example.js"></script>
2:使用async属性
// 使用async属性
<script async src="example.js"></script>
3:动态创建script标签
// 动态创建script标签
var script = document.createElement('script');
script.src = 'example.js';
document.body.appendChild(script);
4:使用XMLHttpRequest对象异步加载
// 使用XMLHttpRequest对象异步加载
var xhr = new XMLHttpRequest();
xhr.open('GET', 'example.js', true);
xhr.onload = function() {
eval(xhr.responseText);
};
xhr.send();
5:使用Web Workers
// 使用Web Workers
var worker = new Worker('example.js');
worker.onmessage = function(event) {
console.log(event.data);
};
worker.postMessage('start');
6:使用Intersection Observer API
// 使用Intersection Observer API
var observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var script = document.createElement('script');
script.src = 'example.js';
document.body.appendChild(script);
observer.unobserve(entry.target);
}
});
});
observer.observe(document.querySelector('#target'));
59:描述一下浏览器输入地址URL后的过程?
答:
- 用户在浏览器地址栏中输入URL。
- 浏览器解析URL,获取其中的协议、主机名、端口号、路径等信息。
- 浏览器根据主机名解析出服务器的IP地址。
- 浏览器向服务器发送HTTP请求。
- 服务器接收到请求后,根据路径等信息处理请求,生成响应报文。
- 服务器将响应报文发送给浏览器。
- 浏览器接收到响应报文后,根据响应报文中的内容进行渲染,最终呈现给用户。
60:JSON.stringify() 的5个秘密特性?
答:
- 可以将 JavaScript 对象转换为 JSON 字符串。
- 可以选择性地只包含某些属性。
- 可以对结果进行格式化,使其更易于阅读。
- 可以使用 replacer 函数来修改转换过程中的值。
- 可以使用 space 参数来指定缩进的空格数。
// 代码示例
const obj = {
name: 'John',
age: 30,
city: 'New York'
};
const jsonString = JSON.stringify(obj, ['name', 'age'], 2);
console.log(jsonString);
61:js(dom操作)、jquery(dom操作)、es6(常用函数、数组交集并集操作等)基础知识
答:
1:DOM操作
// DOM操作
document.getElementById('id'); // 通过id获取元素
document.getElementsByClassName('class'); // 通过class获取元素
document.getElementsByTagName('tag'); // 通过标签名获取元素
document.querySelector('selector'); // 通过选择器获取元素
document.querySelectorAll('selector'); // 通过选择器获取所有匹配的元素
// DOM操作
document.getElementById('id'); // 通过id获取元素
document.getElementsByClassName
2:jQuery DOM操作
// jQuery DOM操作
$('selector'); // 通过选择器获取元素
$('.class'); // 通过class获取元素
$('#id'); // 通过id获取元素
3:ES6常用函数
// ES6常用函数
const arr1 = [1, 2, 3];
const arr2 = [2, 3, 4];
const arr3 = [...new Set([...arr1, ...arr2])]; // 数组并集
const arr4 = arr1.filter(item => arr2.includes(item)); // 数组交集
const arr5 = arr1.filter(item => !arr2.includes(item)); // 数组差集
const arr6 = arr1.map(item => item * 2); // 数组映射
const arr7 = arr1.reduce((prev, curr) => prev + curr, 0); // 数组求和
// ES6常用函数
const arr13 = [1, 2, 3, 4, 5];
const arr14 = arr13.filter(item => item % 2 === 0); // 数组过滤
const arr15 = arr13.every(item => item > 0); // 数组每个元素都满足条件
const arr16 = arr13.some(item => item > 5); // 数组是否有元素满足条件
const arr17 = arr13.find(item => item > 2); // 数组查找第一个满足条件的元素
const arr18 = arr13.findIndex(item => item > 2); // 数组查找第一个满足条件的元素的下标
const arr19 = arr13.slice(1, 3); // 数组截取
const arr20 = arr13.splice(1, 2, 6, 7); // 数组删除、插入、替换元素
// ES6常用函数
const arr21 = [1, 2, 3, 4, 5];
const arr22 = arr21.reduceRight((prev, curr) => prev + curr, 0); // 从右到左数组求和
const arr23 = arr21.some(item => item > 5); // 数组是否有元素满足条件
const arr24 = arr21.findIndex(item => item > 2); // 数组查找第一个满足条件的元素的下标
const arr25 = arr21.slice(1, 3); // 数组截取
const arr26 = arr21.splice(1, 2, 6, 7); // 数组删除、插入、替换元素
3:ES6数组交集并集操作
// ES6数组交集并集操作
const arr8 = [1, 2, 3];
const arr9 = [2, 3, 4];
const arr10 = arr8.filter(item => !arr9.includes(item)); // 数组差集
const arr11 = arr8.filter(item => arr9.includes(item)); // 数组交集
const arr12 = [...new Set([...arr8, ...arr9])]; // 数组并集
62:websocket的原理及使用?
答:WebSocket是一种在单个TCP连接上进行全双工通信的协议。它使得客户端和服务器之间的数据交换变得更加简单、更快速,并且可以实现实时通信。WebSocket协议通过在客户端和服务器之间建立持久连接来实现实时通信。在建立连接后,客户端和服务器可以通过WebSocket对象进行双向数据传输。WebSocket协议的使用需要在客户端和服务器端分别实现相应的代码。在客户端,可以使用JavaScript中的WebSocket API来实现WebSocket协议的使用。在服务器端,可以使用Java、Python、Node.js等语言来实现WebSocket协议的使用。
// 创建WebSocket对象
var ws = new WebSocket("ws://localhost:8080");
// 监听WebSocket连接打开事件
ws.onopen = function() {
console.log("WebSocket连接已打开");
};
// 监听WebSocket接收到消息事件
ws.onmessage = function(evt) {
console.log("接收到消息:" + evt.data);
};
// 监听WebSocket连接关闭事件
ws.onclose = function() {
console.log("WebSocket连接已关闭");
};
// 向WebSocket发送消息
ws.send("Hello, WebSocket!");
63:3种强制类型转换和2种隐式类型转换?
答:
强制类型转换:
- Number():将其他类型转换为数字类型。
- String():将其他类型转换为字符串类型。
- Boolean():将其他类型转换为布尔类型。
隐式类型转换:
- 数字类型和字符串类型的加法运算,会将数字类型转换为字符串类型。
- 布尔类型在进行逻辑运算时,会将其转换为数字类型(true为1,false为0)。
1:强制类型转换示例
// 强制类型转换
// 1. Number()
let numStr = '123';
let num = Number(numStr);
console.log(num); // 123
// 2. String()
let num = 123;
let numStr = String(num);
console.log(numStr); // '123'
// 3. Boolean()
let num = 123;
let bool = Boolean(num);
console.log(bool); // true
2: 隐式类型转换
// 1. 字符串拼接
let str = 'hello' + 123;
console.log(str); // 'hello123'
// 2. 数值运算
let num = '123' - 0;
console.log(num); // 123