由于工作项目原因,最近很少更新博客了,不过忙中抽闲,利用晚上时间,总结了一些有关JS的基础知识,并分享一些大厂面试 题,根据知识点进行具体分析讲解,希望能对方便大家来学习。

数据类型/堆栈内存

JS中的数据类型

  1. 基本数据类型

number string boolean null undefined symbol bigint

  1. 引用数据类型

object function
数据类型结构如下图

数字类型中的比较奇怪的值

  1. NaN是number类型
    Console.log(typeof NaN) // number
    Console.log(NaN === NaN)
    object.is(NaN, NaN) // true
  2. 检测一个值是否为有效数字 isNaN
    Console.log(isNaN(10)) // false
    console.log(isNaN(‘AA’)) // 在检测的时候,如果当前这个值不是数字类型,先隐士转换为数字类型(Number),然后再检测是否为非有效数字 true
  3. Infinity无穷大的值

数据类型转换方法

  1. typeof

    检测出来的结果是字符串,字符串 中包含了我们对于的数据类型
    typeof null 检测结果是 object ,不过null并不属于对象,而是因为二进制储存值以000开头了,检测对象细分类型,所以结果是“object”

  2. instanceof

  3. constructor

  4. Object.prototype.toString.call([value])

let res = parseFloat('left:200px'); // NaN
if(res === 200) {alert(200)
} else if (res === NaN) {alert(NaN)
} else if(typeof res === 'number') {alert('number')  // alert输出的结果都会转换成字符串
} else {alert('Invalid Number')
}
// number
let a = typeof typeof typeof[12, 23];
console.log(a) //string
// 解析 typeof[12, 23] => "object"
// typeof "object" => "string"
// typeof "string" => "string"

数据类型转换的4大核心标准

  1. 把其他数据类型转换为Number类型
  • 特定需要转换为Number的

    • Number([val])
      + parseInt/parseFloat([val])
  • 隐式转换(浏览器内部默认要先转换为Number在进行计算的)

  • isNaN([val])
    + 数学运算(特殊情况:+在出现字符串的情况下不是数学运算,是字符串拼接)
    + 在==比较的时候,有些值需要转换为数字再进行比较
  1. 把其它数据类型转换为字符串
  • 能使用的办法
  • toString()
    + String()
  • 隐式转换(一般都是调用其toString)

    • 加号运算的时候,如果某一边出现字符串,则是字符串拼接
      + 把对象转换为数字,需要先toString()转换为字符串,再去转换为数字
      + 基于alert/confirm/prompt/document.write…这些方式输出内容,都是把内容先转换为字符串,然后再输出的
  1. 在==比较的过程中,数据转换的规则
  • 类型一样的几个特殊点

    {} == {}:false 对象比较的是堆内存的地址
    [] == []:false
    NaN==NaN:false

  • 类型不一样的转换规则

null == undefined:true,但是换成 === 结果是false(因为类型不一致),剩下null/undefined和其它任何数据类型值都不相等
字符串 == 对象 要把对象转换为字符串
剩下如果== 两边数据类型不一致,都是需要转换为数字再进行比较

  1. 把其它数据类型转换为布尔
  • 基于以下方式可以把其它数据类型转换为布尔

    • ! 转换为布尔值后取反
      + !! 转换为布尔类
      + Boolean([val])
  • 在循环或者条件判断中,条件处理的结果就是布尔类型值

  • 在循环或者条件判断中,条件处理的结果就是布尔类型值
    注意:规则:只有 ‘0、NaN、null、undefined、空字符串’ 五个值会变为布尔的FALSE,其余都是TRUE
    把其他类型转换为字符串,一般都是直接“”包起来,只有{}普通对象调取toString是调取的Object.prrototype.toString,不是转换为字符串,而是检测数据类型,返回结果是"[object Objecg]"
let result = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false;
console.log(result); // NaNTencentnull9false
/** 隐式转换true 转换为1null 转换为0undefined 转换为NaN[] 转换为 ""
*/let result2 = 10 + false + undefined + [] + 'lanfeng' + null + true + {};// 10 + false => 10+ 0 => 10
// 10 + undefined => 10 + NaN => NaN
// NaN + [] => NaN + "" => "NaN"// "NaN" + "lanfeng" => "NaNlanfeng"
// {} => "[object Object]"
// "NaNlanfengnulltrue[object Object]"/*
*字符串 字符串拼接
* 对象 对象+ 0 需要把对象转换为字符串
*/
console.log([]==false);
//对象 == 布尔 都转换成数字(隐式转换),对象转换成数字:先toString转换为字符串
//(应该是先基于valueOf获取原始值,没有原始值再去toString),再转换为数字的
// 1. [] => '' => 0
// 2. false => 0
// 0 == 0
// trueconsole.log(![]==false); //![]优先false, false == false true
onsole.log([]===false); // falseconsole.log(![]==false); //true
// ![] 把数组转换成为布尔类型值后,然后取反, 为false
//false === false
// truevar a = {i:0,toString() {return ++this.i}
}
if(a==1 && a==2 && a==3) {console.log('OK')
}let arr = [10, 18, 0, 10, 25, 23]
arr = arr.map(parseInt)
console.log(arr)

把其他类型转换为数字

  1. Number机制

对象变为数字,应该先valueOf,没有原始值,再toString变为字符串,最后把字符串转为数字

console.log(Number('')) // 0
console.log(Number('10')) // 10
console.log(Number('10px')) // NaN 只要出现非有效数字字符串结果都是NaN
console.log(Number(true)) // 1
console.log(Number(false)) // 0
console.log(Number(null)) // 0
console.log(Number(undefined)) // NaN
  1. parseInt机制,从字符串左侧第一个字符开始,查找有效数字字符(遇到非有效数字字符停止查找,不论后面是否还有数字字符,都不再找了),把找到的有效数字字符转为数字,如果一个都没找到结果返回NaN(parseFloat比它多识别一个小数点)
parseInt("") //NaN
Number("") // 0
isNaN("") // 转为0,0是有效数字,所以结果是false
parseInt(null)  // parseInt("null") ,结果是NaN
isNaN(null) // null => 0 0是有效数字,所以结果是false
parseInt("12px") // 12
Number("12px") // NaN
isNaN("12px") // true
parseFloat("1.6px") + parseInt("1.2px") + typeof parseInt(null)
// 1.6+1+"number" => 2.6+ "number" => "2.6number"isNaN(Number(!!Number(parseInt("0.8")))) // false
// parseInt("0.8") => 0
// !!0 => false
// Number(false) => 0
// isNaN(0) => falsetypeof !parseInt(null) + !isNaN(null) // "booleantrue"
// parseInt(null) => NaN
// !NaN => true
// typeof true => "boolean"
// isNaN(null) => false
// !false => true
// => "booleantrue"

注意:

  1. 在js 中加号左右两边出现字符串,则变为字符串拼接(有特殊性),如果出现对象也会变为字符串拼接(因为原本应该是把对象转为数字,但是对象转数字需要先转换为字符串,则+遇到字符串直接转变为字符串拼接)
  2. 加号即使一边出现字符串或者对象,也不一定是字符串拼接:++i/i++/+i,这种情况是数学运算
let n = "10"
console.log(++n) // 11
console.log(+n) //10
{} + 0 // 0
// 左边的{}认为是一个代码块,不参与运算,运算只处理 +0=>0
{{}+0} //
// 参与到数学运算中"[object Object]0"
0 + {}  参与到数学运算中"0[object Object]"

**

变量提升问题

var a = 0;
if (true) {a = 1;function a() {};a = 21;console.log(a)
}
console.log(a);

当前上下文代码执行之前,会把var/function声明+定义,带var的只声明,带function声明+定义,如果遇到了{}新老浏览器表现还好不一致(兼容ES3、ES6)

  • IE浏览器 <= IE10

不管{},还是一如既往的function声明+定义,而且也不会存在块级作用域

  • 新版本浏览器

{}中的function,在全局下只声明不再定义,{} 中出现的function/let/const会创建一个块级上下文

闭包作用域

var x = 1;
function func(x, y = function anonymous1() {x = 2}) {x = 3;y();console.log(x); // 2
}
func(5);
console.log(x); // 1

var x = 1;
function func(x, y = function anonymous1() {x = 2}) {/** EC(FUNC)私有上下文*    作用域链:<EC(FUNC),EC(G)>*    x=5  (2)*    y=anonymous1   [[scope]]:EC(FUNC)* * EC(BLOCK) 块级上下文 (上级上下文 EC(FUNC))*    变量提升:var x;  *    在代码没有执行之前,我们会把EC(FUNC)中的值也给他一份  x=5  (3)*/var x = 3; //=>跨级上下文中的x  x=3y();  //=>不是块级的y,向上级找, EC(FUNC)// anonymous1执行 // 私有的上下文EC(AN)  作用域链:<EC(AN),EC(FUNC)>// x=2 修改的是EC(FUNC)中的2console.log(x); // 3
}
func(5);
console.log(x); // 1

ES6中存在块级作用域(只要{} [除对象之外的大括号] 出现let/const/function)

有一种情况也会产生

  • 函数有形参赋值了默认值
  • 函数体中有单独声明过某个变量

这样在函数运行的时候,会产生两个上下文
第一个:函数执行形成的私有上下文 EC(FUNC) =>作用域链/形参赋值/…
第二个:函数体大括号包起来的是一个块级上下文 EC(BLOCK)

面向对象

function Dog(name) {this.name = name;
}
Dog.prototype.bark = function () {console.log('wangwang');
}
Dog.prototype.sayName = function () {console.log('my name is ' + this.name);
}
function _new(func,...args) {//=>完成你的代码let obj = Object.create(func.prototype)let result = func.call(obj, ...args)if(result !== null && /^(object | functiion)$/.test(typeof(result))) return resultreturn obj}
let sanmao = _new(Dog, '三毛');
sanmao.bark(); //=>"wangwang"
sanmao.sayName(); //=>"my name is 三毛"
console.log(sanmao instanceof Dog); //=>true
// 手写call方法
~function(){function change(context, ...args){//=>实现你的代码// this -> funccontext = context == undefined ? window : context;let type = typeof context;if (!/^(object|function)$/.test(type)) {if (/^(symbol|bigint)$/.test(type)) {context = Object(context);} else {context = new context.constructor(context);}}let key = Symbol('key'),result;context[key] = this;result = context[key](...args);delete context[key];return result;};Function.prototype.change=change;
}();
let obj = {name:'zhufeng'};
function func(x,y){this.total=x+y;return this;
}
let res = func.change(obj,100,200);
//res => {name:'zhufeng',total:300}

总结

这篇文章主要分享了javascript数据类型、数据类型转换、变量提升、闭包作用域、面向对象及一些一线面试题,如果想了解更多,请扫描二维码,关注公众号

夯实基础,彻底掌握js的核心技术(一)相关推荐

  1. 夯实基础——P2084 进制转换

    题目链接:https://www.luogu.org/problem/P2084 P2084 进制转换 题目背景 无 题目描述 今天小明学会了进制转换,比如(10101)2 ,那么它的十进制表示的式子 ...

  2. final关键字_夯实基础:Java中final关键字的几种用法

    导语 在java的关键字中,static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构. 关于static请查 ...

  3. 点线面的特点_夯实基础!点线面的基本特点与表现

    夯实基础!点线面的基本特点与表现 平面设计就是以点.线.面为造型要素的视觉艺术.它具有三大特点: ①单纯性.运用点.线.面设计具有单纯.简洁.明快和运动规律性等特点.能在快节奏的现代生活中,适应人们追 ...

  4. 想要认认真真的夯实基础知识了

    今天看了一篇特别有感触的文章.作者(算是前辈了)从零开始自学生物信息学.博客上积累了很多的内容.让我很是钦佩. 最近也在读另外一个前辈分享的十年来的从业体验,其中就提到一条是"认真对待自己做 ...

  5. 零基础开发 Node.js Addons 插件:参数与返回值处理

    上一篇回顾 零基础开发 Node.js Addons 插件:Hello Node-API.本篇介绍使用 Node-API 为 Node.js 开发基于 C 的 Addons 时,如何接收与处理 Nod ...

  6. javascript 夯实基础

    http://blog.sina.com.cn/s/blog_62d9b0bf0100xo5d.html javascript 夯实基础 HTML DOM     节点树(节点数),节点访问      ...

  7. 夯实基础——P1830 轰炸III

    题目链接:https://www.luogu.org/problem/P1830 P1830 轰炸III 题目背景 一个大小为N*M的城市遭到了X次轰炸,每次都炸了一个每条边都与边界平行的矩形. 题目 ...

  8. Java学习路线-夯实基础

    Java学习路线-夯实基础 第一部分:网络与操作系统 第二部分:数据结构与算法 第三部分:Java基础 第四部分:Java设计模式 第五部分:数据库 第六部分:Redis 第七部分:并发与多线程 第八 ...

  9. 【FFT夯实基础系列】手写笔记合集|傅里叶级数、傅里叶变换

    B站up主@mazonex推出的宝藏系列视频课笔记 因为是数学类的,所以笔者采用了手写并导出的形式 这一篇合集包括了up主[傅里叶夯实基础系列]视频的P1-P6,可以通过上方链接看具体视频 目录 傅里 ...

  10. 【 js基础 Day2】js的流程控制:分支语句,循环.顺序结构

    复习 JavaScript简称为JS JavaScript是什么? 是一门脚本语言:不需要编译,直接运行 是一门解释性的语言:遇到一样代码就解释一行代码 C#语言是一门面向对象的语言,也是编译语言,是 ...

最新文章

  1. OpenCvSharp 图像像素归一化
  2. liunx系统内核安装图形化界面
  3. 有类和无类路由下的路由匹配原则
  4. UE4 控制台管理器: 在C++中设置控制台变量
  5. mac mysql 免密登录_Mac 免密登陆
  6. 合作 | 2018数博会AI全球赛项目征集!提供场景、数据集,总奖金池500万
  7. 单例模式2014-12
  8. Qt与Matlab混合编程细节总结
  9. 系列课程 ElasticSearch 之第 6 篇 —— 自定义扩展分词文件、文档映射
  10. 参考文献在论文中进行引用标注
  11. java 开发平台 普元_普元开发平台好不好?
  12. Python 实现 T00ls 自动签到脚本(邮件+钉钉通知)
  13. jfif格式怎么改成jpg或png格式?
  14. 苹果手机开热点,连上了却无网
  15. 各类学生机万能卸载攻略
  16. android放微信短视频文件,参考微信实现的短视频录像
  17. csv文件使用excel打开乱码解决办法
  18. 定位及overflow
  19. 5.Python函数高级
  20. 课堂随机提问中奖生成器二

热门文章

  1. 开机更新配置怎么关闭计算机,Win7关闭开关机的Windows Update配置()制作方法
  2. 地图距离算法_ORB-SLAM3 单目地图初始化(终结篇)
  3. java后台传一个对象到前台_前台判断对象中的一个布尔值_前后台分离的项目中,如何优雅的传输boolean类型的参数...
  4. lumen 项目根目录_利用rewrite修改网站根目录,适用于laravel、lumen
  5. sql 删除依赖_关系数据库标准语言SQL(二)
  6. Node.js-Express框架
  7. 算法与数据结构(六):堆排序
  8. 微信小程序快速开发上手
  9. Python大数据系列-01-关系数据库基本运算
  10. redis 介绍和常用命令