朋友们,美好的一天!
以下是该存储库中的第二百个JavaScript基础问题列表,包括简短答案以及指向Ilya Kantor的Modern JavaScript Tutorial(JSR)和MDN的链接。我的应用程序
中提供了此列表和300多个练习题。 该应用程序实现了一种用于记忆所研究问题的机制,并且还提供了离线工作。 对于任何可能的错误和印刷错误,我深表歉意。任何形式的反馈意见表示赞赏。 版本14.09。 请在此处查看前100个问题。
101. stopPropagation()的作用是什么?
此方法用于防止事件从目标元素的祖先起泡或在链上冒泡。换句话说,它停止将事件从目标元素发送到其祖先。让我们考虑一个例子:
<div onclick="f2()">
<div onclick="f1()"></div>
</div>
function f1(event) {
event.stopPropagation()
console.log(' ')
}
function f2() {
console.log(' ')
}
当您单击嵌套容器时,控制台中将显示消息“内部容器”。如果删除event.stopPropagation(),则在单击嵌套容器时,两个消息都将显示在控制台中。
JSR
MDN
102.返回假是什么意思?
该语句在事件处理程序中用于:
- 取消默认浏览器行为
- 防止事件通过DOM传播
- 停止执行回调并将控制权返回给调用函数
请注意,在未指定返回值的情况下,return语句返回未定义。
JSR
MDN
103.什么是BOM?
BOM或(浏览器对象模型)允许JavaScript与浏览器进行交互。该模型包括导航器,位置,历史记录,屏幕,XMLHttpRequest等对象。换句话说,BOM是浏览器提供的用于处理除文档之外的所有内容的其他对象。
请注意,物料清单不是标准化的,因此其实现在不同的浏览器中可能会有所不同。
JSR
104. setTimeout()的作用是什么?
此方法用于延迟执行任务。换句话说,它允许您在一定时间(毫秒)后运行函数的执行或表达式的求值。在以下示例中,我们在2秒钟后将消息打印到控制台:
setTimeout(() => console.log('!'), 2000)
// ,
const timer = setTimeout(() => {
console.log('!')
clearTimeout(timer)
}, 2000)
JSR
MDN
105. setInterval()的作用是什么?
此方法用于定期执行任务。换句话说,它允许您在一定时间段(以毫秒为单位)之后运行函数的执行或表达式的求值。在以下示例中,我们每2秒将一条消息打印到控制台:
setInterval(() => console.log('!'), 2000)
// ,
//
let i = 0
const timer = setInterval(() => {
console.log('!')
i++
if (i == 2) {
clearInterval(timer)
}
}, 2000)
在第二个示例中,消息“ Hello!” 将打印到控制台两次,然后计时器将停止
JSR
MDN
106.为什么将JavaScript称为单一威胁?
JavaScript是一种单线程或同步编程语言。这意味着一次只能执行一个任务。如果任务很复杂,则可能需要很长时间才能完成,在此期间,代码执行的主线程将被阻塞。反过来,阻止流意味着页面上没有交互性。浏览器停止响应用户操作和其他事件。为了解决此问题,使用了回调,promise,异步/等待,工作程序和其他用于处理异步代码的工具。在JavaScript中,与Java,Go或C ++不同,它无法创建其他线程或进程。
JSR
MDN
107.什么是事件委托?
事件委托是一种在父母身上注册事件以处理孩子提出的事件的技术。
通常用于处理分组容器中的按钮单击或修改表单中的文本输入字段,例如:
<form>
<input type="text" class="first-input">
<input type="text" class="second-input">
</form>
<div>
<button class="first-button">click</button>
<button class="second-button">click</button>
</div>
const form = document.querySelector('form')
const buttons = document.querySelector('div')
form.addEventListener('input', event => {
console.log(event.target.className)
})
buttons.addEventListener('click', event => {
console.log(event.target.className)
})
在上面的示例中,我们没有在子元素上注册处理程序,而是在父元素上注册了它们。在字段中输入文本或按按钮会导致将相应元素的类名称输出到控制台。
JSR
108.什么是ECMAScript?
ECMAScript是JavaScript背后的编程语言。这是“构建” JavaScript的一种模式或蓝图。ECMAScript由标准组织Ecma International在ECMA-262规范中进行了标准化。
JSR
MDN
109.命名JSON语法的功能
JSON语法具有以下功能:
- 数据是键/值对
- 键和值都用双引号引起来,除非值是数字(“键”:“值”)
- 数据用逗号分隔
- 将对象包裹在花括号中
- 数组-平方
JSR
MDN
110. JSON.stringify()有什么作用?
将数据发送到服务器时,它必须具有特殊的字符串格式。JSON.stringify()方法用于将对象转换为JSON字符串:
const user = { name: '', age: 30 }
const str = JSON.stringify(user)
console.log(str) // {"name":"","age":30}
JSR
MDN
111. JSON.parse()有什么作用?
从服务器接收数据时,它们具有特殊的字符串格式。JSON.parse()方法用于将该数据转换为JavaScript对象:
const str = { "name":"","age":30 }
const user = JSON.parse(str)
console.log(user) // {name: "", age: 30}
JSR
MDN
112. JSON的作用是什么?
在客户端和服务器之间交换数据时,此数据只能是字符串。由于JSON是文本,因此非常适合。它也可以与其他格式(例如XML或Protobuf)一起用作任何编程语言的数据格式。
JSR
MDN
113.什么是PWA(渐进式Web应用程序-渐进式Web应用程序)?
简而言之,PWA是行为类似于本机应用程序的网站。它们可以安装在电话或计算机上,并且通常也可以脱机工作。对于后者,使用服务工作者和缓存接口。与移动应用程序相比,PWA的优势在于它们的大小和相对容易的开发。另外,您无需花费资源为一个站点创建两个应用程序-Web和移动。它还保持了良好的用户体验。
MDN
114. clearTimeout()的作用是什么?
此方法用于停止由setTimeout()启动的计时器。为此,将计时器标识符写入变量,然后将其作为参数传递给clearTimeout()。
const timer = setTimeout(() => {
console.log('!')
clearTimeout(timer)
}, 2000)
在上面的示例中,两秒钟后,控制台上显示消息“ Hello!”,然后计时器停止。这样做是为了使垃圾收集器可以删除已运行的计时器。
JSR
MDN
115. clearInterval()的作用是什么?
此方法用于停止以setInterval()启动的计时器。为此,将计时器标识符写入变量,然后将其作为参数传递给clearInterval()。
let i = 1
const timer = setInterval(() => {
console.log(i)
i++
if (i === 3) clearInterval(timer)
}, 1000)
在上面的示例中,变量i的值每秒打印一次到控制台,每次增加1(1、2)。当我变成3时,计时器停止。
JSR
MDN
116.如何重定向?
为此,可以使用窗口对象的location属性:
location.href = 'newPage.html'
//
location.replace('newPage.html')
//
location.assign('newPage.html')
MDN
117.如何检查字符串中是否存在子字符串?
至少有三种方法可以做到这一点。
String.prototype.includes()
const mainStr = 'hello'
const subStr = 'hel'
mainStr.includes(subStr) // true
String.prototype.indexOf()
const mainStr = 'hello'
const subStr = 'hel'
mainStr.indexOf(subStr) !== -1 // true
正则表达式
const mainStr = 'hello'
const regex = /hel/
regex.test(mainStr) // true
JSR
MDN-包含
MDN-indexOf
MDN-测试
118.如何检查电子邮件地址的正确性?
通过将输入字段的类型设置为值email(<input type =“ email”>),可以使用HTML来完成此操作。但是,这种方法不是很可靠。因此,通常,电子邮件使用正则表达式进行验证。建议在服务器端执行此操作,因为可以在客户端上禁用JavaScript:
const validateEmail = email =>
/\S+@\S+.\S+/
.test(email.toString()
.toLowerCase())
const email = 'myemail@example.com'
validateEmail(email) // true
本示例使用最简单的正则表达式之一来验证电子邮件地址。一个更可靠的表达式如下所示(RFC 2822):[a-z0-9!#$%&'* + / =?^ _ \`{|}〜-] +(?:。[A-z0-9!# $%&'* + / =?^ _ \`{|}〜-] +)* @(?:[a-z0-9](?:[a-z0-9-] * [a-z0- 9])?.)+ [A-z0-9](?:[A-z0-9-] * [a-z0-9])?
119.如何获取当前URL?
为此,可以使用窗口对象的location属性或文档对象的URL属性:
console.log(' URL', location.href)
console.log(' URL', document.URL) // Chrome " URL chrome-search://local-ntp/local-ntp.html"
MDN-位置
MDN-document.URL
120.位置对象具有哪些属性?
location对象的属性可用于获取当前页面的URL的一部分:
- href-完整网址
- 来源-协议,主机和端口(来源,用于通用来源策略(SOP)和资源共享(CORS))
- 协议
- 主机-主机和端口
- 主机名-主机
- 港口
- 路径名-路径
- search-查询字符串之后?
- 哈希-#后的查询字符串(锚定)
- 用户名-域之前的用户名
- 密码-域之前的密码
MDN
121.如何获取查询字符串?
您可以为此使用URL构造函数:
const url = new URL('https://example.com?foo=1&bar=2')
console.log(url.search) // ?foo=1&bar=2
console.log(url.searchParams.get('foo')) // 1
MDN
122.如何检查对象中是否存在属性?
至少有三种方法可以做到这一点。
在运算符中
const user = { name: '' }
console.log('name' in user) // true
console.log(!('age' in user)) // true
HasOwnProperty()方法
const user = { name: '' }
console.log(user.hasOwnProperty('name')) // true
console.log(!user.hasOwnProperty('age')) // true
与未定义的比较
const user = { name: '' }
console.log(user.name !== undefined) // true
console.log(user.age === undefined) // true
JSR
MDN-用于...在
MDN中-hasOwnProperty
123.如何遍历对象的枚举属性?
为此,可以将for ... in循环与hasOwnProperty()方法一起使用以排除继承的属性。
const user = {
name: '',
age: 30
}
for (key in user) {
if (user.hasOwnProperty(key)) {
console.log(\`${key}: ${user[key]}\`) // name: age: 30
}
}
JSR
MDN
124.如何检查对象为空?
至少有三种方法可以做到这一点。
Object.entries()方法
const obj = {}
console.log(Object.entries(obj).length === 0) // true
// Date
const obj2 = new Date()
console.log(Object.entries(obj2).length === 0 && obj2.constructor === Object) // false
Object.keys()方法
const obj = {}
console.log(Object.keys(obj).length === 0) // true
// Date
const obj2 = new Date()
console.log(Object.keys(obj2).length === 0 && obj2.constructor === Object) // false
对于... in循环和Object.hasOwnProperty()方法
const obj = {}
const obj2 = {key: 'value'}
const isEmpty = obj => {
for (key in obj) {
if (obj.hasOwnProperty(key)) return false
}
return true
}
console.log(isEmpty(obj)) // true
console.log(isEmpty(obj2)) // false
JSR-JSR对象
-Object.keys,值,条目
MDN-Object.entries
MDN-Object.keys
MDN-for ...在
MDN中-Object.hasOwnProperty
125.参数对象是什么?
arguments是一个类似数组的对象(伪数组),包含传递给函数的参数:
function sum () {
let total = 0
for (let i = 0; i < arguments.length; i++) {
total += arguments[i]
}
return total
//
let total = 0
for (const i of arguments) {
total += i
}
return total
//
return Array.from(arguments).reduce((acc, cur) => acc + cur)
}
sum(1, 2, 3) // 6
请注意,箭头函数没有参数。建议使用rest运算符...(其他参数)代替参数,该运算符可在普通函数和箭头函数中使用:
const sum = (...rest) => rest.reduce((acc, cur) => acc + cur)
sum(1, 2, 3) // 6
JSR
MDN
126.如何大写字符串的第一个字母?
这可以使用charAt(),toUpperCase()和slice()方法来完成:
String.prototype.capitilize = function () {
return this.charAt(0).toUpperCase() + this.slice(1)
}
console.log('hello'.capitilize()) // Hello
JSR
MDN-charAt
MDN-toUpperCase
MDN-切片
127.如何获取当前日期?
这可以使用Date对象或Intl.DateTimeFormat构造函数完成:
console.log(new Date().toLocaleDateString()) // 02.09.2020
console.log(new Intl.DateTimeFormat(
'ru-Ru',
{
weekday: 'long',
day: 'numeric',
month: 'long',
year: 'numeric'
}
).format(new Date())) // , 2 2020 .
JSR-日期
JSR = Intl MDN-
日期
MDN-Intl.DateTimeFormat
128.如何比较两个Date对象?
为此,您不应该比较对象本身,例如,使用getTime()方法返回的值:
const d1 = new Date()
const d2 = new Date(d1)
console.log(d1.getTime() === d2.getTime()) // true
console.log(d1 === d2) // false
JSR
MDN
129.如何检查一条线从另一条线开始?
您可以使用内置的startsWith()方法执行以下操作:
console.log('Good morning'.startsWith('Good')) // true
console.log('Good morning'.startsWith('morning')) // false
根据CanIUse的说法,几乎94%的
JSR MDN浏览器都支持此方法
130.如何消除生产线上的问题?
为此,可以使用内置方法trimStart()(行的开始),trimEnd()(行的结束)和trim()(行的开始和结束):
console.log(' hello world '.trim()) // hello world
修剪不适用于单词之间的空格。在这种情况下,可以使用replace()方法和正则表达式:
console.log('hello world'.replace(/s+/, ' ')) // hello world
//
console.log('hello world'.replace(/s{2,}/, ' ')) // hello world
console.log('key value'.replace(/s{2,}/, ' -> ')) // key -> value
根据CanIUse的说法,93%的浏览器支持trimStart()和trimEnd()。
MDN
131.如何向对象添加新属性?
有两种方法可以做到这一点。假设我们有一个这样的对象:
const obj = {
name: '',
age: 30
}
我们可以使用点或括号符号为其添加新属性:
obj.job = ''
obj['job'] = ''
这些方法之间的区别之一是,当使用括号表示法时,添加的键可以是数字:
const obj = {}
obj[1] = ''
console.log(obj) // { 1: '' }
obj.2 = '' // SyntaxError: Unexpected number
JSR
MDN
132.表达式!-是特殊运算符吗?
不,这不对。它是两个运算符的组合:运算符!(逻辑不)和运算符-(递减)。如果将指定的表达式与任何值一起使用,则首先将这个值减一,然后转换为布尔类型并取反:
const fun = val => !--val
const a = 1
const b = 2
console.log(fun(a)) // !0 -> not false -> true
console.log(fun(b)) // !1 -> not true -> false
JSR
MDN-逻辑非
MDN-递减
133.如何为变量分配默认值?
为此,您可以使用||。(布尔值或):
const a = b || 'default'
在这种情况下,如果变量b的值为false(false,undefined,null,NaN,0,''),则将为变量a分配默认值。
如果我们在谈论功能参数的标准值,则可以按以下方式分配它们:
const greet = (name = '') => \`, ${name}!\`
console.log(greet('')) // , !
console.log(greet()) // , !
此外,后续参数可以使用先前参数的值作为标准值:
const sum = (a = 1, b = a + 2) => a + b
console.log(sum()) // 4
JSR
MDN
134.如何创建多行字符串?
以前,这样做是这样的(串联和换行控制字符):
const str =
' ' + ' ' +
' ' + ' ' +
'!'
//
const str = ' a
!'
console.log(str)
/*
!
*/
现在他们这样做(模板文字):
const str =
\`
!\`
JSR
MDN
135.我们可以向函数添加属性吗?
由于函数也是对象,因此我们可以轻松地向它们添加属性。函数属性值可以是另一个函数:
function someFun () {}
someFun.somePropName = 'somePropValue'
console.log(someFun.somePropName) // somePropValue
//
console.log(someFun.name) // someFun
const sum = (x, y) => x + y
console.log(sum(1, 2)) // 3
sum.curry = x => y => x + y
console.log(sum.curry(1)(2)) // 3
JSR
MDN
136.如何找出一个函数期望接收多少个参数?
length属性可用于此目的:
const sum = (a, b, c) => +a + +b + +c
console.log(sum(1, '1', true)) // 3
console.log(sum(0, '', [])) // 0
console.log(sum.length) // 3
MDN
137.什么是保鲜纸?
Polyfill用于使现代JavaScript在较旧的浏览器中运行。这是通过使用旧语法实现语言的新功能来完成的。将新代码转换为旧代码的过程称为转换。最受欢迎的JavaScript代码转译器是Babel。
例如,最新的JavaScript功能之一是Promise.allSettled()方法,与Promise.all()不同,该方法不会在传递给它的任何承诺被拒绝时终止。
但是,到目前为止,根据CanIUse数据,其浏览器支持为80%,因此需要polyfill:
const promise1 = Promise.resolve('promise1')
const promise2 = Promise.reject('promise2')
const promise3 = Promise.resolve('promise3')
// Promise.allSettled()
Promise
.allSettled([promise1, promise2, promise3])
.then(console.log)
/*
[
{status: "fulfilled", value: "promise1"},
{status: "rejected", reason: "promise2"},
{status: "fulfilled", value: "promise3"},
]
*/
//
// Promise.all() = 94%
const allSettled = promises => {
const wrappedPromises = promises
.map(p => Promise.resolve(p)
.then(
val => ({
status: 'fulfilled',
value: val
}),
err => ({
status: 'rejected',
reason: err
})))
return Promise.all(wrappedPromises)
}
allSettled([promise1,promise2,promise3])
.then(console.log)
JSR
MDN
138.继续和中断语句有什么用?
break语句用于中断循环。停止迭代后,代码继续:
const obj = {
1: 'Everything',
2: 'is',
3: 'impossible'
}
for (key in obj) {
if (obj[key] === 'impossible') break
console.log(obj[key]) // Everything is
}
console.log('possible') // possible
continue语句用于跳过迭代:
const obj = {
1: 'Everything',
2: 'is',
3: 'impossible',
4: 'possible'
}
for (key in obj) {
if (obj[key] === 'impossible') continue
console.log(obj[key]) // Everything is possible
}
MDN-中断
MDN-继续
139.什么是标签?
标签使您可以命名循环和代码块。例如,它们可以用于退出循环或作为执行代码的条件:
loop1:
for (let i = 0; i < 3; i++) {
loop2:
for (let j = 0; j < 3; j++) {
if (i === j) continue loop1
console.log(\`i = ${i}, j = ${j}\`)
}
}
/*
i = 1, j = 0
i = 2, j = 0
i = 2, j = 1
*/
使用标签被认为是不好的做法。
MDN
140.在代码开头声明变量有什么好处?
建议在每个脚本或函数的开头声明变量。这提供了以下好处:
- 保持代码干净
- 所有变量都放在一个地方
- 避免意外创建全局变量
- 防止不必要的变量覆盖
JSR
MDN
141.在声明变量时初始化变量有什么好处?
建议在声明时初始化所有变量。这提供了以下好处:
- 保持代码干净
- 变量及其值在一个地方
- 防止未初始化的变量被分配未定义
JSR
MDN
142.创建对象的主要建议是什么
要创建对象,建议使用括号符号{}代替对象构造函数new Object()。另外,根据值类型,建议使用以下内容:
- 像“”这样的字符串,而不是新的String()
- 一个数字,例如0而不是新的Number()
- 布尔值,如false,而不是新的Boolean()
- []而不是新的Array()
- //代替新的RegExp()
- function(){}代替new Function()
JSR
MDN
143.如何定义JSON格式的数组?
JSON数组是JSON对象的数组,例如:
[
{ "name": "", "age": 30 },
{ "name": "", "age": 20 }
]
JSR
MDN
144.如何实现一个返回给定范围内的随机整数的函数?
可以使用Math对象的Math.random()和Math.floor()方法实现此功能:
const getRandomInteger = (min, max) => Math.floor(min + Math.random() * (max + 1 - min))
JSR
MDN-Math.random()
MDN-Math.floor()
145.什么是摇树?
摇树是删除未使用模块的代码。此类模块不包含在最终组件(捆绑包)中。为了使模块构建器(捆绑程序)确定正在使用哪些模块,哪些没有使用,程序结构必须基于ES6模块。该技术已由Rollup捆绑器普及。
MDN
146.摇树有什么用?
摇树可以通过删除未使用模块的代码来显着减小组件(捆绑)的大小。组件尺寸越小,应用程序性能越好。树状摇动在Rollup和Webpack等模块构建器中实现。
MDN
147.什么是正则表达式?
正则表达式是形成搜索模式的一系列字符。此模式可用于查找文本中的数据,例如字符串中的子字符串。正则表达式被许多编程语言广泛用于文本搜索和替换操作。常规正则表达式模式如下所示:
//
例:
const regex = /java/i
const str = 'JavaScript'
console.log(regex.test(str)) // true
您还可以使用RegExp构造函数来创建正则表达式:
const regex = new RegExp('java', 'i')
const str = 'JavaScript'
console.log(regex.test(str)) // true
JSR
MDN
148.正则表达式使用什么方法?
正则表达式中使用两种主要方法:exec()和test()。
exec()方法在作为参数传递给它的字符串中搜索正则表达式匹配项。此方法的行为取决于正则表达式是否具有g标志。如果不是,则返回第一个匹配项。如果存在g标志,则:
- exec()调用返回第一个匹配项,并将其后的位置存储在lastIndex属性中。
- 下一个这样的调用从位置lastIndex开始搜索,返回下一个匹配项,并记住在lastIndex之后的位置。
- 如果没有更多匹配项,则exec()返回null,并且lastIndex设置为0。
const str = 'Java JavaScript - '
const regex = /Java/g
let result
while (result = regex.exec(str)) {
console.log(
\` ${result[0]} ${result.index}\`
)
}
/*
Java 0
Java 7
*/
test()方法返回一个布尔值,具体取决于是否在字符串中找到匹配项:
const str = ' JavaScript'
console.log(
/ /.test(str) // true
)
JSR
MDN
149.正则表达式中使用了哪些标志?
旗 | 描述 |
---|---|
G | 全局比较 |
一世 | 匹配时忽略大小写 |
米 | 跨多行匹配 |
const regex = /([-]+)s([-]+)/i
const str = ' '
const newStr = str.replace(regex, '$2 $1')
console.log(newStr) //
JSR
MDN
150.正则表达式中使用哪些特殊字符?
正则表达式中使用的特殊字符可以分为几组。
基本字符类:
符号 | 值 |
---|---|
\。 | 除某些字符外的任何字符 |
\ d | 数字 |
\ D | 不是数字 |
\ w | 拉丁字符和下划线 |
\ W | 不拉丁字符和下划线 |
\ s | 空格字符 |
\ S | 没有空格字符 |
\ | 像\一样转义。是重点 |
字符集:
符号 | 值 |
---|---|
[a-yayo-yo] | 俄语字母的任何字母 |
[^ a-yyoA-yoyo] | 除俄语字母以外的任何字符 |
边框:
符号 | 值 |
---|---|
^ | 行首 |
$ | 行结束 |
\ b | 零宽度字边界 |
\ B | 非零宽度字边界 |
分组:
符号 | 值 |
---|---|
(X) | 匹配x,记住匹配项 |
(?: X) | 匹配x,不记得匹配 |
量词:
符号 | 值 |
---|---|
* | 零个或多个字符 |
+ | 一个或多个字符 |
*?和+? | 与*和+类似,但是要寻找最小匹配项 |
? | 零个或一个字符 |
x(?= y) | 如果x后跟y,则匹配x |
x(?!y) | 如果x不跟y则匹配x |
(?<= y)x | 如果x在y之前,则匹配x |
(?!y)x | 如果x不位于y之前,则匹配x |
x | y | x或y |
x {n} | n是x的确切数 |
x {n,} | n-x的最小数量 |
x {n,m} | n-最小数量x,m-最大(从,到) |
JSR
MDN
151.如何更改HTML元素的样式?
这可以通过使用style属性或将适当的类分配给元素来完成:
document
.querySelector(selector)
.style.property = value
document
.querySelector('title')
.fontSize = '2rem'
document.querySelector(selector)
.className = 'class-name'
document.querySelector(selector)
.classList.add('class-name')
document.querySelector('button')
.classList.add('active')
JSR MDN-
样式
MDN-className
MDN-classList
152.什么是调试器?
调试器表达式提供对特定环境中可用的任何调试功能的访问,例如,设置断点(断点,断点)。如果调试功能在运行时不可用,则此表达式无效:
const fun = () => {
//
debugger //
//
}
JSR
MDN
153.调试器断点用于什么?
检查点用于在特定位置暂停函数或其他代码的执行,以找出程序无法正常运行的原因。一旦停止,该功能就可以继续。
JSR
MDN
154.保留字可以用作标识符吗?
不,您不能将保留字用作变量,标签,函数或对象的名称:
const class = ' ' // SyntaxError: Unexpected token 'class'
155.如何确定图像的宽度和高度?
这可以通过多种方式来完成。这是其中之一:
const getImgSize = src => {
const img = new Image()
img.src = src
img.addEventListener('load', () => console.log(\`${img.width} x ${img.height}\`)) // 276 x 110
document.body.append(img)
}
getImgSize('http://www.google.com/ intl/en_ALL/images/logo.gif')
MDN
156.如何发送同步HTTP请求?
为此,可以通过将XMLHttpRequest对象传递给带有第三个可选参数且值为false的open()方法来使用XMLHttpRequest对象:
const getUsers = url => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url, false)
xhr.send()
console.table(xhr.response)
const response = JSON.parse(xhr.response)
const template = \`
<table>
${response.reduce((html, user) => html += \`
<tr>
<td>${user.name}</td>
<td>${user.username}</td>
<td>${user.email}</td>
</tr>\`, '')}
<table>
\`
document.body
.insertAdjacentHTML('beforeend', template)
}
getUsers('https://jsonplaceholder. typicode.com/users')
JSR
MDN
157.如何发出异步HTTP请求?
fetch()方法可用于此目的:
const getUsers = async url => {
const response = await fetch(url)
const data = await response.json()
console.table(data)
const template = \`
<table>
${data.reduce((html, user) => html += \`
<tr>
<td>${user.name}</td>
<td>${user.username}</td>
<td>${user.email}</td>
</tr>\`, '')}
<table>
\`
document.body.insertAdjacentHTML('beforeend', template)
}
getUsers('https://jsonplaceholder. typicode.com/users')
JSR
MDN
158.如何以所需的格式获取日期?
toLocaleString()方法可用于此目的:
console.log(
new Date().toLocaleString('ru-Ru', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
})
) // , 6 2020 .
MDN
159.如何获取最大页面大小?
为此,您需要找到document.body和document.documentElement对象对象的属性scrollWidth,offsetWidth,clientWidth和scrollHeight,offsetHeight,clientHeight的最大值:
const pageWidth = Math.max(
document.body.scrollWidth, document.documentElement.scrollWidth,
document.body.offsetWidth, document.documentElement.offsetWidth,
document.body.clientWidth, document.documentElement.clientWidth
)
const pageHeight = Math.max(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight
)
const pageSize = {
width: pageWidth,
heigth: pageHeight
}
console.log(pageSize)
const pageCenter = {
centerX: pageWidth / 2,
centerY: pageHeight / 2
}
console.log(pageCenter)
JSR
160.什么是条件运算符或三元运算符?
三元运算符是编写if ... else块的简便方法:
let accesAllowed
const age = propmt(' ?')
// if...else
if (age > 18) {
accesAllowed = true
} else {
accessAllowed = false
}
//
(age > 18)
? accesAllowed = true
: accessAllowed = false
JSR
MDN
161.可以使用三元运算符链吗?
是的,在这种情况下,三元运算符可以替代if ... else if ... else块:
let accessAllowed
const getAge = () => prompt(' ?')
// -
// if...else if...else
const checkAge = (age = getAge()) => {
console.log(age)
if (isNaN(age)) {
Promise.resolve(alert(' ')).then(accessAllowed = false).then(checkAge)
} else if (age === null || age === '') {
Promise.resolve(alert(' ')).then(accessAllowed = false).then(checkAge)
} else if (age < 0) {
Promise.resolve(alert(' 0')).then(accessAllowed = false).then(checkAge)
} else if (age > 100) {
Promise.resolve(alert(' 100')).then(accessAllowed = false).then(checkAge)
} else if (age < 18) {
Promise.resolve(alert(', ')).then(accessAllowed = false)
} else {
Promise.resolve(alert(' !')).then(accessAllowed = true)
}
console.log(accessAllowed)
}
//
const checkAge = (age = getAge()) => {
isNaN(age)
? Promise.resolve(alert(' ')).then(accessAllowed = false).then(checkAge)
: (age === null || age === '')
? Promise.resolve(alert(' ')).then(accessAllowed = false).then(checkAge)
: (age < 0)
? Promise.resolve(alert(' 0')).then(accessAllowed = false).then(checkAge)
: (age > 100)
? Promise.resolve(alert(' 100')).then(accessAllowed = false).then(checkAge)
: (age < 18)
? Promise.resolve(alert(', ')).then(accessAllowed = false)
: Promise.resolve(alert(' !')).then(accessAllowed = true)
console.log(accessAllowed)
}
JSR
MDN
162.页面完全加载后如何开始执行代码?
这可以通过几种方式来完成。
将script标记放在结束body标记之前,或向其添加defer属性:
<body>
...
<script src="script.js"></script>
</body>
<!-- -->
<head>
...
<script src="script.js" defer></script>
</head>
如果脚本是模块,则需要使用value模块指定type属性,而不是defer属性:
<script src="script.js" type="module"></script>
将一个onload属性添加到body标签:
<body onload="script()"></body>
将代码添加为窗口对象的load事件的处理程序:
window.onload = () => console.log(' ')
//
window.addEventListener('load', () => console.log(' '))
对document.body执行相同的操作:
document.body.onload = () => console.log(' ')
163. __proto__和prototype有什么区别?
__proto__属性([[Prototype]]内部隐藏属性)是一个对象,实例从该对象继承字段和方法。原型是用于使用new关键字实例化__proto__的对象:
class Person {
constructor(firstName, secondName) {
this.firstName = firstName
this.secondName = secondName
}
getFullName() {
return \`${this.firstName} ${this.secondName}\`
}
}
const user = new Person('', '')
console.log(user.getFullName()) //
console.log(user.__proto__.getFullName === Person.prototype.getFullName) // true
console.log(Person.prototype) // {constructor: ƒ, getFullName: ƒ}
console.log(user.prototype === undefined) // true
JSR
MDN
164.举例说明强制使用分号
分号的强制使用之一是IIFE(立即调用函数表达式)的使用:
例如,以下代码:
try {
const x = ''
(() => {
console.log(x)
})()
} catch {
console.log(' ')
}
将这样解释:
try {
const x = ''(() => {
console.log(x)
})()
} catch {
console.log(' ')
}
因此,在try块中,我们得到TypeError:“ To be”不是函数,控制权传递给catch块,而“ Not be be”输出到控制台。
为了使代码按预期工作,它应如下所示:
try {
//
const x = '';
//
;(() => {
console.log(x)
})()
} catch {
console.log(' ')
}
另外,不要忘记自动分号放置的情况。
165.冻结()方法用于什么?
顾名思义,此方法用于“冻结”对象。冻结的对象是不可变的(immutable)。这意味着您不能向此类对象添加新属性,也不能删除或修改现有属性。此方法还为现有属性设置可配置的:false和可写的:false。该方法返回冻结的对象。
'use strict'
const obj = {
mission: 'possible'
}
Object.freeze(obj)
obj.mission = 'impossible' // TypeError: Cannot assign to read only property 'mission' of object '#<Object>'
delete obj.mission // TypeError: Cannot delete property 'mission' of #<Object>
请注意,在非严格模式下,不会引发任何异常,因此代码根本不会执行。
JSR
MDN
166.为什么我们需要freeze()方法?
面向对象的编程范例说,包含一定数量元素的接口必须是不可变的,即 必须不可能在当前上下文之外扩展,修改或使用元素。此方法是某些其他编程语言中final关键字的别名。
JSR
MDN
167.如何将每个单词的首字母大写?
一种方法如下:
const capitilize = str => str.replace(
/[-]S+/gi,
txt => txt[0].toUpperCase() + txt.slice(1).toLowerCase()
)
console.log(capitilize(', , ')) // , ,
168.我怎么知道页面上是否禁用了JavaScript?
您可以为此使用noscript标记。仅当在页面上禁用JavaScript时,才会执行此标记内的代码:
console.log('JavaScript ')
<noscript>
<p> JavaScript, </p>
</noscript>
要在Chrome中禁用JavaScript,请转到设置->“隐私和安全性”部分->网站设置->“内容”部分-> JavaScript。
MDN
169. JavaScript支持哪些运算符?
运算符用于处理值或操作数。JavaScript支持以下运算符:
- 算术:+(加法,强制转换为数字,级联),-(减法),*(乘法),/(除法),%(模,余数),++(递增),-(递减),* *(取幂)
- 比较运算符:==(抽象,松散相等),!=(抽象不平等),===(严格相等,身份检查),!==(严格不平等),>,> =,<,<=
- 逻辑:&&(和),|| (要么),!(not)(!!!(双重否定)不是单独的运算符)
- 赋值运算符:=,+ =,-=,* =,/ =,%=
- 三元:?... :(如果...否则)
- typeof运算符:定义操作数的类型
- 按位:&(和),| (或),^(非或),〜(非),<<(左移),>>(右移),>>>(零填充的右移)
- 新:?..(可选链),?? (空合并)
//
const obj = {
foo: {
baz: {
qux: 'bar'
}
}
}
//
console.log(obj.foo.bar.baz.qux) // TypeError: Cannot read property 'baz' of undefined
if (
obj.foo !== undefined &&
obj.foo.bar !== undefined &&
obj.foo.bar.baz !== undefined
) {
console.log(obj.foo.bar.baz.qux) //
}
//
console.log(obj?.foo?.bar?.baz?.qux) // undefined
// null
console.log(
0 || 'default null', // 'default null'
0 ?? 'default null', // 0
'' || 'default string', // default string
'' ?? 'default string', // ''
)
JSR - JSR运营商
-逻辑运算符
JSR -比较运算符
JSR -条件
JSR运营商
- MDN位运算符-可选顺序
操作MDN -空合并运算符
170. rest运算符...(其他参数)用于什么?
rest运算符是arguments对象的替代方法,它返回传递给函数的参数数组:
const sum = (...rest) => rest.reduce((acc, cur) => acc + cur)
console.log(sum(1, 2, 3)) // 6
请注意,必须将rest运算符作为最后一个参数传递:
const fun = (x, ...rest, y) => console.log(rest) // SyntaxError: Rest parameter must be last formal parameter
JSR
MDN
171.点差运算符的作用是什么?
扩展运算符用于扩展(解包,扩展)可迭代的实体(数组,字符串)。解包意味着将例如数字数组转换为一组简单值:
const sum = (x, y, z) => x + y + z
const nums = [1, 2, 3]
console.log(sum(...nums)) // 6
JSR
MDN
172.如何确定对象是否冻结?
为了确定对象是否被冻结,即 是否使用isFrozen()方法不可变(immutable):
const obj = {
prop: ' JavaScript!'
}
Object.freeze(obj)
console.log(Object.isFrozen(obj)) // true
MDN
173.如何使用对象确定值的相等性?
is()方法可用于此目的:
Object.is(' ', ' ') // true
Object.is(0.1 + 0.2, 0.3) // false
Object.is(window, window) // true
Object.is(+0, -0) // false
const objA = {}
const objB = objA
Object.is(objA, objB) // true
Object.is({}, {}) // false
如果满足以下条件,则值相等
- 两者都是不确定的
- 两者都为空
- 都是对还是错
- 都是长度相同且字符相同的字符串
- 两者都指向同一个对象
- 都是数字,+ 0,-0或NaN
JSR
MDN
174.如何创建对象的副本?
执行此操作的最可靠方法之一是使用assign()方法:
const objA = {a: 1, b: 2}
const objB = Object.assign(objA)
console.log(objB) // {a: 1, b: 2}
console.log(objA === objB) // true
另外,此方法允许您合并对象,但不包括重复项:
const objA = {a: 1, b: 2}
const objB = {b: 2, c: 3}
const objC = Object.assign(objA, objB)
console.log(objC) {a: 1, b: 2, c: 3}
您可以使用JSON.parse-JSON.stringify绑定来复制简单对象:
const objA = {a: 1, b: 2}
const objB = JSON.parse(JSON.stringify(objA))
console.log(objB) // {a: 1, b: 2}
JSR
MDN
175.什么是代理人?
代理对象“包装”在另一个对象周围,并且可以拦截(并根据需要独立处理)与其相关的各种操作,例如,读取/写入属性等。
const handler = {
get: (obj, prop) => prop in obj
? obj[prop]
: 0
}
// new Proxy(, )
const p = new Proxy({}, handler)
p.a = 1
p.b = true
console.log(p.a, p.b) // 1 true
console.log( 'c' in p, p.c) // false 0
176. seal()方法用于什么?
此方法“密封”对象,防止添加/删除属性。它还设置了可配置的:所有现有属性为false。但是,可以更改此类对象的属性值。isSealed()方法用于检查对象是否密封。
'use strict'
const obj = {
prop: ' JavaScript!'
}
Object.seal(obj)
obj.prop = ' , '
console.log(Object.isSealed(obj)) // true
delete obj.prop // TypeError: Cannot delete property 'prop' of #<Object>
console.log(obj.prop) // ,
请注意,在宽松模式下,尝试删除密封对象上的属性的尝试将自动失败。
JSR
MDN
177. Frozen()和seal()方法之间有什么区别?
与Object.freeze()方法不同,Object.seal()方法允许您修改对象的现有属性。
'use strict'
const objA = {
prop: ''
}
Object.freeze(objA)
objA.prop = ' ' // TypeError: Cannot assign to read only property 'prop' of object '#<Object>'
const objB = {
prop: ' '
}
Object.seal(objB)
objB.prop = ''
console.log(objB.prop) //
178.如何获取对象的枚举键/值对?
Object.entries()方法返回一个枚举对象键/值对的数组作为子数组,其顺序与for ... in循环相同:
const obj = {
x: 1,
y: 2
}
console.log(Object.entries(obj)) // [["x", 1], ["y", 2]]
for (let [key, value] of Object.entries(obj)) {
console.log(\`${key}: ${value}\`) // x: 1 y: 2
}
JSR
MDN
179. Object.keys(),Object.values()和Object.entries()方法之间的主要区别是什么?
Object.keys()方法返回对象的键,Object.values()方法返回其属性的值,而Object.entries()返回键/值对的数组:
const user = {
name: '',
age: 30
}
console.log(Object.keys(user)) // ["name", "age"]
console.log(Object.values(user)) // ["", 30]
console.log(Object.entries(user)) // [["name", ""], ["age", 30]]
JSR
MDN-Object.keys()
MDN-Object.values()
MDN-Object.entries()
180.如何在不使用构造函数和类的情况下使用特定的原型创建对象?
Object.create()方法可用于此目的:
const firstUser = {
name: '',
sayHi() {
console.log(\`, ${this.name}!\`)
}
}
const secondUser = Object.create(firstUser)
secondUser.name = ''
secondUser.sayHi() // , !
JSR
MDN
181. WeakSet的作用是什么?
WeakSet用于存储松散引用的对象的集合。换句话说,它用作其他代码使用的对象的附加存储。当这些对象变得不可访问(未使用)时,即垃圾回收器会自动将其删除。当只有密钥保留在WeakSet中时。
const ws = new WeakSet()
let user = {}
ws.add(user)
console.log(ws.has(user)) // true
user = null
console.log(ws.has(user)) // false,
JSR
MDN
182. Set和WeakSet有什么区别?
它们的主要区别是存储在WeakSet中的对象被弱引用,即 一旦无法访问,就会被自动删除。其他区别如下:
- Set可以存储任何值,而WeakSet只能存储对象。
- WeakSet没有大小属性
- WeakSet没有clear(),keys(),values(),forEach()方法
- WeakSet不是可迭代的实体
JSR
MDN
183. WeakSet中提供哪些方法?
WeakSet具有以下方法:
- add():向集合添加一个对象
- delete():从集合中删除对象
- has():确定对象是否在集合中
- length():返回集合的长度
const ws = new WeakSet()
const objA = {}
const objB = {}
ws.add(objA)
ws.add(objB)
console.log(ws.has(objA)) // true
console.log(ws.lenghth()) // 2
ws.delete(objA)
console.log(ws.has(objA)) // false
JSR
MDN
184. WeakMap的作用是什么?
WeakMap用于存储弱引用键的键/值对。换句话说,它充当其他代码使用的键的附加存储库。当此类密钥变得不可访问(未使用)时,即垃圾回收器会自动将其删除。当只有密钥保留在WeakMap中时。
const wm = new WeakMap()
let user = {}
wm.set(user, 'user')
console.log(wm.has(user)) // true
user = null
console.log(wm.has(user)) // false,
JSR
MDN
185. Map和WeakMap有什么区别?
它们的主要区别在于,WeakMap中存储的密钥被弱引用,即 一旦无法访问,就会被自动删除。其他区别如下:
- Map可以使用任何值作为键,而WeakMap只能使用对象
- WeakMap没有大小属性
- WeakMap没有clear(),keys(),values(),entries(),forEach()方法
- WeakMap不是可迭代的实体
JSR
MDN
186. WeakMap提供哪些方法?
WeakMap具有以下方法:
- set():将键/值对添加到对象
- delete():按键删除值
- has():确定键是否存在值
- get():按键返回值
const wm = new WeakMap()
const firstUser = {}
const secondUser = {}
wm.set(firstUser, '')
wm.set(secondUser, '')
console.log(wm.has(firstUser)) // true
console.log(wm.get(firstUser)) //
wm.delete(secondUser)
console.log(wm.has(secondUser)) // false
JSR
MDN
187.如何编码URL?
您可以为此使用encodeURI()方法。此方法转换除/?以外的所有特殊字符:@ = + $#
const url = 'https://ru.wikipedia.org/wiki/,__'
const encoded = encodeURI(url)
console.log(encoded) // https://ru.wikipedia.org/wiki/%D0%9B%D0...
JSR
MDN
188.如何解码URL?
您可以为此使用decodeURI()方法:
const url = 'https://ru.wikipedia.org/wiki/%D0%9B%D0...'
const decoded = decodeURI(url)
console.log(decoded) // https://ru.wikipedia.org/wiki/,__
JSR
MDN
189.如何打印页面内容?
您可以为此使用global print()方法。此方法将打开一个带有打印设置的特殊对话框:
<button></button>
document.querySelector('button')
.addEventListener('click', () => print())
MDN
190.什么是匿名函数?
匿名函数是未命名的函数。通常将此类函数分配给变量,并用作回调:
const sayHi = function () {
console.log('')
}
sayHi() //
//
const sayBye = () => console.log('')
sayBye() //
window.addEventListener('click', function () {
console.log(' , ')
})
//
window.addEventListener('contextmenu', e => {
e.preventDefault()
console.log(' - ')
})
JSR
MDN
191.使用局部变量和全局变量的优先级是什么?
局部变量优先于同名的全局变量:
let question = ' '
function toBe () {
question = ''
console.log(question)
}
toBe() //
JSR
MDN
192.什么是访问器?
访问器或计算属性是获取器和设置器。获取器用于获取对象属性的值,设置器用于设置它们:
class User {
constructor (name, age) {
this.name = name
this.age = age
}
#access = false
get access () {
return this.#access
}
set access (bool) {
this.#access = bool
}
}
const user = new User('', 30)
console.log(user.#access) // SyntaxError: Private field '#access' must be declared in an enclosing class
console.log(user.access) // false
user.access = true
console.log(user.access) // true
获取器和设置器是属性,方法是函数:
class User {
constructor (name, age) {
this.name = name
this.age = age
}
#access = false
getAccess () {
return this.#access
}
setAccess(bool) {
this.#access = bool
}
}
const user = new User('', 30)
console.log(user.#access) // SyntaxError: Private field '#access' must be declared in an enclosing class
console.log(user.getAccess()) // false
user.setAccess(true)
console.log(user.getAccess()) // true
JSR
193.如何在对象构造函数中定义属性?
为此可以使用Object.defineProperty()方法。此方法使您可以向对象添加新属性并修改现有属性,以及更改用于访问对象的设置:
'use strict'
const obj = {}
Object.defineProperty(obj, 'prop', {
value: 1,
writable: false
})
console.log(obj.prop) // 1
obj.prop = 2 // TypeError: Cannot assign to read only property 'prop' of object '#<Object>'
在宽松模式下,尝试更改只读属性将无提示地失败。
JSR
MDN
194.吸气剂和吸气剂的特征是什么?
getter和setter的主要功能如下:
- 与方法相比,它们的语法更简单。
- 用于定义计算属性-访问器
- 使属性和方法之间具有相同的关系
- 可以提供更好的数据质量
- 涉及封装时,允许您在后台执行任务
JSR
195.可以使用Object.defineProperty()方法将获取器和设置器添加到对象吗?
相当:
const obj = {counter: 0}
Object.defineProperty(obj, 'increment', {
get() {return ++this.counter}
})
Object.defineProperty(obj, 'decrement', {
get() {return --this.counter}
})
Object.defineProperty(obj, 'sum', {
set(val) {return this.counter += val}
})
Object.defineProperty(obj, 'sub', {
set(val) {return this.counter -= val}
})
obj.sum = 10
obj.sub = 5
console.log(obj) // {counter: 5}
console.log(obj.increment) // 6
console.log(obj.decrement) // 5
JSR
MDN
196. switch ... case的作用是什么?
switch ... case是if ... else的替代方法,是一种根据传递的条件以更直观的方式执行代码的方式:
const calc = (x, y, operator) => {
let result
try {
switch (operator) {
case '+':
result = x + y
break
case '-':
result = x - y
break
case '*':
result = x * y
break
case '/':
result = x / y
break
default:
throw new Error(' ')
}
if (isNaN(result)) {
throw new Error(' ')
}
console.log(result)
return result
} catch (e) {
console.error(e.message)
}
}
calc(1, 2, '+') // 3
calc(3, 4, '*') // 12
calc('a', 1, '-') //
calc(5, 6, 'x') //
JSR
MDN
197.命名使用switch ... case的规则
使用switch ...案例构造时,必须遵守以下规则:
- 条件可以是数字或字符串
- 不允许重复值
- 默认语句是可选的。如果没有找到情况,则执行默认块
- break用于停止循环
- break也是可选的,但是没有它,循环执行将继续
JSR
MDN
198.命名原始数据类型。
JavaScript中的原始数据类型(“原始”)是以下值:
- number : , ±253
- bigint
- string . ,
- boolean true/false
- null – , null
- undefined – , undefined
- symbol
MDN
Habr — JavaScript?
Habr — JavaScript ?
JavaScript ?
Medium — Advanced JavaScript ES6 — Temporal Dead Zone, Default Parameters And Let vs Var — Deep dive!
JavaScript:
̆ JavaScript
Medium — JavaScript.
Habr — JavaScript
Medium — Understanding Prototypes in JavaScript
Medium — apply(), call() bind(), JavaScript
JavaScript:
Medium — JavaScript Classes: An In-Depth look (Part 1)
Medium — JavaScript slice(), splice() split()
JavaScript
JavaScript- .map(), .filter() .reduce()
reduce() JavaScript
̆ ̆ ECMAScript 2019, for-of
ES2020,
DigitalOcean — map set JavaScript
Medium — JavaScript
Medium — What is Memoization in Javascript?
Redd — Debounce vs Throttle: Definitive Visual Guide
JavaScript
Habr — 5 JSON.stringify()
Habr — () «» JavaScript
Habr — JavaScript- : . 1
Habr — -
GoogleDevelopers — Service Workers: an Introduction
Habr —
WebDevBlog — IndexedDB
GoogleDevelopers — Working with IndexedDB
Habr — Web Storage API:
Habr — -
Medium — A Simple Introduction to Web Workers in JavaScript
Habr — JavaScript,
Habr — Async/Await
Habr — CORS: