面试试题2

闭包

闭包应用场景:防抖,节流,库的封装,保证数据的私有性,可避免变量被污染

可以避免变量被污染

私有化

(function(){
	let a =2;
    let b = 3;
    function a(){
    }
    return{
		a
    }
})

外部可以访问到但是不能修改里面的内容,和外面的不会冲突

保存变量,常驻内存,延长变量的声明周期

let a = "xx"

在script里面

function fn(){
	let b = 1
}

而b在local里面

AO是一个临时变量对象,在程序执行完后,会被垃圾回收机制回收,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AhdbhbG5-1634197814122)(F:%5Ctypora%5Cimage%5Cimage-20210914151156196.png)]

直接调用闭包里面的changeBy()方法是不能访问会报错,访问c1的privateCounter也是undefined,保证了数据的私有性

要调用return里面的方法才对,

在这里插入图片描述

控制台返回2

new关键字

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1tikFb5h-1634197814126)(F:%5Ctypora%5Cimage%5Cimage-20210914151734273.png)]

new完之后,这个函数才是构造函数

person1.fn()

控制台输出…

下面的创建空对象有何区别
  1. 创建一个空对象,let obj = Object.Create(null)

    没有原型链 _ proto _

  2. let obj2 = {}

    有原型链

只是用来保存某些值,不去调用原型链的方法,用第一种方法, 效率高,

new的一瞬间做了什么事情

1创建一个空对象

let obj = new Object();//称之为基类

或是let obj = {}

2设置原型链

obj. _ proto _ = Person.prototype

指向构造函数的原型

3改变this的指向

let result = Person.call(obj)

让结果指向object

4判断返回值类型

if(typeof (result)==“object”){

​ person1 = result//如果是引用类型,就返回引用类型的对象,默认情况下函数返回undefined,但是在构造函数里面默认返回新创建的对象

}else{

​ person1 = obj

}

事件委托

事件发身在谁的身上,就给谁添加委托,

nodeName

原始值和引用值类型及区别

原始值是存储在栈中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。

包含简单数据类型:undefined、null、symbol、boolean、number 和 string ;可以通过typeof 运算符来判断一个值是否在某种类型的范围内,如果它是原始类型,还可以判断它表示哪种原始类型。

引用值存储在堆中的对象,放在变量的栈空间中的值是该对象存储在堆中的地址,也就是说,存储在变量处的值是一个指针(内存地址),指向存储对象的堆内存中。

包含:Object、function、array等。

区别:简单数据类型的值是储存在栈中,当把一个变量传递给另一个变量时,是把一个栈中的东西复制到另一个到栈中,并且这两个变量互不影响,修改其中的变量值时,不会改变另外一个变量的结果。

复杂数据类型是把引用变量的名称(内存地址)存储在栈中,但是把其实际对象存储在堆中,栈中的内存地址指向堆中的实际对象,当把引用对象传递给另一个变量时,复制的其实是指向实际对象的指针(内存地址),此时两者指向的是同一个数据,若通过方法改变其中一个变量的值,则访问另一个变量时,其值也会跟着改变, 因为JavaScript 中对象的赋值是默认引用赋值的。

js延迟加载方式
  • defer和async
  • 动态创建DOM,创建script,插入DOM中,加载完后callback
  • 异步载入js
跨域问题解决

jsonp

document.domain+iframe

window.name、window.postMessage

服务器设置代理页面

双飞翼布局和圣杯布局

typeof的使用
	typeof Symbol()
	//Symbol
	typeof ''
	//String
	typeof true
	//boolean
	typeof 1
	//number
	typeof new Function()
	//function
	typeof undefined
	//undefined


	typeof null
	//object失效
    typeof []
	//object失效
	typeof new Date()
	//object无效
	typeof new RegExp()
	//object无效

Object.prototype.toString.call()

