概述
数据类型和存储上的差别
在JavaScript
中,我们可以分成两种类型:
- 基本类型
- 复杂类型
两种类型的区别是:存储位置不同
基本类型主要为以下 6 种:
- Number
- String
- Boolean
- Undefined
- null
- symbol
引用类型
复杂类型统称为Object
,我们这里主要讲述下面三种:
- Object
- Array
- Function
存储区别
基本数据类型和引用数据类型存储在内存中的位置不同:
-
基本数据类型存储在栈中
-
引用类型的对象存储于堆中
== 和 ===区别,分别在什么情况使用
= : 一个等号为赋值操作
== :二个等号为判断,判断的是值是否相等,相等返回 true,不等返回 false
===: 三个等号为全等,判断的是值和类型是否相等,相等返回 true,不等返回 false
typeof 与 instanceof 区别
typeof 一般是用来判断变量是否存在,返回他的类型,其中基本数据类型 null 返回的是一个 object,但 null 不属于引用数据类型,typeof 除了判断 function 函数会识别,其他的引用类型输出为 object
instanceof 一般是用来判断引用数据类型,但不能正确判断基本数据类型,根据在原型链中查找判断当前数据的原型对象是否存在返回布尔类型
2 种方法各有各的优缺点,一般我们推荐判断数据类型使用 Object.prototype.toString,返回统一的格式[object Xxx]
深拷贝浅拷贝的区别?如何实现一个深拷贝?
浅拷贝:拷贝基本数据类型为他的值,拷贝引用数据类型为地址,生成新的数据,修改新的数据会影响原数据,实际开发常用的方法有:object.assgin,扩展运算符等等
深拷贝:在内存中开辟一个新的栈空间保存新的数据,修改新数据不会影响到原数据,开发中常用的方法有:loadsh 中的_.cloneDeep()方法,JSON.stringify()
浅拷贝
浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝
如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址
即浅拷贝是拷贝一层
,深层次的引用类型则共享内存地址
下面简单实现一个浅拷贝
function shallowClone(obj) {
const newObj = {}
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
newObj[prop] = obj[prop]
}
}
return newObj
}
在JavaScript
中,存在浅拷贝的现象有:
Object.assign
Array.prototype.slice()
,Array.prototype.concat()
- 使用拓展运算符实现的复制
深拷贝
深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
常见的深拷贝方式有:
-
_.cloneDeep()
-
jQuery.extend()
-
JSON.stringify()
-
手写循环递归
#_.cloneDeep()
const _ = require('lodash')
const obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3],
}
const obj2 = _.cloneDeep(obj1)
console.log(obj1.b.f === obj2.b.f) // false
说说你对作用域链的理解
作用域一般可以理解为函数或变量的生效范围,我们一般把作用域分成全局作用域,函数(局部)作用域,块级作用域(es6 推出),列如我们在 a 函数中定义了一个变量,那么当我们在 js 中访问这个变量他就会在当前作用域进行查找,如果访问不到,他会一层一层向外进行查找,整个逐级向上查找的过程我们称为作用域链. 可以用八个字来总结 依次查找 就近原则
我们一般将作用域分成:
-
全局作用域 : 任何不在函数中或是大括号中声明的变量,都是在全局作用域下,全局作用域下声明的变量可以在程序的任意位置访问
-
函数作用域 : 函数作用域也叫局部作用域,如果一个变量是在函数内部声明的它就在一个函数作用域下面。这些变量只能在函数内部访问,不能在函数以外去访问
-
块级作用域 : ES6 引入了
let
和const
关键字,和var
关键字不同,在大括号中使用let
和const
声明的变量存在于块级作用域中。在大括号之外不能访问这些变量
箭头函数
箭头函数是定义函数一种新的方式,他比传统函数 function 定义更加方便和简单,他没有绑定自己的 this 指向和伪数组 arguments,无法调用 super 方法生成实例化对象,因为他不是构造函数,一般用来取代匿名函数的写法,最主要的是箭头函数的 this 指向他的上一级作用域中的 this 也可以理解为他的 this 是固定的,而普通函数的 this 是可变的
JavaScript 原型,原型链 ? 有什么特点?
-
原型是我们创建函数的时候,系统帮我们自动生成的一个对象。 主要作用是解决构造函数内部方法内存资源浪费问题。在开发中我们一般把实例对象一些通用的方法放入原型中,在 vue 里面有时候也会给 vue 的原型添加一些公共类方法来实现所有的组件中可以共享成员。像一些常见的$router和$store 都是挂载到 vue 的原型上的。
-
原型链是 js 对象一种查找机制,遵循就近原则。当我们访问一个对象中的成员的时候,会优先访问自己的,如果自己没有就访问原型的,如果原型也没有就会访问原型的原型,直到原型链的终点 null. 如果还没有,此时属性就会获取 undefined,方法就会报错 xxx is not a function。一般原型链主要是用来实现面向对象继承的。
JavaScript
常被描述为一种基于原型的语言——每个对象拥有一个原型对象
-
构造函数
Person
存在原型对象Person.prototype
-
构造函数生成实例对象
person
,person
的__proto__
指向构造函数Person
原型对象
最后
以上就是乐观酒窝为你收集整理的JavaScript面试题数据类型和存储上的差别== 和 ===区别,分别在什么情况使用typeof 与 instanceof 区别深拷贝浅拷贝的区别?如何实现一个深拷贝?说说你对作用域链的理解箭头函数JavaScript 原型,原型链 ? 有什么特点?说说你对闭包的理解?闭包使用场景说说 JavaScript 中内存泄漏的几种情况?bind、call、apply 区别?如何实现一个 bind?Javascript 如何实现继承?说说 new 操作符具体干了什么?数组的常用方法有哪些?JavaS的全部内容,希望文章能够帮你解决JavaScript面试题数据类型和存储上的差别== 和 ===区别,分别在什么情况使用typeof 与 instanceof 区别深拷贝浅拷贝的区别?如何实现一个深拷贝?说说你对作用域链的理解箭头函数JavaScript 原型,原型链 ? 有什么特点?说说你对闭包的理解?闭包使用场景说说 JavaScript 中内存泄漏的几种情况?bind、call、apply 区别?如何实现一个 bind?Javascript 如何实现继承?说说 new 操作符具体干了什么?数组的常用方法有哪些?JavaS所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复