网站首页 > 技术文章 正文
JS数据类型
JS基本有5种简单数据类型:String,Number,Boolean,Null,Undefined。引用数据类型:Object,Array,Function。
判断数据类型的方法
在写业务逻辑的时候,经常要用到JS数据类型的判断,面试常见的案例深浅拷贝也要用到数据类型的判断。
typeof
console.log(typeof 2); // number
console.log(typeof true); // boolean
console.log(typeof 'str'); // string
console.log(typeof undefined); // undefined
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof function(){}); // function
console.log(typeof null); // object
复制代码
优点:能够快速区分基本数据类型 缺点:不能将Object、Array和Null区分,都返回object
instanceof
console.log(2 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
复制代码
优点:能够区分Array、Object和Function,适合用于判断自定义的类实例对象 缺点:Number,Boolean,String基本数据类型不能判断
Object.prototype.toString.call()
var toString = Object.prototype.toString;
console.log(toString.call(2)); //[object Number]
console.log(toString.call(true)); //[object Boolean]
console.log(toString.call('str')); //[object String]
console.log(toString.call([])); //[object Array]
console.log(toString.call(function(){})); //[object Function]
console.log(toString.call({})); //[object Object]
console.log(toString.call(undefined)); //[object Undefined]
console.log(toString.call(null)); //[object Null]
复制代码
优点:精准判断数据类型 缺点:写法繁琐不容易记,推荐进行封装后使用
var,let,const的区别
let 为 ES6 新添加申明变量的命令,它类似于 var,但是有以下不同:
- var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象
- let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升
- const声明的变量不允许修改
null和undefined区别
Undefined类型只有一个值,即undefined。当声明的变量还未被初始化时,变量的默认值为undefined。用法:
- 变量被声明了,但没有赋值时,就等于undefined。
- 调用函数时,应该提供的参数没有提供,该参数等于undefined。
- 对象没有赋值的属性,该属性的值为undefined。
- 函数没有返回值时,默认返回undefined。
Null类型也只有一个值,即null。null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。用法
- 作为函数的参数,表示该函数的参数不是对象。
- 作为对象原型链的终点。
定义函数的方法
- 函数声明
//ES5
function getSum(){}
function (){}//匿名函数
//ES6
()=>{}
复制代码
- 函数表达式
//ES5
var getSum=function(){}
//ES6
let getSum=()=>{}
复制代码
- 构造函数
const getSum = new Function('a', 'b' , 'return a + b')
复制代码
JS作用域的理解
JS中的作用域分为两种:全局作用域和函数作用域。函数作用域中定义的变量,只能在函数中调用,外界无法访问。没有块级作用域导致了if或for这样的逻辑语句中定义的变量可以被外界访问,因此ES6中新增了let和const命令来进行块级作用域的声明。
更多作用域的了解可以看JS作用域
闭包的理解
简单来说闭包就是在函数里面声明函数,本质上说就是在函数内部和函数外部搭建起一座桥梁,使得子函数可以访问父函数中所有的局部变量,但是反之不可以,这只是闭包的作用之一,另一个作用,则是保护变量不受外界污染,使其一直存在内存中,在工作中我们还是少使用闭包的好,因为闭包太消耗内存,不到万不得已的时候尽量不使用。
更多闭包的内容可以看JS闭包
数组去重
let arr = [1,'1',2,'2',1,2,'x','y','f','x','y','f'];
function unique1(arr){
let result = [arr[0]];
for (let i = 1; i < arr.length; i++) {
let item = arr[i];
if(result.indexOf(item) == -1){
result.push(item);
}
}
return result;
}
console.log(unique1(arr));
复制代码
更多JS去重的方法JS数组去重
call,apply和bind区别
三个函数的作用都是将函数绑定到上下文中,用来改变函数中this的指向;三者的不同点在于语法的不同。
fun.call(thisArg[, arg1[, arg2[, ...]]])
fun.apply(thisArg, [argsArray])
复制代码
所以apply和call的区别是call方法接受的是若干个参数列表,而apply接收的是一个包含多个参数的数组。
而bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。
var bindFn = fun.bind(thisArg[, arg1[, arg2[, ...]]])
bindFn()
复制代码
Demos:
var name = 'window';
var sayName = function (param) {
console.log('my name is:' + this.name + ',my param is ' + param)
};
//my name is:window,my param is window param
sayName('window param')
var callObj = {
name: 'call'
};
//my name is:call,my param is call param
sayName.call(callObj, 'call param');
var applyObj = {
name: 'apply'
};
//my name is:apply,my param is apply param
sayName.apply(applyObj, ['apply param']);
var bindObj = {
name: 'bind'
}
var bindFn = sayName.bind(bindObj, 'bind param')
//my name is:bind,my param is bind param
bindFn();
复制代码
==和===区别
- ==, 两边值类型不同的时候,要先进行类型转换,再比较
- ===,不做类型转换,类型不同的一定不等。
==类型转换过程:
- 如果类型不同,进行类型转换
- 判断比较的是否是 null 或者是 undefined, 如果是, 返回 true .
- 判断两者类型是否为 string 和 number, 如果是, 将字符串转换成 number
- 判断其中一方是否为 boolean, 如果是, 将 boolean 转为 number 再进行判断
- 判断其中一方是否为 object 且另一方为 string、number 或者 symbol , 如果是, 将 object 转为原始类型再进行判断
深拷贝和浅拷贝
浅拷贝
function simpleClone(obj) {
var result = {};
for (var i in obj) {
result[i] = obj[i];
}
return result;
}
复制代码
深拷贝,遍历对象中的每一个属性
function deepClone(obj) {
let result;
if (typeof obj == 'object') {
result = isArray(obj) ? [] : {}
for (let i in obj) {
//isObject(obj[i]) ? deepClone(obj[i]) : obj[i]
//多谢"朝歌在掘金"指出,多维数组会有问题
result[i] = isObject(obj[i])||isArray(obj[i])?deepClone(obj[i]):obj[i]
}
} else {
result = obj
}
return result
}
function isObject(obj) {
return Object.prototype.toString.call(obj) == "[object Object]"
}
function isArray(obj) {
return Object.prototype.toString.call(obj) == "[object Array]"
}
复制代码
防抖和节流
防抖
function debounce(fn, delay) {
let timer = null;
return function () {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
}
}
复制代码
节流
function throttle(fn, cycle) {
let start = Date.now();
let now;
let timer;
return function () {
now = Date.now();
clearTimeout(timer);
if (now - start >= cycle) {
fn.apply(this, arguments);
start = now;
} else {
timer = setTimeout(() => {
fn.apply(this, arguments);
}, cycle);
}
}
}
复制代码
cookie,sessionStorage和localStorage
- cookie用来保存登录信息,大小限制为4KB左右
- localStorage是Html5新增的,用于本地数据存储,保存的数据没有过期时间,一般浏览器大小限制在5MB
- sessionStorage接口方法和localStorage类似,但保存的数据的只会在当前会话中保存下来,页面关闭后会被清空。
名称生命期大小限制与服务器通信cookie一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效4KB每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题localStorage除非被清除,否则永久保存5MB仅在浏览器中保存,不与服务器通信sessionStorage仅在当前会话下有效,关闭页面或浏览器后被清除5MB仅在浏览器中保存,不与服务器通信
0.1+0.2!=0.3怎么处理
把需要计算的数字升级(乘以10的n次幂)成计算机能够精确识别的整数,等计算完成后再进行降级(除以10的n次幂),即:
(0.1*10 + 0.2*10)/10 == 0.3 //true
复制代码
更多关于浮点数精度处理请看JS中浮点数精度问题
JS实现继承
首先创建一个父类
// 定义一个动物类
function Animal(name, color) {
// 属性
this.name = name || 'Animal';
this.color = color || ['black'];
// 实例方法
this.sleep = function () {
console.log(this.name + '正在睡觉!');
}
}
// 原型方法
Animal.prototype.eat = function (food) {
console.log(this.name + '正在吃:' + food);
};
复制代码
原型链继承
new了一个空对象,这个空对象指向Animal并且Cat.prototype指向了这个空对象,这种就是基于原型链的继承。
function Cat(name) {
this.name = name || 'tom'
}
Cat.prototype = new Animal()
var cat = new Cat()
cat.color.push('red')
cat.sleep() //tom正在睡觉!
cat.eat('fish') //tom正在吃:fish
console.log(cat.color) //["black", "red"]
console.log(cat instanceof Animal) //true
console.log(cat instanceof Cat) //true
var new_cat = new Cat()
console.log(new_cat.color) //["black", "red"]
复制代码
- 特点:基于原型链,既是父类的实例,也是子类的实例。
- 缺点:1.无法实现多继承;2.所有新实例都会共享父类实例的属性。
构造继承
function Dog(name) {
Animal.call(this)
this.name = name || 'mica'
}
var dog = new Dog()
dog.color.push('blue')
dog.sleep() // mica正在睡觉!
dog.eat('bone') //Uncaught TypeError: dog.eat is not a function
console.log(dog.color) //["black", "blue"]
console.log(dog instanceof Animal) //false
console.log(dog instanceof Dog) //true
var new_dog = new Dog()
console.log(new_dog.color) //["black"]
复制代码
- 特点:可以实现多继承(call多个),解决了所有实例共享父类实例属性的问题。
- 缺点:1.只能继承父类实例的属性和方法;2.不能继承原型上的属性和方法。
组合继承
function Mouse(name){
Animal.call(this)
this.name = name || 'jerry'
}
Mouse.prototype = new Animal()
Mouse.prototype.constructor = Mouse
var mouse = new Mouse()
mouse.color.push('yellow)
mouse.sleep() //jerry正在睡觉!
mouse.eat('carrot') //jerry正在吃:carrot
console.log(mouse instanceof Animal)//true
console.log(mouse instanceof Mouse)//true
var new_mouse = new Mouse()
console.log(new_mouse.color) //["black"]
复制代码
- 特点:可以继承实例属性/方法,也可以继承原型属性/方法
- 缺点:调用了两次父类构造函数,生成了两份实例
链接来源:https://juejin.im/post/5df1e312f265da33d039d06d
猜你喜欢
- 2024-10-05 前端面试,你有必要知道的一些JavaScript 面试题(上)
- 2024-10-05 几道看起来代码量很少的Javascript笔试题,看看你会不会做?
- 2024-10-05 前端面试题《JS基础》 前端面试 js
- 2024-10-05 前端面试题JavaScript 前端面试题目100及最佳答案
- 2024-10-05 day6:前端面试题(js) js前端面试题及答案
- 2024-10-05 2023年最新的JavaScript面试题 锦屏县2023年幼儿园面试题
- 2024-10-05 20个基本的JavaScript面试问题及答案
- 2024-10-05 逐渐深入的Javascript面试题,看看你能过几关?
- 2024-10-05 谷歌面试7个简单又棘手的前端JavaScript面试题
- 2024-10-05 day10:前端面试题(js) 前端面试题及答案 知乎
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端md5加密 (49)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- 前端接口 (46)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)