在JS中,可以通过Object.prototype.toString方法,判断某个对象之属于哪种内置类型。

	Object.prototype.toString.call(null)//[object Null]
	Object.prototype.toString.call(undefined); //[object Undefined]
	Object.prototype.toString.call(“abc”);//[object String]
	Object.prototype.toString.call(123);//[object Number]
	Object.prototype.toString.call(true);//[object Boolean]

	Function fn(){
  		console.log(“test”);
	}
	Object.prototype.toString.call(fn);//[object Function]
	var date = new Date();
	Object.prototype.toString.call(date); //[object Date]
	var arr = [1,2,3];
	Object.prototype.toString.call(arr); //[object Array]
	var reg = /[hbc]at/gi;
	Object.prototype.toString.call(reg); //[object RegExp]
	
	function Person(name, age) {
    	this.name = name;
    	this.age = age;
	}
	var person = new Person("Rose", 18);
	Object.prototype.toString.call(person); //[object Object]

而Object.prototype.toString.call()不能准确判断person是Person的实例,要用instanceof来进行判断,

	console.log(person instanceof Person); // true
constructor 的缺点

无法检测null和undefined,不稳定,

	var aa=[1,2];
	console.log(aa.constructor===Array);//true
	console.log(aa.constructor===RegExp);//false
	console.log((1).constructor===Number);//true
浏览器的本地存储

sessionStorage和localStorage

sessionStorage用于存储会话中的数据,这些数据只是用在同一个会话的页面才能,当会话结束数据随之销毁,sessionStorage不是一种持久化的本地存储, 仅仅是会话级别的存储

localStorage用于持久化的本地存储,除非主动删除数据

Cookie

cookie是以小的文本文件形式完全存储在客户端,服务器知道正在和哪个客户端通信,以及保持与已识别出的客户端通信。cookie的最大为4k,

会话cookie记录用户访问站点的设置和偏好,退出浏览器会话cookie会被删除

持久cookie存储在硬盘,维护某个用户周期性访问的站点的配置文件或登录名

原理:首次访问web站点,服务器通过set-cookie首部将cookie(包含多个键值对)存放到cookie数据库中,后面用户再次访问同一站点,浏览器会将键值对来查找服务器为其访问积累的信息

每次访问网站,浏览器通常每次只向网站发送2-3个cookie,所有cookie进行传输会降低性能,而且会引发隐私问题

一般cookie缓存图片

Cookie数量和长度的限制,有些状态不可能保存在客户端

数组和类数组

数组和类数组都可用下标访问每个元素,都有length属性。

数组对象的类型是Array,

类数组对象的类型是object,

数组遍历可以用 for in和for循环,

类数组只能用for循环遍历。

数组转换为类数组
	var arr = [1, 2, 3, 4];
	var obj = { };
	[].push.apply(obj, arr);
	console.log(obj);
	//输出为原型为Object 的一个对象

在这里插入图片描述

类数组转换为数组

方法一

Array.prototype.slice.call(arrayLike,start);

在这里插入图片描述

方法二 Array.from(arrayLike)

在这里插入图片描述

在这里插入图片描述

方法三 扩展运算符(…)

在这里插入图片描述

JS七大原始数据基本类型

Boolean,null,undefined,number,string,symbol,bigint

引用数据类型

对象Object,普通对象object,数组对象array,正则对象regexp,日期对象date,数学函数math,函数对象function

null不是对象

虽然 typeof null 会输出 object,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象然而 null 表示为全零,所以将它错误的判断为 object

‘1’.toString()为什么可以调用

在这个语句运行的过程中做了下面几件事情

var s = new Object(‘1’)

s.toString()

s=null

而1.toString()会报错

小数点会被认为带有小数的数字整体,应该加一个空格或是加括号

内存泄漏

任何对象在不需要之后仍然存在

垃圾回收机制,计算引用每个对象的其他对象的数量,引用数量为0或是只引用了循环,该对象的内存会被回收

setTimeout的第一个参数是字符串,闭包,控制台日志,循环,都会造成内存泄漏

JavaScript提供了数据类型和访问器属性两类
数据类型

value属性的值

writable 决定属性能否被赋值

enumerable决定for in能否枚举该属性

configurable决定该属性能否被删除或者改变特征值

访问器属性

getter,函数或undefined,取属性值时被调用

setter,函数或undefined,设置属性值时被调用

装箱转换

a+b

先检测对象是否存在valueOf方法,若有返回原始类型,使用该值进行强制类型转换;valueOf没有返回原始类型,就用toString方法的返回值,,如果valueOf和toString都不返回,触发TypeError错误

在执行1+'2’的过程中,执行了装箱转换

