1.延迟加载JS有哪些方式?
延迟加载:async、defer
例如:<script defer type="text/javascript>javascript" src='script.js'></script>
defer:等html全部解析完毕,才会执行js代码,顺次执行js脚本
async:async是和html解析同步的(一起的),不是顺次执行js脚本(谁先加载完谁先执行)。
2.JS数据类型有哪些?
基本类型:string、number、boolean、undefined、null、symbol、bigint(有争议)
引用类型:object
NaN是一个数值类型,但不是一个具体的数字。
3.JS数据类型考题
// 1. alter(true + 1) // 2 alter('name' + true) // nametrue alter(undefined + 1) // NaN alter(typeof null) // object
字符串和其他类型 相加,变成连接的形式。
//2 alter(typeof(NaN)) // number alter(typeof(undefined)) // undefined alter(typeof(null)) // object
4.nul和undefined的区别
1.作者在设计js的时候是先设计的null
(为什么设计了null:最初设计js的时候借鉴了java的语言)
2.null会被隐式转换成0,很不容易发现错误
3.先有null后有undefined,出来undefined是为了填补之前的坑
具体区别:JavaScript的最初版本是这样区分的:null是一个表示“无”的对象(空对象指针),转为数值时为0;undefined是一个表示“无”的原始值,转为数值时为NaN。
5.==和===有什么不同?
==:比较的是值
string == number || boolean || ......都会隐式转换
通过valueOf转换(valueOf() 方法通常由JavaScript在后台自动调用,并不显式地出现在代码中)
===:除了比较值,还比较类型建议使用===,因为==可能存在一些问题。
6.JS微任务和宏任务
1.JS是单线程的语言。
2.JS代码执行流程:同步执行完==》事件循环同步的任务都执行完了,才会执行事件循环的内容
进入事件循环:请求ajax、定时器、事件......
3.事件循环中包含:【微任务、宏任务】
微任务:Promise.then
宏任务:setTimeout..
要执行宏任务的前提是清空了所有的微任务
流程:同步==>事件循环【微任务和宏任务】==>微任务==>宏任务==>微任务.....
为什么JS是单线程?单线程就是同一个时间只能做一件事。JS的单线程与它的用途有关,作为浏览器脚本语言,它的主要用途就是与用户互动,以及操作DOM,这就决定了它的单线程。
setTimeout(function(){console.log('1') // 宏任务 })new Promise((resolve)=>{console.log('1 promise 1'); // 同步resolve(); }).then(()=>{console.log('微1') // 微任务 }).then(()=>{console.log('微2') // 微任务 })console.log('2') // 同步-------------------------- 输出的结果: 1 promise 1 2 微1 微2 1
7.JS作用域考题
1.除了函数外,JS是没有块级作用域的
2.作用域链:内部可以访问外部的变量,但是外部不能访问内部的变量
注意:如果内部有,优先查找到内部,如果内部没有就查找外部的
3.注意声明变量是用var还是没有写(没有写默认window.)
4.注意:js有变量提升的机制【变量悬挂声明】
function fun(){ // var str; 你看不到的,是js独有的机制console.log(str); // undefinedvar str = '你好吗?'console.log(str); // 你好吗? }
5.优先级:声明变量 > 声明普通函数 > 参数 > 变量提升
面试的时候怎么看:
1.本层作用域有没有此变量【注意变量提升】
2.注意:js除了函数外没有块级作用域
3.普通声明函数是不看写函数的顺序
考题1:
function c(){var b = 1;function a(){ // 注意,此处有变量提升 var b;console.log(b);var b = 2;console.log(b);}a();console.log(b); }c();----------------- 运行结果: undefined 2 1
考题2:
var name = 'a'; (function(){ // var name;if(typeof name == 'undefined'){var name = 'b';console.log('111'+name);}else{console.log('222'+name);}})----------------- 得到的结果都是: 111b
<script type="text/javascript>javascript"> // var a;console.log(a); if(false){var a = 10; } console.log(a) </script>---------------------- undefined undefined
考题3:
var bar = 1; function test(){ // var bar;console.log(bar); // undefinedvar bar = 2;console.log(bar); // 2 } test()-------------------- undefined 2
考题4:
function fun(a){var a = 10;function a(){}console.log(a); } fun(100);
8.JS对象考题
JS对象注意点:
1.对象是通过new操作符构建出来的,所以对象之间不相等
2.对象注意:引用类型
3.对象的key都是字符串类型
4.对象如何找属性|方法
先在对象本身找 ===> 构造函数中找 ===> 对象原型中找 ===> 构造函数原型中找 ===> 对象上一层原型找
考题1:
[1,2,3] === [1,2,3] // false
考题2:var arr1 = [1,2,3] var arr2 = arr1; console.log(arr1 === arr2) // true
考题3:
var obj1 = {a:'hello' } var obj2 = obj1; obj2.a = 'world'; console.log(obj1); // {a:world} (function(){console.log(a); // undefinedvar a = 1; })();
考题4:
var a = {} var b = {key:'a' } var c = {key:'c' }a[b] = '123' a[c] = '456' console.log(a[b]); // '456'
考题5:
1.每一个函数都自带一个prototype【原型】
注意:对象拥有__proto__
2.new Fun 该Fun构造函数的原型指向于对象(new Fun)的原型
function Fun(){this.a = '在Fun函数中添加的'; // 2 } Fun.prototype.a = '这是Fun原型添加的'; // 4 let obj = new Fun(); // var obj.a; undefined // 6 obj.a = '对象本身'; // 1 obj.__proto__.a = '这是对象原型添加的'; // 3Object.a = '这是Object添加的'; // 5 console.log(obj.a);