【前端必备】三、JS篇
1.运算符与隐式类型转换
类型判断:
typeof |
constructor.toString().indexOf() |
|---|---|
| NaN是number Array、Date、Null都是Object function是function 未定义变量都是undefined |
"John".constructor // 返回函数 String() (3.14).constructor// 返回函数 Number() false.constructor// 返回函数 Boolean() [1,2,3,4].constructor// 返回函数Array() {name:'John', age:34}.constructor // 返回函数 Object() new Date().constructor// 返回函数 Date() function () {}.constructor// 返回函数 Function() |
类型转换:
- 对象转基本类型:
先调用valueOf()再调用toString() - 其他简单类型-->String:
| 方法 | 注意 |
|---|---|
| 变量+"" | |
| String(变量) | |
| 变量.toString() | ull和undefined这两个值没有toString()方法, Number.toString(2);将数字转成二进制 ArrayObject.toString()会转为逗号分隔的列表内容 |
- 其他数据类型-->Number:
| 方法 | 注意 |
|---|---|
| Number(变量) | true-->1 ; false-->0 ; null-->0 ;""或空格串-->0; undefined-->NaN;非纯数字串-->NaN; |
| parseInt(变量,进制) | 只保留开头数字,小数自动截断,非字符串会先自动转字符串。 两个参数时做进制转换 |
| parseFloat(变量) | 可以获得有效的小数部分 |
- 转换为Boolean:
0、-0、NaN、空串、null、undefined会转成false,其他都转成true - 伪数组转数组:
Array.prototype.slice.call(arguments)
隐式类型转换:
| 算术运算符 - * / + |
自动转换为Number 任何值和NaN计算结果都是NaN 任何的值和字符串做加法运算都会先转换为字符串,然后再做拼串操作 如[1,2]+[2,3]="1,22,3" 'a'+ +'b'="aNaN" |
| 一元运算符 typeof + - ++ -- |
对一个其他的数据类型使用+ - ++ -- 会将其转换为数字 |
| 逻辑运算符 && || ! |
能参与逻辑运算的都是布尔值 非布尔值会先转换成布尔值 |
| 关系运算符 && || ! |
*比较:非数值比较会先转换成数字     两个字符串比较不会转换,而是比较它们的unicode编码     任何值与NaN作比较都是false。(只有NaN自己不等于自己) *判等:==不同类型会转为相同类型(大部分时候转为数字)     ===不会做类型转换 |
调用非函数,或者读取null或者undefined的属性时,会报错 :
isNaN("foo"); // true
isNaN(undefined); // true
isNaN({}); // true
2.创建对象的方法
- new Object();
- 工厂函数(一个返回Object的函数)
- 构造函数,必须使用new来调用,this指向新建的对象。
new 一个构造函数的执行流程
(1)开辟内存空间,存储新创建的对象
(2)链接到原型,
(3)绑定this到新建对象,执行构造函数
(4)将新建的对象作为返回值返回
通过同一个构造函数实例化的多个对象具有相同的原型对象。
实例对象有一个__proto__属性,指向该实例对象对应的原型对象
实例.__proto__.constructor==构造函数 //true
构造函数有prototype属性,实例有__proto__属性
实例.__proto__==构造函数.prototype
试着实现一下instanceof:
function instanceof(left, right) {
// 获得类型的原型
let prototype = right.prototype
// 获得对象的原型
left = left.__proto__
// 判断对象的类型是否等于类型的原型
while (true) {
if (left === null)
return false
if (prototype === left)
return true
left = left.__proto__
}
}
3.闭包
闭包是指有权访问另一函数作用域中的变量的函数。
换句话说,在函数内定义一个嵌套的函数时,就构成了一个闭包, 它允许嵌套函数访问外层函数的变量。 通过返回嵌套函数,允许你维护对外部函数中局部变量、参数、和内函数声明的访问。
这种封装允许你在外部作用域中隐藏和保护执行环境,并且暴露公共接口,进而通过公共接口执行进一步的操作。
缺点:函数执行完后, 函数内的局部变量没有释放,占用内存时间会变长,容易造成内存泄露。
解决:能不用闭包就不用,及时释放。(将引用置为null)
经典面试题:
循环中使用闭包解决 var 定义函数的问题:

- 解决方法一,使用闭包:
(包装了一层立即执行函数,这样就不会污染全局变量了)

