每天10道面试题,助你走上人生巅峰,进大厂不再事梦想.......

123 阅读5分钟

考题列表

  • undefined 和 null 有什么区别?
  • && 运算符能做什么
  • || 运算符能做什么
  • 使用 + 或一元加运算符是将字符串转换为数字的最快方法吗?
  • DOM 是什么?
  • 什么是事件传播?
  • 什么是事件冒泡?
  • 什么是事件捕获?
  • event.preventDefault() 和 event.stopPropagation()方法之间有什么区别?
  • 如何知道是否在元素中使用了event.preventDefault()方法?

1.undefined 和 null 有什么区别?

在理解undefined和null之间的差异之前,我们先来看看它们的相似类。 它们属于 JavaScript 的 7 种基本类型。

  let primitiveTypes =       ['string','number','null','undefined','boolean','symbol', 'bigint'];

它们是属于虚值,可以使用Boolean(value)或!!value将其转换为布尔值时,值为false。

 console.log(!!null); // false
 console.log(!!undefined); // false
 console.log(Boolean(null)); // false
 console.log(Boolean(undefined)); // false

接着来看看它们的区别。

undefined是未指定特定值的变量的默认值,或者没有显式返回值的函数,如:console.log(1),还包括对象中不存在的属性,这些 JS 引擎都会为其分配 undefined 值。

let _thisIsUndefined;
const doNothing = () => {};
const someObj = {
  a : "ay",
  b : "bee",
  c : "si"
};

console.log(_thisIsUndefined); // undefined
console.log(doNothing()); // undefined
console.log(someObj["d"]); // undefined

null是**“不代表任何值的值”**。null是已明确定义给变量的值。在此示例中,当 fs.readFile方法未引发错误时,我们将获得null值。

fs.readFile('path/to/file', (e,data) => {
   console.log(e); // 当没有错误发生时,打印 null
   if(e){
     console.log(e);
   }
   console.log(data);
 });

在比较null和undefined时,我们使用==时得到true,使用===时得到false:

console.log(null == undefined); // true
console.log(null === undefined); // false

2. && 运算符能做什么

&& 也可以叫逻辑与,在其操作数中找到第一个虚值表达式并返回它,如果没有找到任何虚值表达式,则返回最后一个真值表达式。它采用短路来防止不必要的工作。

console.log(false && 1 && []); // false
console.log(" " && true && 5); // 5

使用if语句

const router: Router = Router();
router.get('/endpoint', (req: Request, res: Response) => {
   let conMobile: PoolConnection;
   try {
      //do some db operations
   } catch (e) {
   if (conMobile) {
    conMobile.release();
   }
  }
});

使用&&操作符

const router: Router = Router();
router.get('/endpoint', (req: Request, res: Response) => {
  let conMobile: PoolConnection;
  try {
     //do some db operations
  } catch (e) {
    conMobile && conMobile.release()
  }
});

3. || 运算符能做什么

||也叫或逻辑或,在其操作数中找到第一个真值表达式并返回它。这也使用了短路来防止不必要的工作。在支持 ES6 默认函数参数之前,它用于初始化函数中的默认参数值。