Number(1).toString()+‘2’

如果没有如果其中一项是字符串,v8默认将另外一个值转换为字符串

[]+[]会被隐式调用toString()方法,一个[]转换为原始值’’

{}+{}会被隐式调用toString()方法,一个{}转换为原始值"[object object]"

[]==0返回true,![]==0返回true,!![]返回true

[]==![]返回true

[]转换为数字为0,[]转换为布尔值true,![]则为false,转换为数字为0,0 == 0,结果为true

BigInt

在数字末尾追加n即可

也可以创建BigInt()构造函数

BigInt(“9007199254740995”); // → 9007199254740995n

BigInt不支持一元加号运算符

不允许在bigint和 Number 之间进行混合操作

不能将BigInt传递给Web api和内置的 JS 函数

Number

toString()返回数值对象的字符串

valueOf()返回原始数值

toFixed(n)返回包含指定小数位数的字符串

toExponential(n)返回科学计数法的字符串

toPrecision()返回数值最恰当形式

Number.isFinite()检查数值是否有限,不是数值返回false

Number.isNaN()检查是否为NaN,不是NaN返回false

Number.parseInt()和Number.parseFloat()

Number.isInteger()判断是否为整数,不是数值返回false

Math对象的常用方法

undefined转为数值为NaN,null转为数值为0

字符串

‘abc’+{

value:10,

toString: function(){

​ return this.value.toString();

​ }

}

结果为’abc10’

String()

indexOf(),返回指定某个字符串值在字符串首次出现的位置,区分大小写

数组

创建数组方法:

  • 数组字面量
    • let count = [1,2,3]
  • 构造函数Array()
    • let a1 = new Array()

数组长度length可以用Object.defineProperty()来改成只读

arr.push(n),原数组末尾增加指定元素

arr.unshift(n),原数组开头增加指定元素

arr.delete(n),删除原数组下标为n的元素

arr.pop(n),删除原数组末尾元素

arr.shift(n),删除原数组开头元素

arr.splice(a,b,c),在下标为a的位置,删除b个元素,添加元素c,

  • a可以为负值,b可以为0即不删除,c可以为多个元素

  • b和c为0,从a开始删除后面所有元素

arr.join(),将数组转换为字符串,默认逗号分割,arr.join("-"),按-分割

arr.reverse(),颠倒数组元素的顺序

arr.sort(),排序数组元素,按照字母表顺序排

arr.concat(m,n),返回一个新的数组,m和n可以是元素也可以是数组

arr.slice(a,b),返回指定数组下标为a到b-1的元素,如果b大于数组长度或是b省略,会提取到原数组的末尾

arr.includes(a),判断数组是否包含指定的值,有则返回true

arr.filter(function(a)),传进一个参数a,根据方法,返回一个新的数组,

arr.indexOf(),返回指定某个值在数组首次出现的位置,区分大小写

构造函数方法

Array.from(),将可遍历的对象或是类似数组的对象转为真正数组

Array.of(),将数值转换为数组

数组去重:

return […new Set(arr)]