- 解决方法二,使用let:

- 解决方法三,使用setTimeout的第三个参数:

4.作用域和上下文
作用域(Scope)和上下文(Context)
作用域决定了代码区块中变量和其他资源的可见性。它指一个变量的作用范围。相对于上下文对象是静态的, 在编写代码时就确定了。
上下文(context)是指 this 在同一作用域内的值,是代码的执行环境。
执行上下文是动态的, 调用函数时创建, 函数调用结束时就会自动释放。
有三种类型的ECMAScript代码:全局代码,函数代码和eval代码。代码执行在它的执行上下文里。有唯一的全局上下文,以及可能有多个函数和eval上下文。
1.在全局代码执行前, JS引擎就会创建一个栈来存储管理所有的执行上下文对象
2.在全局执行上下文(window)确定后, 将其添加到栈中(压栈)
3.在函数执行上下文创建后, 将其添加到栈中(压栈)
4.在当前函数执行完后,将栈顶的对象移除(出栈)
5.当所有的代码执行完后, 栈中只剩下window
5.内存溢出和内存泄漏
内存溢出:一种程序运行出现的错误。当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误。
内存泄漏:占用的内存没有及时释放。
注意,内存泄露的次数积累多了,就容易导致内存溢出。
常见的内存泄露:
•意外的全局变量
•没有及时清理的计时器或回调函数
6.深浅拷贝
将引用复制改为值复制:
- Object.assign(target, ...sources)
将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。 不会跳过那些值为 null 或 undefined 的源对象。
只能解决第一层的问题 - 展开运算符 let b = {...a}
只能解决一层 - JSON.parse(JSON.stringify(object))
会忽略 undefined、symbol
不能序列化函数
不能解决循环引用(父子循环引用、兄弟循环引用)的对象
/**
* 对象克隆
* 支持基本数据类型及对象
* 递归方法
*/
// 方法一:
function clone(obj) {
var o;
switch (typeof obj) {
case "undefined":
break;
case "string":
o = obj + "";
break;
case "number":
o = obj - 0;
break;
case "boolean":
o = obj;
break;
case "object": // object 分为两种情况 对象(Object)或数组(Array)
if (obj === null) {
o = null;
} else {
if (Object.prototype.toString.call(obj).slice(8, -1) === "Array") {
o = [];
for (var i = 0; i < obj.length; i++) {
o.push(clone(obj[i]));
}
} else {
o = {};
for (var k in obj) {
o[k] = clone(obj[k]);
}
}
}
break;
default:
o = obj;
break;
}
return o;
}
7.异步与同步
js 是单线程,而且有一个任务队列:全部的同步任务执行完毕后,再来执行异步任务。
同步任务在主线程上排队执行,异步任务在任务队列等待,主线程上的同步任务执行完了,才会从任务队列取出异步任务执行。
常见的异步操作:网络请求、定时任务、事件绑定、promise
异步编程的4种方式:
- 回调函数
- 事件监听
f1.on('done', f2);
f1.trigger('done');
- 发布/订阅
jQuery.subscribe("done", f2);
jQuery.publish("done");
jQuery.unsubscribe("done", f2);
- promise对象
8.伪数组
特性:具有length属性、按索引方式存储数据、不具有数组的push,pop等方法。
例子:函数的arguments参数,调用getElementsByTagName,document.childNodes之类的返回的NodeList对象。
将伪数组转为数组:
function log(){
var args = Array.prototype.slice.call(arguments);
//为了使用unshift数组方法,将argument转化为真正的数组
args.unshift('(app)');
console.log.apply(console, args);
};
9.arguments的callee和caller属性
两个属性都是指针
arguments.callee指向当前函数,
arguments.caller指向当前函数的父函数
可用于递归函数中的自调用,实现函数执行与函数名的解耦合。
10.this、call、apply、bind
this 表示当前对象的一个引用
• 在方法中,this 表示该方法所属的对象。
• 如果单独使用,this 表示全局对象。
• 在函数中,this 表示全局对象。
• 在函数中,在严格模式下,this 是未定义的(undefined)。
• 在事件中,this 表示接收事件的元素。
类似 call() 和 apply() 方法可以将 this 引用到任何对象。
call、apply是立即调用函数,apply的第二个参数是参数数组。
persion1.say.call(p2, "实验小学", "六年级");
persion1.say.apply(p2, ["实验小学", "六年级"]);
将第一个参数p2作为say方法内this的指向,后面的参数作为say函数的参数。
bind传参与call相同,但bind返回一个函数,要加()才能立即执行。
persion1.say.bind(p2, "实验小学", "六年级")();
11.事件机制
事件触发的三个阶段 :
路径:Window <——> Document <——> <html> <——> … <——> 事件触发处
- 捕获阶段:遇到注册的捕获事件会触发
- 目标阶段:传播到事件触发处时触发注册的事件
- 冒泡阶段:遇到注册的冒泡事件会触发
如果给一个目标节点同时注册冒泡和捕获事件,事件触发会按照注册的顺序执行。
注册事件:
属性注册:
<button onlick="sayHello()">点击</button>
方法注册:
element.addEventListener(event, function, useCapture);
//usecapture默认false冒泡,true捕获element.attachEvent(event,function); //IE中EventTarget.onEventName=function(e){};
注销事件:
removeEventListener(event,function,capture/bubble);detachEvent(event,function);- 事件属性赋值为null
阻止事件冒泡:
box3.onclick = function (event) {
alert("child");
//阻止冒泡
event = event || window.event;
if (event && event.stopPropagation) {
event.stopPropagation();//w3c(火狐、谷歌、IE11)
} else {
event.cancelBubble = true;//IE10以下
}
}
事件委托(事件代理):
如果一个节点中的子节点是动态生成的,那么子节点需要注册事件的话应该委托给父节点
优点:减少内存消耗,提高性能。
12.BOM与DOM
BOM与DOM的关系:

