defer : 等html全部解析完成,才会执行js代码,顺次执行js脚本。async : async是和html解析同步的(一起的),不是顺次执行js脚本(谁先加载完谁先执行)。二、JS数据类型有哪些?基本类型:string、num............._js高级面试题">
赞
踩
延迟加载:async、defer
defer : 等html全部解析完成,才会执行js代码,顺次执行js脚本。
async : async是和html解析同步的(一起的),不是顺次执行js脚本(谁先加载完谁先执行)。
基本类型:string、number、boolean、undefined、null、symbol、bigint
引用类型:object
NaN是一个数值类型,但是不是一个具体的数字。
- console.log( true + 1 ); //2
- console.log( 'name'+true ); //nametrue
- console.log( undefined + 1 ); //NaN
- console.log( typeof undefined ); //undefined
- console.log( typeof(NaN) ); //number
- console.log( typeof(null) ); //object
1. 作者在设计js的都是先设计的null(为什么设计了null:最初设计js的时候借鉴了java的语言)
2. null会被隐式转换成0,很不容易发现错误。
3. 先有null后有undefined,出来undefined是为了填补之前的坑。
具体区别:JavaScript的最初版本是这样区分的:null是一个表示"无"的对象(空对象指针),转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。
== : 比较的是值
string == number || boolean || number ....都会隐式转换
通过valueOf转换(valueOf() 方法通常由 JavaScript 在后台自动调用,并不显式地出现在代码中。)=== : 除了比较值,还比较类型
1. js是单线程的语言。
2. js代码执行流程:同步执行完==》事件循环
同步的任务都执行完了,才会执行事件循环的内容
进入事件循环:请求、定时器、事件....
3. 事件循环中包含:【微任务、宏任务】
微任务:promise.then
宏任务:setTimeout..
要执行宏任务的前提是清空了所有的微任务
流程:同步==》事件循环【微任务和宏任务】==》微任务==》宏任务=》微任务...
1. 除了函数外,js是没有块级作用域。
2. 作用域链:内部可以访问外部的变量,但是外部不能访问内部的变量。
注意:如果内部有,优先查找到内部,如果内部没有就查找外部的。
3. 注意声明变量是用var还是没有写(window.)
4. 注意:js有变量提升的机制【变量悬挂声明】
5. 优先级:声明变量 > 声明普通函数 > 参数 > 变量提升
- function c(){
- var b = 1;
- function a(){
- console.log( b );
- var b = 2;
- console.log( b );
- }
- a();
- console.log( b );
- }
- c();
- var name = 'a';
- (function(){
- if( typeof name == 'undefined' ){
- var name = 'b';
- console.log('111'+name);
- }else{
- console.log('222'+name);
- }
- })()
- function fun( a ){
- var a = 10;
- function a(){}
- console.log( a );
- }
-
- fun( 100 );
JS对象注意点:
1. 对象是通过new操作符构建出来的,所以对象之间不想等(除了引用外);
2. 对象注意:引用类型(共同一个地址);
3. 对象的key都是字符串类型;
4. 对象如何找属性|方法;
查找规则:先在对象本身找 ===> 构造函数中找 ===> 对象原型中找 ===> 构造函数原型中找 ===> 对象上一层原型查找
[1,2,3] === [1,2,3] //false
- var obj1 = {
- a:'hellow'
- }
- var obj2 = obj1;
- obj2.a = 'world';
- console.log(obj1); //{a:world}
- (function(){
- console.log(a); //undefined
- var a = 1;
- })();
- var a = {}
- var b = {
- key:'a'
- }
- var c = {
- key:'c'
- }
-
- a[b] = '123';
- a[c] = '456';
-
- console.log( a[b] ); // 456
- function Foo(){
- getName = function(){console.log(1)} //注意是全局的window.
- return this;
- }
-
- Foo.getName = function(){console.log(2)}
- Foo.prototype.getName = function(){console.log(3)}
- var getName = function(){console.log(4)}
- function getName(){
- console.log(5)
- }
-
- Foo.getName(); //2
- getName(); //4
- Foo().getName(); //1
- getName(); //1
- new Foo().getName();//3
- var o = {
- a:10,
- b:{
- a:2,
- fn:function(){
- console.log( this.a ); // 2
- console.log( this ); //代表b对象
- }
- }
- }
- o.b.fn();
- window.name = 'ByteDance';
- function A(){
- this.name = 123;
- }
- A.prototype.getA = function(){
- console.log( this );
- return this.name + 1;
- }
- let a = new A();
- let funcA = a.getA;
- funcA(); //this代表window
- var length = 10;
- function fn(){
- return this.length + 1;
- }
- var obj = {
- length:5,
- test1:function(){
- return fn();
- }
- }
- obj.test2 = fn;
- console.log( obj.test1() ); //1
- console.log( fn()===obj.test2() ); //false
- console.log( obj.test1() == obj.test2() ); //false
- var arr = [1,2,3];
- console.log( Array.isArray( arr ) );
- var arr = [1,2,3];
- console.log( arr instanceof Array );
- var arr = [1,2,3];
- console.log( Object.prototype.toString.call(arr).indexOf('Array') > -1 );
- var arr = [1,2,3];
- console.log( Array.prototype.isPrototypeOf(arr) )
- var arr = [1,2,3];
- console.log( arr.constructor.toString().indexOf('Array') > -1 )
1. slice是来截取的
2. splice 功能有:插入、删除、替换
- var arr1 = [1,2,3,2,4,1];
- function unique(arr){
- return [...new Set(arr)]
- }
- console.log( unique(arr1) );
- var arr2 = [1,2,3,2,4,1];
- function unique( arr ){
- var brr = [];
- for( var i=0;i<arr.length;i++){
- if( brr.indexOf(arr[i]) == -1 ){
- brr.push( arr[i] );
- }
- }
- return brr;
- }
- console.log( unique(arr2) );
- var arr3 = [1,2,3,2,4,1];
- function unique( arr ){
- arr = arr.sort();
- var brr = [];
- for(var i=0;i<arr.length;i++){
- if( arr[i] !== arr[i-1]){
- brr.push( arr[i] );
- }
- }
- return brr;
- }
- console.log( unique(arr3) );
- function fnArr(arr){
- var newArr = [];
- arr.forEach((item,index)=>{
- newArr.push( Math.max(...item) )
- })
- return newArr;
- }
- console.log(fnArr([
- [4,5,1,3],
- [13,27,18,26],
- [32,35,37,39],
- [1000,1001,857,1]
- ]));
给字符串对象定义一个addPrefix函数,当传入一个字符串str时,它会返回新的带有指定前缀的字符串,例如:
console.log( 'world'.addPrefix('hello') ) 控制台会输出helloworld
- String.prototype.addPrefix = function(str){
- return str + this;
- }
- console.log( 'world'.addPrefix('hello') )
- var str = 'aaasdwqeasdaqwd';
- var o = {};
- for (var i = 0; i < str.length; i++) {
- var index = str[i];
- if (!o[index]) {
- o[index] = 1;
- } else {
- o[index]++;
- }
- }
-
- var max = 0;
- var str1 = '';
- for (var k in o) {
- if (o[k] > max) {
- max = o[k];
- str1 = k;
- }
- }
-
- console.log('出现最多的次数:' + max + '及其字母为:' + str1);
1. 闭包是什么
闭包是一个函数加上到创建函数的作用域的连接,闭包“关闭”了函数的自由变量。
优点:
缺点:会增大内存使用量,滥用闭包会影响性能,导致内存泄漏【如果说一定要提到ie】等问题。
解决方法:在退出函数之前,将不使用的局部变量全部删除,可以使变量赋值为null。
2. 什么是垃圾?
垃圾回收机制:
执行环境负责管理代码执行过程中使用的内存。JS的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,没有被释放,导致该内存无法被使用,垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。
1. 原型可以解决什么问题
2. 谁有原型
3. 对象查找属性或者方法的顺序
4. 原型链
4.1 是什么?:就是把原型串联起来
4.2 原型链的最顶端是null
- class Parent{
- constructor(){
- this.age = 18;
- }
- }
-
- class Child extends Parent{
- constructor(){
- super();
- this.name = '张三';
- }
- }
- let o1 = new Child();
- console.log( o1,o1.name,o1.age );
- function Parent(){
- this.age = 20;
- }
- function Child(){
- this.name = '张三'
- }
- Child.prototype = new Parent();
- let o2 = new Child();
- console.log( o2,o2.name,o2.age );
- function Parent(){
- this.age = 22;
- }
- function Child(){
- this.name = '张三'
- Parent.call(this);
- }
- let o3 = new Child();
- console.log( o3,o3.name,o3.age );
- function Parent(){
- this.age = 100;
- }
- function Child(){
- Parent.call(this);
- this.name = '张三'
- }
- Child.prototype = new Parent();
- let o4 = new Child();
- console.log( o4,o4.name,o4.age );
共同点:功能一致
可以改变this指向
语法: 函数.call()、函数.apply()、函数.bind()
区别:
场景:
- 1. 用apply的情况
- var arr1 = [1,2,4,5,7,3,321];
- console.log( Math.max.apply(null,arr1) )
-
- 2. 用bind的情况
- var btn = document.getElementById('btn');
- var h1s = document.getElementById('h1s');
- btn.onclick = function(){
- console.log( this.id );
- }.bind(h1s)
V8 引擎 sort 函数只给出了两种排序 InsertionSort 和 QuickSort,数量小于10的数组使用 InsertionSort,比10大的数组则使用 QuickSort。
之前的版本是:插入排序和快排,现在是冒泡
原理实现链接:https://github.com/v8/v8/blob/ad82a40509c5b5b4680d4299c8f08d6c6d31af3c/src/js/array.js
***710行代码开始***
共同点:复制
1. 浅拷贝:只复制引用,而未复制真正的值。
- var arr1 = ['a','b','c','d'];
- var arr2 = arr1;
-
- var obj1 = {a:1,b:2}
- var obj2 = Object.assign(obj1);
2. 深拷贝:是复制真正的值 (不同引用)
- var obj3 = {
- a:1,
- b:2
- }
- var obj4 = JSON.parse(JSON.stringify( obj3 ));
//递归的形式
- var oldObj = {
- a: 1,
- b: 2,
- arr: ['1', '2', '3']
- };
- var newObj = {};
-
- function recursion(newObj, oldObj) {
- for (var k in oldObj) {
- var item = oldObj[k];
- if (item instanceof Array) {
- newObj[k] = [];
- recursion(newObj[k], item);
- } else if (item instanceof Object) {
- newObj[k] = {};
- recursion(newObj[k], item);
- } else {
- newObj[k] = item;
- }
- }
- return newObj;
- }
- recursion(newObj, oldObj);
- newObj.a = '我是你爸爸真伟大'
- console.log(newObj);
- console.log(oldObj);
公共点:在客户端存放数据
区别:
1. 数据存放有效期
2. localStorage、sessionStorage不可以设置过期时间
3. 存储大小的限制
****根据不同的浏览器存储的大小是不同的。
共同点:限制函数的执行次数
防抖:通过setTimeout的方式,在一定的时间间隔内,将多次触发只执行最后一次触发;
节流:减少一段时间的触发频率
var、let、const 共同点都是可以声明变量的
区别一:
区别二:
区别三:
区别四:
考题一:let和const没有变量提升性
- console.log( str );//undefined
- var str = '你好';
-
- console.log( num );//报错
- let num = 10;
考题二:
- function demo(){
- var n = 2;
- if( true ){
- var n = 1;
- }
- console.log( n );//1
- }
- demo();
-
-
- function demo(){
- let n = 2;
- if( true ){
- let n = 1;
- }
- console.log( n );//2
- }
- demo();
考题三:可以修改
- const obj = {
- a:1
- }
- obj.a = 11111;
- console.log( obj )
-
- const arr = ['a','b','c'];
- arr[0]= 'aaaaa';
- console.log( arr );
方式一:Object.assign
- const a = {a:1,b:4};
- const b = {b:2,c:3};
-
- let obj1 = Object.assign(a,b);
- console.log( obj1 );
方式二:...
- let obj2 = {...a,...b};
- console.log( obj2 );
方式三:自己封装方法
- function extend( target, source ){
- for(var key in source){
- target[key] = source[key];
- }
- return target;
- }
- console.log( extend(a,b) );
1. this指向的问题
2. 箭头函数不能new(不能当作构造函数)
3. 箭头函数prototype
4. 箭头函数arguments
有三种状态:
Promise 是es6引入的异步编程解决方案
可以链式调用,解决回调地狱的问题
三十一、find和filter的区别
区别一:返回的内容不同
区别二:
- function fb(n) {
- if (n == 0) {
- return 0;
- }
- if (n <= 2) {
- return 1;
- }
- return fb(n - 1) + fb(n - 2);
- }
- console.log(fb(9));
- function fn(n) {
- if (n == 1) {
- return 1;
- }
- return n * fn(n - 1);
- }
- console.log(fn(3));
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。