console.log(null || 1 || undefined); // 1
function logName(name) {
  var n = name || "Mark";
  console.log(n);
logName(); // "Mark"

4. 使用 + 或一元加运算符是将字符串转换为数字的最快方法吗?

根据[MDN文档][1],+是将字符串转换为数字的最快方法,因为如果值已经是数字,它不会执行任何操作。

5. DOM 是什么?

DOM 代表文档对象模型,是 HTML 和 XML 文档的接口(API)。当浏览器第一次读取(解析)HTML文档时,它会创建一个大对象,一个基于 HTM L文档的非常大的对象,这就是DOM。它是一个从 HTML 文档中建模的树状结构。DOM 用于交互和修改DOM结构或特定元素或节点。 假设我们有这样的 HTML 结构:

 <!DOCTYPE html>
 <html lang="en">
 
 <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-     scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document Object Model</title>
 </head>
 
 <body>
    <div>
       <p>
          <span></span>
       </p>
       <label></label>
       <input>
    </div>
 </body>
 
 </html>

等价的DOM是这样的: JS 中的document对象表示DOM。它为我们提供了许多方法,我们可以使用这些方法来选择元素来更新元素内容,等等。

6. 什么是事件传播?

当事件发生在DOM元素上时,该事件并不完全发生在那个元素上。在**“冒泡阶段”中,事件冒泡或向上传播至父级,祖父母,祖父母或父级,直到到达window为止;而在“捕获阶段”**中,事件从window开始向下触发元素 事件或event.target。 事件传播有三个阶段:

捕获阶段–事件从 window 开始,然后向下到每个元素,直到到达目标元素。

目标阶段–事件已达到目标元素。

冒泡阶段–事件从目标元素冒泡,然后上升到每个元素,直到到达 window。

7. 什么是事件冒泡?

当事件发生在DOM元素上时,该事件并不完全发生在那个元素上。在冒泡阶段,事件冒泡,或者事件发生在它的父代,祖父母,祖父母的父代,直到到达window为止。 假设有如下的 HTML 结构:

<div class="grandparent">
  <div class="parent">
    <div class="child">1</div>
  </div>
</div>
对应的 JS 代码:
function addEvent(el, event, callback, isCapture = false) {
  if (!el || !event || !callback || typeof callback !== 'function')     return;
  if (typeof el === 'string') {
    el = document.querySelector(el);
  };
  el.addEventListener(event, callback, isCapture);
}

addEvent(document, 'DOMContentLoaded', () => {
  const child = document.querySelector('.child');
  const parent = document.querySelector('.parent');
  const grandparent = document.querySelector('.grandparent');

  addEvent(child, 'click', function (e) {
    console.log('child');
  });

  addEvent(parent, 'click', function (e) {
    console.log('parent');
  });

  addEvent(grandparent, 'click', function (e) {
    console.log('grandparent');
  });

  addEvent(document, 'click', function (e) {
    console.log('document');
  });

  addEvent('html', 'click', function (e) {
    console.log('html');
  })

  addEvent(window, 'click', function (e) {
    console.log('window');
  })

});

addEventListener方法具有第三个可选参数useCapture,其默认值为false,事件将在冒泡阶段中发生,如果为true,则事件将在捕获阶段中发生。如果单击child元素,它将分别在控制台上记录child,parent,grandparent,html,document和window,这就是事件冒泡。

8. 什么是事件捕获?

当事件发生在 DOM 元素上时,该事件并不完全发生在那个元素上。在捕获阶段,事件从window开始,一直到触发事件的元素。 假设有如下的 HTML 结构:

<div class="grandparent">
  <div class="parent">
    <div class="child">1</div>
  </div>
</div>
对应的 JS 代码:
function addEvent(el, event, callback, isCapture = false) {
  if (!el || !event || !callback || typeof callback !== 'function')     return;
  if (typeof el === 'string') {
    el = document.querySelector(el);
  };
  el.addEventListener(event, callback, isCapture);
}

addEvent(document, 'DOMContentLoaded', () => {
  const child = document.querySelector('.child');
  const parent = document.querySelector('.parent');
  const grandparent = document.querySelector('.grandparent');

  addEvent(child, 'click', function (e) {
    console.log('child');
  });

  addEvent(parent, 'click', function (e) {
    console.log('parent');
  });

  addEvent(grandparent, 'click', function (e) {
    console.log('grandparent');
  });

  addEvent(document, 'click', function (e) {
    console.log('document');
  });

  addEvent('html', 'click', function (e) {
    console.log('html');
  })

  addEvent(window, 'click', function (e) {
    console.log('window');
  })

});

addEventListener方法具有第三个可选参数useCapture,其默认值为false,事件将在冒泡阶段中发生,如果为true,则事件将在捕获阶段中发生。如果单击child元素,它将分别在控制台上打印window,document,html,grandparent和parent,这就是事件捕获。

9. event.preventDefault() 和 event.stopPropagation()方法之间有什么区别?

event.preventDefault() 方法可防止元素的默认行为。如果在表单元素中使用,它将阻止其提交。如果在锚元素中使用,它将阻止其导航。如果在上下文菜单中使用,它将阻止其显示或显示。event.stopPropagation()方法用于阻止捕获和冒泡阶段中当前事件的进一步传播。

10. 如何知道是否在元素中使用了event.preventDefault()方法?

我们可以在事件对象中使用event.defaultPrevented属性。它返回一个布尔值用来表明是否在特定元素中调用了event.preventDefault()。