系统对话框:
alert(); //不同浏览器中的外观是不一样的
confirm(); //兼容不好
prompt(); //不推荐使用
window操作窗口
window.open(url,target,param)
window.close()
新窗口.moveTo(5,5)
新窗口.resizeTo()
window.resizeBy()
location对象:
window.location可以简写成location。location相当于浏览器地址栏,可以将url解析成独立的片段。
- 属性
- href:跳转
- hash 返回url中#后面的内容,包含#
- host 主机名,包括端口
- hostname 主机名
- pathname url中的路径部分
- protocol 协议 一般是http、https
- search 查询字符串
- 方法
- location.assign():改变浏览器地址栏的地址,并记录到历史中
设置location.href 就会调用assign()。一般使用location.href 进行页面之间的跳转。 - location.replace():替换浏览器地址栏的地址,不会记录到历史中
- location.reload():重新加载
- location.assign():改变浏览器地址栏的地址,并记录到历史中
navigator对象:
window.navigator的一些属性 可以获取客户端的一些信息。
appCodeName appName appVersion cookieEnabled platform userAgent systemLanguage
history对象:
window.history 包含用户(在浏览器窗口中)访问过的 URL。
| 方法 | 描述 |
|---|---|
| back() | 加载 history 列表中的前一个 URL |
| forward() | 加载 history 列表中的下一个 URL |
| go() | 加载 history 列表中的某个具体页面 |
screen对象:
Screen 对象包含有关客户端显示屏幕的信息。
availHeight availWidth colorDepth height width pixelDepth
【前端必备】三、JS篇的更多相关文章
- 前端必备的js知识点(转载)
1.本文主体源自:http://www.cnblogs.com/coco1s/p/4029708.html,有兴趣的可以直接去那里看,也可以看看我整理加拓展的.2.js是一门什么样的语言及特点? ...
- 前端面试(原生js篇) - DOM
根据我的面试经历,一般小公司的面试环节,比较关心框架的熟练程度,以及独立开发组件的能力 但大厂通常有五轮以上的面试,而且对 js 基础语法很是看重 于是我总结了一些关于 js 基础的面试对话,有的当时 ...
- 前端深入之js篇丨Array数组操作从入门到成神Up Up Up,持续更新中
写在前面 随着前端深入的不断学习,发现数组这个数据结构在前端中有着相当大的存在感,由于我初学前端的时候并没有系统性的学习数组,所以我将通过这篇文章同你一起学习数组,希望我们能一起进步,学会熟练操作数组 ...
- 前端面试(原生js篇) - 精确运算
一.面试题 问:开发的时候有用到过 Math 吗? 答:很多啊.比如生成 GUID 的时候,就会用到 Math.random() 来生成随机数. 问:别的呢?比如向下取整.向上取整? 答:向下取整是 ...
- 前端自动化(三) 合并压缩css、压缩js、添加时间戳、打包上线操作
前端自动化(三) 合并压缩css.压缩js.添加时间戳.打包上线操作 此文在前两篇基础上对比参考,会很方便理解 gulp.task("delete",function(){ r ...
- 前端第三篇---前端基础之JavaScript
前端第三篇---前端基础之JavaScript 一.JavaScript概述 二.JavaScript的基础 三.词法分析 四.JavaScript的内置对象和方法 五.BOM对象 六.DOM对象 七 ...
- 前端开发者使用JS框架的三个等级
目前前端开发者使用JS框架是种很普遍的现象,因为框架可以加快开发速度,同时避免各类浏览器的兼容性问题.不过同样是用框架开发,不同开发者的境界水平还是有一定差距,本文将这些前端开发者分为三个等级. 第一 ...
- 月薪12k的零基础自学前端必备手册
随着互联网的深入发展,前端开发工程师一跃成为市场上非常抢手的人才.很多同学,包括以前做UI的.Java的.或者对于IT完全零基础的同学都想学习前端.下图是网上流传甚广的一张前端学习思维导图,很多初学者 ...
- 好程序员分享Web前端面试题汇总JS篇之跨域问题
为什么80%的码农都做不了架构师?>>> 好程序员分享Web前端面试题汇总JS篇之跨域问题,接着上一篇文章我们继续来探讨web前端面试必备面试题. 跨域解决方案 1. 通过jso ...
- webpack入门--前端必备
webpack入门--前端必备 什么是 webpack? webpack是一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都作为模块来 ...
随机推荐
- python模拟android屏幕高频点击工具
一.环境 windows 10 + python3.6 二.需求 1.模拟android设备高频点击事件: 2.模拟规定次数的点击事件或模拟规定时间内的点击事件: 三.code 1.模拟规定时间内的 ...
- centos6.8配置FTP普通用户除了家目录外还能访问其他目录
今天有个需求,使用ftp服务搭建一个文件共享服务器,每个普通用户除了能访问自己家目录的东西,还能访问一个公共的目录.配置步骤如下: 环境如下: 创建用户并配置密码(使用默认家目录/home) user ...
- Java面试知识总结三
1.SpringMVC在项目中的应用? 1)service层,项目的业务逻辑层,一般先定义一个接口,在写一个实现类,实现所有的接口方法.service的实现类中要加注解@Service(用于标注业务层 ...
- 安装在Linux下的jenkins执行windows下的bat命令
launch method里面没有 launch agent via java web start 默认是disable 需要改成random 转载自: http://blog.csdn.net/so ...
- 用reduce实现简单的pipe
function pipe(src, ...fns){ return fns.reduce(function(fn1, fn2){ return fn2(fn1) }, src); } undefin ...
- 省队集训Day1 总统选举
[题目大意] 一个$n$个数的序列,$m$次操作,每次选择一段区间$[l, r]$,求出$[l, r]$中出现超过一半的数. 如果没有超过一半的数,那么就把答案钦定为$s$,每次会有$k$个数进行改变 ...
- Centos服务器ssh免密登录以及搭建私有git服务器
一.概述 服务器的免密登录和git服务器的搭建,关键都是要学会把自己用的机器的公钥添加到服务器上,让服务器“认识”你的电脑,从而不需要输入密码就可以远程登录服务器上的用户 免密登录当然是登录root用 ...
- 移动端 H5 页面注意事项
1. 单个页面内容不能过多 设计常用尺寸:750 x 1334 / 640 x 1134,包含了手机顶部信号栏的高度. 移动端H5活动页面常常需要能够分享到各种社交App中,常用的有 微信.QQ 等. ...
- 阅读关于DuReader:百度大规模的中文机器阅读理解数据集
很久之前就得到了百度机器阅读理解关于数据集的这篇文章,今天才进行总结!.... 论文地址:https://arxiv.org/abs/1711.05073 自然语言处理是人工智能皇冠上的明珠,而机器阅 ...
- 源码分析之tinyhttpd-0.1
1. 简介: tinyhttpd是使用c语言开发的超轻量级http服务器,通过代码流程可以了解http服务器的基本处理流程, 并且涉及了网络套接字,线程,父子进程,管道等等知识点: 项目地址:http ...