i.im com_i.im com查找手机怎么可以错过
来吧,再复习下
引言Javascript是前端面试的重点,本文重点梳理下 Javascript 中的常考基础知识点,然后就一些容易出现的题目进行解析限于文章的篇幅,无法将知识点讲解的面面俱到,本文只罗列了一些重难点,如果想要了解更多内容欢迎点击。
https://github.com/ljianshu/Blog一、变量类型1.JS 的数据类型分类根据 JavaScript 中的变量类型传递方式,分为基本数据类型和引用数据类型其中基本数据类型包括Undefined、Null、Boolean、Number、String、Symbol (ES6新增,表示独一无二的值),而引用数据类型统称为Object对象,主要包括对象、数组和函数。
在参数传递方式上,有所不同:函数的参数如果是简单类型,会将一个值类型的数值副本传到函数内部,函数内部不影响函数外部传递的参数变量如果是一个参数是引用类型,会将引用类型的地址值复制给传入函数的参数,函数内部修改会影响传递参数的引用对象。
题目:基本类型和引用类型的区别基本类型和引用类型存储于内存的位置不同,基本类型直接存储在栈中,而引用类型的对象存储在堆中,与此同时,在栈中存储了指针,而这个指针指向正是堆中实体的起始位置下面通过一个小题目,来看下两者的主要区别:。
// 基本类型var a =10var b = ab =20console.log(a)// 10console.log(b)// 20上述代码中,a b都是值类型,两者分别修改赋值,相互之间没有任何影响。
再看引用类型的例子:// 引用类型var a ={x:10, y:20}var b = ab.x =100b.y =200console.log(a)// {x: 100, y: 200}console
.log(b)// {x: 100, y: 200}上述代码中,a b都是引用类型在执行了b = a之后,修改b的属性值,a的也跟着变化因为a和b都是引用类型,指向了同一个内存地址,即两者引用的是同一个值,因此b修改属性时,a的值随之改动。
2.数据类型的判断1)typeoftypeof返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、symbol、object、undefined、function等7种数据类型,但不能判断null、array等
typeofSymbol();// symbol 有效typeof;// string 有效typeof1;// number 有效typeoftrue;//boolean 有效typeofundefined
;//undefined 有效typeofnewFunction();// function 有效typeofnull;//object 无效typeof[];//object 无效typeofnewDate
();//object 无效typeofnewRegExp();//object 无效2)instanceofinstanceof 是用来判断A是否为B的实例,表达式为:A instanceof B,如果A是B的实例,则返回true,否则返回false。
instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性,但它不能检测null 和 undefined[]instanceofArray;//true{}
instanceofObject;//truenewDate()instanceofDate;//truenewRegExp()instanceofRegExp//truenullinstanceofNull
//报错undefinedinstanceofundefined//报错3)constructorconstructor作用和instanceof非常相似但constructor检测 Object与instanceof不一样,还可以处理基本数据类型的检测。
不过函数的 constructor 是不稳定的,这个主要体现在把类的原型进行重写,在重写的过程中很有可能出现把之前的constructor给覆盖了,这样检测出来的结果就是不准确的4)Object.prototype.toString.call()。
Object.prototype.toString.call() 是最准确最常用的方式Object.prototype.toString.call();// [object String]Object.
prototype.toString.call(1);// [object Number]Object.prototype.toString.call(true);// [object Boolean]
Object.prototype.toString.call(undefined);// [object Undefined]Object.prototype.toString.call(null);// [object Null]
Object.prototype.toString.call(newFunction());// [object Function]Object.prototype.toString.call(newDate
());// [object Date]Object.prototype.toString.call([]);// [object Array]Object.prototype.toString.call
(newRegExp());// [object RegExp]Object.prototype.toString.call(newError());// [object Error]3.浅拷贝与深拷贝
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存浅拷贝的实现方式(详见https://github.com/ljianshu/Blog/issues/5):Object.assign():需注意的是目标对象只有一层的时候,是深拷贝。
Array.prototype.concat()Array.prototype.slice()深拷贝就是在拷贝数据的时候,将数据的所有引用结构都拷贝一份简单的说就是,在内存中存在两个数据结构完全相同又相互独立的数据,将引用型类型进行复制,而不是只复制其引用关系。
深拷贝的实现方式:热门的函数库lodash,也有提供_.cloneDeep用来做深拷贝jquery 提供一个$.extend可以用来做深拷贝JSON.parse(JSON.stringify())手写递归方法
递归实现深拷贝的原理:要拷贝一个数据,我们肯定要去遍历它的属性,如果这个对象的属性仍是对象,继续使用这个方法,如此往复//定义检测数据类型的功能函数function checkedType(target。
){returnObject.prototype.toString.call(target).slice(8,-1)}//实现深度克隆---对象/数组function clone(target){//判断拷贝的数据类型
//初始化变量result 成为最终克隆的数据let result, targetType = checkedType(target)if(targetType === Object ){ result
={}}elseif(targetType === Array ){ result =[]}else{return target}//遍历目标数据for(let i in target){//获取遍历数据结构的每一项值。
let value = target[i]//判断目标结构里的每一值是否存在对象/数组if(checkedType(value)=== Object || checkedType(value)=== Array
){//对象/数组里嵌套了对象/数组//继续遍历获取到value值 result[i]= clone(value)}else{//获取到value值是基本的数据类型或者是函数 result。
[i]= value}}return result}二、作用域和闭包1.执行上下文和执行栈执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念, JavaScript 中运行任何的代码都是在执行上下文中运行。
执行上下文的生命周期包括三个阶段:创建阶段→执行阶段→回收阶段,我们重点介绍创建阶段创建阶段(当函数被调用,但未执行任何其内部代码之前)会做以下三件事:创建变量对象:首先初始化函数的参数arguments,提升函数声明和变量声明。
创建作用域链:下文会介绍确定this指向:下文会介绍function test(arg){// 1. 形参 arg 是 "hi"// 2. 因为函数声明比变量声明优先级高,所以此时 arg 是 function
console.log(arg);var arg = hello ;// 3.var arg 变量声明被忽略, arg = hello 被执行function arg(){ console
.log( hello world )} console.log(arg);}test( hi );/* 输出:function arg() { console.log( hello world );
}hello*/这是因为当函数执行的时候,首先会形成一个新的私有的作用域,然后依次按照如下的步骤执行:如果有形参,先给形参赋值进行私有作用域中的预解释,函数声明优先级比变量声明高,最后后者会被前者所覆盖,但是可以重新赋值
私有作用域中的代码从上到下执行函数多了,就有多个函数执行上下文,每次调用函数创建一个新的执行上下文,那如何管理创建的那么多执行上下文呢?JavaScript 引擎创建了执行栈来管理执行上下文可以把执行栈认为是一个存储函数调用的栈结构,遵循先进后出的原则。
。
从上面的流程图,我们需要记住几个关键点:JavaScript执行在单线程上,所有的代码都是排队执行一开始浏览器执行全局的代码时,首先创建全局的执行上下文,压入执行栈的顶部每当进入一个函数的执行就会创建函数的执行上下文,并且把它压入执行栈的顶部。
当前函数执行完成后,当前函数的执行上下文出栈,并等待垃圾回收浏览器的JS执行引擎总是访问栈顶的执行上下文全局上下文只有唯一的一个,它在浏览器关闭时出栈2.作用域与作用域链ES6 到来JavaScript 有全局作用域、函数作用域和块级作用域(ES6新增)。
我们可以这样理解:作用域就是一个独立的地盘,让变量不会外泄、暴露出去也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突在介绍作用域链之前,先要了解下自由变量,如下代码中,console.log(a)要得到a变量,但是在当前的作用域中没有定义a(可对比一下b)。
当前作用域没有定义的变量,这成为 自由变量var a =100function fn(){var b =200 console.log(a)// 这里的a在这里就是一个自由变量 console
.log(b)}fn()自由变量的值如何得到 —— 向父级作用域(创建该函数的那个父级作用域)寻找如果父级也没呢?再一层一层向上寻找,直到找到全局作用域还是没找到,就宣布放弃这种一层一层的关系,就是作用域链 。
function F1(){var a =100returnfunction(){ console.log(a)}}function F2(f1){var a =200 console
.log(f1())}var f1 = F1()F2(f1)// 100上述代码中,自由变量a的值,从函数F1中查找而不是F2,这是因为当自由变量从作用域链中去寻找,依据的是函数定义时的作用域链,而不是函数执行时。
3.闭包是什么闭包这个概念也是JavaScript中比较抽象的概念,我个人理解,闭包是就是函数中的函数(其他语言不能这样),里面的函数可以访问外面函数的变量,外面的变量的是这个内部函数的一部分闭包的作用:。
使用闭包可以访问函数中的变量可以使变量长期保存在内存中,生命周期比较长闭包不能滥用,否则会导致内存泄露,影响网页的性能闭包使用完了后,要立即释放资源,将引用变量指向null闭包主要有两个应用场景:函数作为参数传递(见作用域部分例子)
函数作为返回值(如下例)function outer(){var num =0//内部变量returnfunction add(){//通过return返回add函数,就可以在outer函数外访问了 num
++//内部函数有引用,作为add函数的一部分了 console.log(num)}}var func1 = outer()//func1()//实际上是调用add函数, 输出1func1()//输出2
var func2 = outer()func2()// 输出1func2()// 输出24.this全面解析先搞明白一个很重要的概念 —— this的值是在执行的时候才能确认,定义的时候不能确认!为什么呢 —— 因为this是执行上下文环境的一部分,而执行上下文需要在代码执行之前确定,而不是定义的时候。
看如下例子:// 情况1function foo(){ console.log(this.a)//1}var a =1foo()// 情况2function fn(){ console.log(this
);}var obj={fn:fn};obj.fn();//this->obj// 情况3functionCreateJsPerson(name,age){//this是当前类的一个实例p1this.name
=name;//=>p1.name=namethis.age=age;//=>p1.age=age}var p1=newCreateJsPerson("尹华芝",48);// 情况4function add
(c, d){returnthis.a +this.b + c + d;}var o ={a:1, b:3};add.call(o,5,7);// 1 + 3 + 5 + 7 = 16add.apply
(o,[10,20]);// 1 + 3 + 10 + 20 = 34// 情况5箭头函数this
免责声明:本站所有信息均搜集自互联网,并不代表本站观点,本站不对其真实合法性负责。如有信息侵犯了您的权益,请告知,本站将立刻处理。联系QQ:1640731186