赞
踩
你的 JavaScript 水平如何?您是摇滚明星 JavaScript 开发人员还是新手?让我们通过这 50 个 JavaScript 面试问题来测试你的知识。每个问题都有一个答案,但我鼓励你们在查看答案之前尽力而为。
JavaScript 是一种动态类型、解释型脚本语言。它支持不同的范例,例如函数式、OOP 和过程式。它是唯一在浏览器上执行的语言,这就是为什么它也被称为网络语言的原因。
动态类型 - 意味着变量在其整个生命周期中可以包含多种类型
复制
复制
COPY
COPY
- let someVarName = "JavaScript" // JavaScript
- someVarName = 12 // 12
- someVarName = {name: "JavaScript"} // {name: "JavaScript"}
- someVarName = false // false
- someVarName = [1,2,3] // [1,2,3]
解释 - 意味着 JavaScript 中的代码不是像 C、C++ 和 Java 等语言那样被编译然后执行,而是以从上到下的逐行方式执行
原始类型
原始类型只能包含一个值,而非原始类型可以有多个。
JavaScript 原始类型
复制
复制
COPY
COPY
- ""
- false
- 1
- null
- undefined
- 123n
- Symbol("symbol")
非原始类型或引用类型
非原始类型一次可以包含原始的多个值
复制
复制
COPY
COPY
- const hobbies = ["Reading", "Calisthenics", "Swimming"]
- const person = {
- name: "Jaxongir",
- age: 27,
- country: "Uzbekistan"
- hobbies
- }
\== - 比较运算符只比较值而不是它们的类型,如果比较不同类型的两个相同值,则会发生类型转换。这是一种类型转换为另一种类型。
复制
复制
COPY
COPY
- console.log(1 == "1") // true
- console.log(false == "0") // true
\=== * - 严格相等比较运算符首先比较值的数据类型。如果它们是同一类型,则比较值,否则它们不是同一类型,无论值是否相同都返回 false
复制
复制
COPY
COPY
- console.log(1 === "1") // false
- console.log(false === "0") // false
**HOF(高阶函数)- 是将另一个函数作为参数并在其主体内调用它或将函数作为值返回的函数
HOF 的示例有:map、filter、for each、reduce 等...
复制
复制
COPY
COPY
- const nums = [1,2,3,4]
- const multiplyNum = nums.map(num => num * 2)
- console.log(multiplyNum) // [2,4,6,8]
- const greet = (greeting)=> name => `${greeting} ${name}!`
- const func = greet("Hello")
- func("Jaxongir") // Hello Jaxongir!
- func("Lola") // Hello Lola!
纯函数- 是没有任何副作用的函数,它从不改变参数并返回与参数相同类型的副本。
复制
复制
COPY
COPY
- // Impure function
- const add = (num1, num2)=> {
- num1 = 10
- return num1 + num2
- }
- // Pure function
- const add = (num1, num2)=> num1 + num2
Currying - 是将具有多个参数的函数转换为具有单个参数的多个函数的函数式编程技术
复制
复制
COPY
COPY
- const curry = (f) => (a) => (b) => f(a, b);
- const product = (num1, num2) => num1 * num2;
- const curriedProduct = curry(product);
- console.log(curriedProduct(20)(5)) // 100
- console.log(curriedProduct(1)(10)) // 10
- console.log(curriedProduct(0)(100)) // 0
让和常量
let 和 const 是 2015 年引入的 ES6 特性
用 let 或 const 声明的变量是作用域 {} 这意味着它们在定义它们的 {} 之外是不可见的
用它们贴标的变量没有被提升,这意味着我们不能在它们定义的变量之前访问
var 是 ES5 特性并且
如果变量在函数中使用 var 关键字声明,那么它在该函数内的范围内,这意味着它不能在它定义的函数体之外访问
在所有其他情况下,用 var 关键字声明的变量是全局范围的
复制
复制
COPY
COPY
- if(10 > 0){
- var test = "right"
- let test2 = "test"
- }
- console.log(test) // right
- console.log(test2) // ReferenceError: test2 is not defined
全局作用域* - 当变量和函数可以全局访问时。因此,当您在任何 {} 之外声明 let 和 const 变量时,它们是全局范围的。当用 var 外部函数声明的变量是全局作用域时
**局部作用域- 只要用 let 和 const 声明的长变量在 {} 内,它们就是局部作用域到该 {} 的主体并向内
复制
复制
COPY
COPY
- // global scope variable
- const name = "Jaxongir"
- // global scoped function
- const func = ()=>{
- // local scoped variable
- let age = 25
- }
- func()
- console.log(name) // Jaxongir
- console.log(age) // ReferenceError: age is not defined
临时死区- 是指无法访问使用 let 或 const 声明的变量。发生这种情况是因为它们没有被吊起。或者更简单的是,它们是不可见的或在时间死区中,从它们在 {} 范围内到为它们分配内存
复制
复制
COPY
COPY
- const fuc = () => {
- console.log(name);
- console.log(age);
- var age = 27;
- let name = "Jaxongir";
- };
- fuc() // ReferenceError: Cannot access 'name' before initialization
提升- 是指用 var 声明的变量和函数声明在执行之前移动到当前作用域的顶部,因此在声明之前可以访问它们。
复制
复制
COPY
COPY
- greeting("Jaxongir")
- function greeting(name) {
- console.log("Hello " + name) // Hello Jaxongir
- console.log(age) // undefined
- var age = 26;
- }
闭包- 基本上是当函数始终访问它的周围范围时,即使在周围范围已经执行之后也是如此。每次创建函数时都会创建闭包。每次创建函数时,该函数都可以访问在其周围范围内定义的变量、函数和对象
复制
复制
COPY
COPY
- let name = "Jaxongir";
- const fun = () => {
- console.log(name) // Jaxongir
- };
- fun()
- const outerFunc = (message)=>{
- let test = "string"
- const innerFunc = (text)=>{
- console.log(message, test, text)
- }
- }
- const test = outerFunc("Hello")
- test("JavaScript")
为了深入解释,看看这个优秀的堆栈溢出
复制
复制
COPY
COPY
- const obj1 = {name: "Lola"}
- const obj2 = {name: "Lola"}
- JSON.stringify(obj1) === JSON.stringify(obj2) // true
复制
复制
COPY
COPY
// object literals const person = {name: "Jaxongir} // Object constructor const person = new Object(); console.log(person); // Object create method const person = Object.create({}); console.log(person); // singleton pattern const person = new (function () { this.name = "Jaxongir"; })(); // Constructor function function Person(name) { this.name = name; } const person = new Person("Jaxongir"); // ES6 Class class Person { constructor(name) { this.name = name; } } const person = new Person("Jaxongir"); console.log(person);
原型链- 当对象从它的原型对象继承它的属性和方法时
,每个其他类型在 JavaScript 中继承的根构造函数是 Object
复制
复制
COPY
COPY
- const company = {
- companyName: "UZS",
- };
- const teacher = {
- fullname: "Jaxongir Rahimov",
- __proto__: company,
- };
- console.log(teacher.companyName) // UZS
- console.log(teacher.fullname) // Jaxongir Rahimov
虽然它们之间的使用方式有所不同,但它们之间的共同点是在函数体内为 this 关键字提供上下文并传入参数
注意:它们只能在函数声明中调用,不能在箭头函数中调用。因为箭头函数没有绑定 this 关键字
call - 使用提供的 this 值和附加参数调用函数。第一个参数总是 this 或 object 的上下文,它可以有 n 个参数
复制
复制
COPY
COPY
const person1 = { name: "Jaxongir", age: 27, country: "Uzbekistan", gender: "male", hobbies: ["Reading", "Calisthenics", "Swimming"], }; const person2 = { name: "Lola", age: 21, country: "Russia", gender: "female", hobbies: ["Reading", "Knitting", "Swimming", "Badminton"], }; function printBio(greeting) { console.log( `${greeting} ${this.gender === "male" ? "His name is" : "Her name is"} ${ this.name } and is ${this.age} years old and is from ${ this.country } and has following hobbies ${this.hobbies.join(", ")}` ); } printBio.call(person1, "Hello") // Hello His name is Jaxongir and is 27 years old and is from Uzbekistan printBio.call(person2, "Hello") // Hello Her name is Lola and is 21 years old and is from Russia
apply - 调用提供此值上下文的函数并传递参数数组
复制
复制
COPY
COPY
- function printBio(greeting) {
- console.log(
- `${greeting} ${this.gender === "male" ? "His name is" : "Her name is"} ${
- this.name
- } and is ${this.age} years old and is from ${this.country}`
- );
- }
- printBio.apply(person1, ["Hello"]);
- printBio.apply(person2, ["Hello"]);
bind - 返回可以存储变量的新函数,当调用该函数时,将其设置为提供的对象和传递的值
复制
复制
COPY
COPY
- function printBio(greeting) {
- console.log(
- `${greeting} ${this.gender === "male" ? "His name is" : "Her name is"} ${
- this.name
- } and is ${this.age} years old and is from ${this.country}`
- );
- }
- printBio.bind(person1)("Hello");
- printBio.bind(person2)("Hello");
JSON代表用于在网络上发送数据的 JavaScript 对象表示法。甚至 Douglas Crockford,前 Atari 员工和创造并推广术语“JSON”的人,也表示他“发现”了 JSON 而不是“发明”
它主要有两个操作
解析- 从文本转换为原始数据
复制
复制
COPY
COPY
JSON.parse("{name: "Jaxongir"}") // {name: "Jaxongir"}
Stringification - 将有效数据转换为字符串格式
复制
复制
COPY
COPY
JSON.stringify({name: "Jaxongir"}) // "{name: "Jaxongir"}"
数组切片方法用于复制字符串和数组的一部分,这样我们就可以使用数组的副本而不是修改它。它用于防止突变。这是切片的链接
复制
复制
COPY
COPY
- let fullname = "Jaxongir Rahimov"
- console.log(fullname.slice(0, 10))
const people = ["Lola", "Jol", "Mat", Jaxongir"]
conosle.log(people.slice(0,2))
数组拼接方法用于删除给定索引中的指定项或在给定索引中添加单个或多个项。链接到拼接
复制
复制
COPY
COPY
- const people = ["Lola", "Jaxongir", "Test", "Horum"];
- // Deleting single item in the given index
- console.log(people); // ["Lola", "Jaxongir", "Test", "Horum"]
- people.splice(2, 1);
- console.log(people); // ["Lola", "Jaxongir", "Horum"]
- // Adding multiple items in the given index
- people.splice(2, 0, "Madina", "Nodira");
- console.log(people); // ["Lola", "Jaxongir", "Madina", "Nodira", "Horum"]
slice - 返回数组的副本并且它不会改变数组
复制
复制
COPY
COPY
- const people = ["Lola", "Jaxongir", "Test", "Horum"];
- console.log(people.slice(0,2)) // ["Lola", "Jaxongir")
- console.log(peopl) // ["Lola", "Jaxongir", "Test", "Horum"]
拼接- 删除单个或多个项目或添加单个或多个项目,并就地进行这些更改
复制
复制
COPY
COPY
- const people = ["Lola", "Jaxongir", "Test", "Horum"];
- people.splice(2, 1);
- console.log(people); // ["Lola", "Jaxongir", "Horum"]
arrow function - 是 ES6 特性,与普通函数声明有一些不同
箭头函数没有 this 关键字,但它在其周围范围内使用 this 的任何值
由于上述原因,箭头函数不能用于创建构造函数
箭头函数没有超级参数
复制
复制
COPY
COPY
- const person = {
- name: "Jaxongir",
- test: () => {
- console.log(arguments) // ReferenceError: arguments is not defined
- console.log(this) // references to window object
- },
- test2() {
- console.log(arguments) // [2, 13, 321, 2]
- console.log(this) // {name: 'Jaxongir', test: ƒ, test2: ƒ}
- },
- };
- person.test();
- person.test2(2, 13, 321, 2);
IIFE - 顾名思义就是函数,声明后立即执行。主要用于创建Module设计模式,Singleton设计模式,
复制
复制
COPY
COPY
- const person = (() => {
- let name = "Jaxongir";
- let age = 27;
- return {
- name,
- age,
- };
- })();
- console.log(person) // {name: "Jaxongir", age: 27}
encodeURI - 将一串 url 作为参数并对它进行编码并返回编码后的 URI
decodeURI - 采用 encodedURI 并返回解码后的 url
复制
复制
COPY
COPY
- const uri = "https://mozilla.org/?x=шеллы";
- const encoded = encodeURI(uri);
- console.log(encoded); // https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B
- console.log(decodeURI(encoded)) // https://mozilla.org/?x=шеллы
记忆- 是一种编程技术,它通过缓存昂贵的函数调用的结果并在发生相同输入时返回缓存的数据来优化应用程序的性能。并且仅在给出不同输入时执行相同的昂贵函数计算
复制
复制
COPY
COPY
- const fib = (num, memo = []) => {
- if (memo[num]) return memo[num];
- if (num <= 2) return 1;
- const res = fib(num - 1, memo) + fib(num - 2, memo);
- memo[num] = res;
- return res;
- };
- console.log(fib(5));
ES6 - 类允许像 Java 或其他 OOP 语言一样以 OOP 风格编写 JavaScript 程序。虽然在幕后,ES6 类转换为构造函数和原型继承开始发挥作用,但编写 OOP 风格的代码仍然更容易,特别是对于那些来自 OOP 语言的人。
复制
复制
COPY
COPY
class Person { constructor(name, age) { this.name = name; this.age = age; } eat(food) { console.log(`${this.name} eats ${food}`); } sleep(time) { console.log(`${this.name} sleeps at ${time}`); } wakeup(time) { console.log(`${this.name} wakesup at ${time}`); } } class Teacher extends Person { constructor(name, age, role, salary, hobbies) { super(name, age); this.role = role; this.salary = salary; this.hobbies = hobbies; } printBio() { console.log( `${this.name} is ${this.age} years old. And he is ${ this.role } with the salary of $${ this.salary }. His hobbies are: ${this.hobbies.join(", ")}` ); } } const jaxongir = new Teacher("Jaxongir", 27, "Full-Stack mentor", 1500, [ "Reading", "Calisthenics", "Swmming", ]); jaxongir.eat("Caviar") // Jaxongir eats Caviar jaxongir.sleep("23:00 pm") // Jaxongir sleeps at 23:00 pm jaxongir.wakeup("09:00 am") // Jaxongir wakesup at 09:00 am jaxongir.printBio() // Jaxongir is 27 years old. And he is Full-Stack mentor with the salary of $1500. His hobbies are: Reading, Calisthenics, Swmming
模块- 是相关可重用代码的容器,可以导入多个文件。
模块非常适合代码的数据隐私、模块化、可维护性、命名空间和可重用性。基本上,它们允许孤立地考虑软件,这减少了大脑的负担,并使考虑程序的整体结构变得容易。
Promise - 指示异步操作结果的对象,可能是失败(拒绝)或成功(完成)。
复制
复制
COPY
COPY
- const promise = new Promise(function (resolve, reject) {
- // promise description
- });
- const promise = new Promise(
- (resolve) => {
- setTimeout(() => {
- resolve("I'm a Promise!");
- }, 5000);
- },
- (reject) => {}
- );
- promise.then((value) => console.log(value));
Promise的3种状态描述如下:
Fulfilled - 当异步请求成功完成并给出响应时
Rejected - 当异步请求不成功并且没有给出响应时,可能是由于网络错误,身份验证或授权错误等
Pending - 在请求发送和响应返回之间
回调- 是作为参数传递给不同函数的函数,然后在该函数体内调用
复制
复制
COPY
COPY
- const nums = [1, 2, 3, 4, 5];
- const myMap = (callbackFunc, nums) => {
- newNums = [];
- for (const num of nums) {
- newNums.push(callbackFunc(num));
- }
- return newNums;
- };
- const modifiedNums = myMap((num) => num * num, nums);
- console.log(modifiedNums) // [1, 4, 9, 16, 25]
回调函数非常有用,尤其是在异步操作中,例如:当获取数据或失败时调用回调以指示请求是成功还是失败。或者在用户单击按钮的事件中,触发回调以在回调主体中执行代码。
复制
复制
COPY
COPY
- const generateReportBtn = document.querySelector(".generate-report");
- const generateReport = ()=>{
- // do something
- }
- generateReportBtn.addEventListener("click", generateReport)
- const populatePeople = ()=>{
- // do something
- }
- setTimeout(populatePeople, 2000)
回调地狱- 这个术语用于描述回调函数何时相互嵌套太深,这使得调试此代码变得更加困难,因为即使是此代码的作者也很难阅读。解决方案是使用异步等待或承诺链接。
回调地狱的例子。这让我在梦中做噩梦
复制
复制
COPY
COPY
fs.readdir(source, function (err, files) { if (err) { console.log('Error finding files: ' + err) } else { files.forEach(function (filename, fileIndex) { console.log(filename) gm(source + filename).size(function (err, values) { if (err) { console.log('Error identifying file size: ' + err) } else { console.log(filename + ' : ' + values) aspect = (values.width / values.height) widths.forEach(function (width, widthIndex) { height = Math.round(width / aspect) console.log('resizing ' + filename + 'to ' + height + 'x' + height) this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) { if (err) console.log('Error writing file: ' + err) }) }.bind(this)) } }) }) } })
Promise Chaining - 是我们在上面看到的回调地狱的解决方案。我们不是将一个回调嵌套在另一个回调中,而是使用先前已完成的承诺的结果,并为链中的下一个承诺返回已完成的承诺。
复制
复制
COPY
COPY
- new Promise(function(resolve, reject) {
- setTimeout(() => resolve(1), 1000); // (*)
- }).then(function(result) { // (**)
- alert(result); // 1
- return result * 2;
- }).then(function(result) { // (***)
- alert(result); // 2
- return result * 2;
- }).then(function(result) {
- alert(result); // 4
- return result * 2;
- });
Promise.all - 是一个静态方法,它将 arraf 个可迭代的承诺作为输入并返回一个单一的 Promise,它是数组中已实现的承诺的值。已实现的承诺与它们的可迭代承诺的顺序相同。如果任何一个承诺被拒绝,整个操作将被拒绝。即使 promise 数组中的最后一个 promise 已实现,Promise.all() 也不会停止操作,而是等待直到每个 promise 都已实现。
复制
复制
COPY
COPY
- const promise1 = Promise.resolve(3);
- const promise2 = 42;
- const promise3 = new Promise((resolve, reject) => {
- setTimeout(resolve, 100, 'foo');
- });
- Promise.all([promise1, promise2, promise3]).then((values) => {
- console.log(values);
- });
- // Expected output: Array [3, 42, "foo"]
Promise.race - 是一种静态方法,它将可迭代的承诺作为输入并返回第一个已解析的承诺值。
复制
复制
COPY
COPY
- const promise1 = new Promise((resolve, reject) => {
- setTimeout(resolve, 500, 'one');
- });
- const promise2 = new Promise((resolve, reject) => {
- setTimeout(resolve, 100, 'two');
- });
- Promise.race([promise1, promise2]).then((value) => {
- console.log(value);
- // Both resolve, but promise2 is faster
- });
- // Expected output: "two"
严格模式- 在 JavaScript 中,用于将 javascript 环境设置为 sticter 模式,以避免错误,例如在没有关键字 var、let、const 的情况下声明变量。可以对整个环境或特定功能启动严格。
我们需要严格模式因为:
通过将它们更改为抛出错误来消除一些 JavaScript 静默错误。
修复了导致 JavaScript 引擎难以执行优化的错误:严格模式代码有时可以比非严格模式的相同代码运行得更快。
禁止某些可能在未来版本的 ECMAScript 中定义的语法。
我们可以通过在全局或特定函数中键入“use strict”来启用严格模式。
复制
复制
COPY
COPY
- // Non strict mode
- age = 27;
- console.log(age) // 27
- // Strict mode
- "use strict";
- age = 27;
- console.log(age) // ReferenceError: age is not defined
删除运算符- 用于删除对象的属性。如果该属性值是一个对象,则对该对象的引用将丢失
复制
复制
COPY
COPY
- const person = {
- name: "John",
- age: 34,
- country: "USA",
- };
- console.log(person) // {name: "John", age: 34, country: "USA"}
- delete person.country;
- console.log(person) // {name: "John", age: 34}
typeof operator - 是一个函数,用于知道传递给它的表达式的类型
复制
复制
COPY
COPY
- console.log(typeof 1) // number
- console.log(typeof "hello") // string
- console.log(typeof false) // boolean
- console.log(typeof []) // object
- console.log(typeof {}) // object
- console.log(typeof undefined) // undefined
- console.log(typeof null) // object
- console.log(typeof NaN) // number
undefined - 是原始数据类型。当声明了变量但没有给出值时,在控制台中它的结果是未定义的。
复制
复制
COPY
COPY
- let name;
- console.log(name) // undefined
null - 也是原始数据类型。它用于指示值的缺失。
复制
复制
COPY
COPY
- let name = null;
- console.log(name) // null
*空
null 是原始数据类型,表示内存中没有为该变量分配内存
用于比较时转换为 0
typeof null 是一个对象
不明确的
undefined - 也是原始数据类型,表示为变量分配了内存并声明了它但没有分配任何值
用于比较时转换为 NaN
未定义的类型是未定义的
eval - 用于将代码字符串作为 JavaScript 脚本执行的函数。代码字符串可以是表达式、函数调用等。
警告:从字符串执行 JavaScript 存在巨大的安全风险。当您使用 eval() 时,坏人很容易运行任意代码 - MDN
复制
复制
COPY
COPY
- const add = (num1, num2) => num1 + num2;
- console.log(eval("add(1, 9)")); // 10
窗户
window 对象是每个页面上的根级元素
默认情况下,它在每个页面中都可用
它有确认、警报等方法
document 或 DOM 是其自身的直接子属性
文档
文档或 DOM 是窗口对象的直接子对象。它是 HTML 的表示
可以通过 document 或 window.document 引用
它让我们通过以下方法访问 DOM 元素:querySelector、getElementById、querySelectorAll 等
它让我们在 UI 上进行增删改查
我们可以通过使用 window 对象的 history 对象来分页历史记录。history 对象有 back 和 forward 方法。
复制
复制
COPY
COPY
- // moves back to previous URI
- window.history.back()
- // moves forward to next URI
- window.history.forward()
我们可以通过使用 KeyboardEvent.getModifierState() 来检测大写锁定键是否被激活,它返回布尔值 true 表示大写锁定键被激活,false 表示未被激活。它不仅可以检测大写锁定,还可以检测 ScrollLock、NumsLock。
复制
复制
COPY
COPY
- const heading = document.querySelector("h1");
- document.body.addEventListener("click", (e) => {
- const isCapsLockOn = e.getModifierState("CapsLock");
- if (isCapsLockOn) {
- heading.textContent = "CapsLock is Activated";
- } else {
- heading.textContent = "CapsLock is Deactivated";
- }
- });
isNaN - 内置函数,用于检查给定输入是否为 NaN(不是数字)
复制
复制
COPY
COPY
- console.log(isNaN("1")) // false it's a number;
- console.log(isNaN("st")) // true it's not a number
未申报
变量是一个未声明或未赋值的变量,当试图访问它时,会抛出错误
没有为它们分配内存,因为它们还不存在
不明确的
变量是已声明但未分配值的变量。
内存已分配,当尝试在控制台中打印时,声明未定义
全局变量- 是在 {} 和函数之外声明的变量,它们在任何地方都可以访问
复制
复制
COPY
COPY
- // global variable
- let name = "Jaxongir"
- (()=>{
- console.log(name) // Jaxongir
- })()
全局变量有很多问题,例如:
名称空间冲突
可维护性
可测试性
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。