为什么我们可以在方法 map() 的用法中省略 return 语句
Why can we omit a return statement in this usage of the method map()
当我注意到他们在使用 map() 之后使用 forEach 时,我目前正在查看他们 docs 上的 WebRTC 教程。为了使用 forEach 并期望一个值而不是未定义的数组,map() 需要 return 一个数组,我不知道它是怎么做到的,因为它没有 return 任何东西.
function updateCameraList(cameras) {
const listElement = document.querySelector('select#availableCameras');
listElement.innerHTML = '';
cameras.map(camera => {
const cameraOption = document.createElement('option');
cameraOption.label = camera.label;
cameraOption.value = camera.deviceId;
}).forEach(cameraOption => listElement.add(cameraOption));
}
由于地图 returns 什么都没有,代码将无法运行。
这是另一种方法
function updateCameraList(cameras) {
document.getElementById('availableCameras').innerHTML = cameras
.map(({label, deviceId}) => `<option value="${deviceId}">${label}</option>`)
.join("");
}
我今天了解到我们现在可以使用标签而不是文本
https://jsfiddle.net/mplungjan/osyLzqk2/
这是一个更安全的版本,因为 XSS 的可能性很小
function updateCameraList(cameras) {
const sel = document.getElementById('availableCameras')
cameras.forEach(({label, deviceId}) => {
const option = new Option(label,deviceId);
sel.add(option)
})
}
这是一个无效的 XSS 尝试 - 至少它在 Chrome
中什么都不做
const cameras = [{ deviceId : `xss"></option></select><img src="x" onerror="alert(1)" />` , label:"bla" }]
function updateCameraList(cameras) {
const xssString = cameras
.map(({label, deviceId}) => `<option value="${deviceId}">${label}</option>`)
.join("")
console.log(xssString)
document.getElementById('availableCameras').innerHTML = xssString;
}
updateCameraList(cameras)
<select id="availableCameras"></select>
代码明显少了一行。代码应该将 undefined 推入一个数组,并将附加到 select.
function updateCameraList(cameras) {
const listElement = document.querySelector('select#availableCameras');
listElement.innerHTML = '';
cameras.map(camera => {
const cameraOption = document.createElement('option');
cameraOption.label = camera.label;
cameraOption.value = camera.deviceId;
return cameraOption;
}).forEach(cameraOption => listElement.add(cameraOption));
}
现在我们为什么要循环两次,这有点浪费时间。所以我只循环一次。
function updateCameraList(cameras) {
const listElement = document.querySelector('select#availableCameras');
listElement.innerHTML = '';
cameras.forEach(camera => {
const cameraOption = document.createElement('option');
cameraOption.label = camera.label;
cameraOption.value = camera.deviceId;
listElement.add(cameraOption));
});
}
当我注意到他们在使用 map() 之后使用 forEach 时,我目前正在查看他们 docs 上的 WebRTC 教程。为了使用 forEach 并期望一个值而不是未定义的数组,map() 需要 return 一个数组,我不知道它是怎么做到的,因为它没有 return 任何东西.
function updateCameraList(cameras) {
const listElement = document.querySelector('select#availableCameras');
listElement.innerHTML = '';
cameras.map(camera => {
const cameraOption = document.createElement('option');
cameraOption.label = camera.label;
cameraOption.value = camera.deviceId;
}).forEach(cameraOption => listElement.add(cameraOption));
}
由于地图 returns 什么都没有,代码将无法运行。
这是另一种方法
function updateCameraList(cameras) {
document.getElementById('availableCameras').innerHTML = cameras
.map(({label, deviceId}) => `<option value="${deviceId}">${label}</option>`)
.join("");
}
我今天了解到我们现在可以使用标签而不是文本
https://jsfiddle.net/mplungjan/osyLzqk2/
这是一个更安全的版本,因为 XSS 的可能性很小
function updateCameraList(cameras) {
const sel = document.getElementById('availableCameras')
cameras.forEach(({label, deviceId}) => {
const option = new Option(label,deviceId);
sel.add(option)
})
}
这是一个无效的 XSS 尝试 - 至少它在 Chrome
中什么都不做const cameras = [{ deviceId : `xss"></option></select><img src="x" onerror="alert(1)" />` , label:"bla" }]
function updateCameraList(cameras) {
const xssString = cameras
.map(({label, deviceId}) => `<option value="${deviceId}">${label}</option>`)
.join("")
console.log(xssString)
document.getElementById('availableCameras').innerHTML = xssString;
}
updateCameraList(cameras)
<select id="availableCameras"></select>
代码明显少了一行。代码应该将 undefined 推入一个数组,并将附加到 select.
function updateCameraList(cameras) {
const listElement = document.querySelector('select#availableCameras');
listElement.innerHTML = '';
cameras.map(camera => {
const cameraOption = document.createElement('option');
cameraOption.label = camera.label;
cameraOption.value = camera.deviceId;
return cameraOption;
}).forEach(cameraOption => listElement.add(cameraOption));
}
现在我们为什么要循环两次,这有点浪费时间。所以我只循环一次。
function updateCameraList(cameras) {
const listElement = document.querySelector('select#availableCameras');
listElement.innerHTML = '';
cameras.forEach(camera => {
const cameraOption = document.createElement('option');
cameraOption.label = camera.label;
cameraOption.value = camera.deviceId;
listElement.add(cameraOption));
});
}