数组去重[https://segmentfault.com/a/1190000016418021]

四种遍历语法

for循环

forEach

  • 回调参数分别为value,index,array,缺点在于无法中途跳出

for…in

  • 用于遍历可枚举属性,功能类似于Object.keys(),遍历不到constructor和length属性,主要用于遍历对象而设计,不适用与遍历数组

for…of

  • ES6新增,提供了所有数据结构的统一操作接口
  • entries()返回一个遍历器对象,用于遍历[键名,键值]组成的数组,对于Set,键名和键值相同,对于Map,Iterator接口,默认entries方法
  • keys()返回遍历器对象,遍历所有键名
  • values()返回遍历器对象,遍历所有键值

不是所有类似数组的对象都有Iterator接口,用Array.from()方法将其转换为数组

普通的对象必须要部署接口后才能使用,用for…in可以,用for…of必须加上Object.keys(obj)方法。

let a = {a:1,b:2,c:“3”}

for(let key of Object.keys(a)){
console.log(e,a[key])
}

json字符串转json对象

JSON.parse()

json对象转为json字符串

JSON.stringify()

obj.toJSONString()

json字符数组转为json数组

JSON.parse()

ajax的过程

创建XMLHttpRequest对象/异步调用对象

创建新的HTTP请求,指定方法URL和验证信息

设置响应HTTP请求状态变化的函数

发送HTTP请求

获取异步调用返回的数据

使用js和DOM实现局部刷新

异步加载

动态插入script标签

通过ajax获取js代码通过eval执行

script标签添加defer后async属性

创建并插入iframe,异步执行js

正则表达式

范围类[a-z0-9-]表示a到z和0-9和-的之间的任意字符

元字符1,匹配不属于abc的字符

  • . (点),除了回车符和换行符的所有字符

  • \d,[0-9]数字字符

  • \D,[ ^0-9],非数字字符

  • \s,[\t\n\x0b\f\r],空白符,\f换页符,\r回车符,\t水平制表符,\n换行符,\x0b垂直制表符

  • \S,[ ^\t\n\x0b\f\r],非空白符

  • \w, [a-zA-Z_0-9],单词字符,字母数字下划线

  • \W,[ ^a-zA-Z_0-9],非单词字符

  • ^ 以xxx开始,$ 以xxx结束,\b,单词边界,\B,非单词边界

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VlkGmeOq-1634197814130)(F:/typora/image/image-20211004154228636.png)]

  • {n},出现 n 次

  • {n, m},出现 n 到 m 次

  • {n,},出现 n 次或更多次

贪婪模式——尽可能多的匹配

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T387HUKD-1634197814133)(F:/typora/image/image-20211004154635873.png)]

非贪婪模式——尽可能少的匹配

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vLDmpvE5-1634197814134)(F:/typora/image/image-20211004154954602.png)]

分组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M0pEkP2r-1634197814135)(F:/typora/image/image-20211004154946697.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pm2tlQ1V-1634197814136)(F:/typora/image/image-20211004155128830.png)]

反向引用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gp0NM2iV-1634197814137)(F:/typora/image/image-20211004155322818.png)]

变量提升/预处理

console.log(username)//undefined

var username=‘11’

而函数可以

//执行上下文/EC

eval是什么?

把对应的字符串解析成js代码并运行

避免使用eval,不安全,耗能

原型链,原型对象

原型链是用来继承和共享属性的对象组成的对象链

原型对象是对象自带的隐式的_ proto _属性,如果原型对象的原型不是null,就是原型链

js阻止冒泡

ev.stopPropagation()

Ajax

优化浏览器和服务器之间的传输,减少不必要的数据往返,减少带宽,可以通过异步模式,提升用户体验

ajax对搜索引擎支持比较弱,安全问题,不容易调试

如何解决跨域问题?

jsonp

回调执行函数,handleCallback()

跨域资源共享,CORS,

获取UA
function whatBrowser() {  
  document.Browser.Name.value=navigator.appName;  
  document.Browser.Version.value=navigator.appVersion;  
  document.Browser.Code.value=navigator.appCodeName;  
  document.Browser.Agent.value=navigator.userAgent;  
}
eventloop
  • macro-task(宏任务)
    • setTimeout
    • setInterval
    • set Immediate
  • micro-task(微任务)
    • Promise
    • process.nextTick
改变this指向
  1. apply

    function bindThis(f, oTarget) {
     return function() {
         return f.apply(oTarget, arguments)
     }
    }
    
  2. bind

    function bindThis(f, oTarget) {
     return f.bind(oTarget)
    }
    
  3. call

    function bindThis(f, oTarget) {
     return function() {
         return f.call(oTarget, ...arguments)
     }
    }
    

lue=navigator.appVersion;
document.Browser.Code.value=navigator.appCodeName;
document.Browser.Agent.value=navigator.userAgent;
}




#### eventloop

- macro-task(宏任务)
  - setTimeout
  - setInterval
  - set Immediate
- micro-task(微任务)
  - Promise
  - process.nextTick

#### 改变this指向

1. apply

   ```js
   function bindThis(f, oTarget) {
    return function() {
        return f.apply(oTarget, arguments)
    }
   }
  1. bind

    function bindThis(f, oTarget) {
     return f.bind(oTarget)
    }
    
  2. call

    function bindThis(f, oTarget) {
     return function() {
         return f.call(oTarget, ...arguments)
     }
    }
    

  1. ^abc ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值