6基本数据类型: Undefined, Null, Boolean, Number, String ,Symbol
引用类型: Array Object Date Function
区别:
基本类型值保存在栈空间,我们通过按值来访问的。
引用类型,的值是对象,栈内存中存放地址指向堆内存中的对象。是按引用访问的。栈内存中存放的只是该对象的访问地址,在堆内存中为这个值分配空间。
1.基本数据类型不可以添加/删除属性和方法;
2.复制的方式不同;引用类型复制的时候,复制的是指针,2个变量实际指的是同一个对象。
3.函数的参数是按值传递的
检测数据类型 typeof instanceof
转型数据类型
区别: undefined与null 的区别
null:
undefined :
symbol
表示独一无二的值
Symbol 值通过Symbol函数生成
对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型
Symbol函数前不能使用new命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象
由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型
Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的。因为symbol的每个值不相等。
Symbol 值不能与其他类型的值进行运算,会报错
Symbol 值可以显式转为字符串。
Symbol 值也可以转为布尔值,但是不能转为数值
Symbol 值作为对象属性名时,不能用点运算符。
何为面向对象
万物皆对象,
对象又有如下特点:
抽象:抓住核心问题
封装:只能通过对象来访问方法
继承:从已有的对象下继承出新的对象
多态:多对象的不同形态
创建对象的5种方式
1.工厂方式创建对象:面向对象中的封装函数(内置对象)
2.构造函数创建对象
优点:创建自定义函数意味着将来可以将它的实例标识为一种特定的类型,这是构造函数胜过工厂模式的地方
缺点:每个方法都要在每个实例上重新创建一遍
3、对象字面量方式创建对象
4、用原型方式
1、优点:可以让所有的对象实例共享它所包含的属性和方法
2、缺点:原型中是所有属性都是共享的,但是实例一般都是要有自己的单独属性的。所以一般很少单独使用原型模式。
5.混合模型:构造函数模式定义实例属性,而原型模式用于定义方法和共享的属性
总结:使用上述的混合法
数组的增加
数组的删除
改
查
排序
array.reverse() 把数组倒过来排序,原有数组改变
array.sort() 可以实现由大到小或者由小到大的排序 但是直接写sort只能排序十以内的数字
数组 对象 字符串 的转换;
array -->string:
obj --> string
string-->array:
obj --> array:
number --> array
string --> number (4种)
string <-- number (4种)
var c = String(number)
var c = number + ''
var c = number.toString(8) // 将number 转换成8进制的数字 且c的类型是string
var c = number.toFixed(1); //数字转换为字符串,并且显示小数点后的指定的位数 例 number = 123.476,则c= 123.5"
深浅拷贝
对象和数组的拷贝有两种
浅拷贝即 拷贝了指针指向,当一个对象的值改变会影响另一个对象的值。
深拷贝, 拷贝的是真正的值。2者相互独立,互不干扰。
浅拷贝的方法4种方法
slice() concat() 赋值法 遍历
注:concat 和 slice 对一维数组 能算是深拷贝;2维的 是浅拷贝
深拷贝的方法5种方法:
一维数组和对象的concat slice法 JSON.parse(JSON.stringify(arr)) 和遍历法 解构赋值法
示例:(前3种毕竟简单,这里也不表述)
解构赋值法:const a1 = [1, 2]; const a2 = [...a1];或者const [...a2] = a1;
还有一些常用方法如filter() forEach() map() every() some()
详情请见:最全最细致的数组的方法整理 es5+es6
ES5的属性特性包括下面六个:
configurable: 表示能否通过delete来删除属性从而重新定义属性,能够修改属性的特性,默认为true
enumberable: 表示是否能通过for-in循环返回属性。默认为true
writable: 是否可以修改属性, 默认为true
value: 包含这个属性的数据值。读取属性值时3,从这个属性读,写入属性时,把新值保存到这个位置。默认值为undefine.
getter: 在读取属性时,调用的函数
setter: 在写入属性时调用的函数
特别注意:一旦调用了Object.defineProperty方法之后,那些未定义的特性值除了configurable为false之外,其他都为undefined;
DOM是针对HTML和XML文档的一个API(应用程序编程接口). DOM描绘了一个层次化的节点树, 允许开发人员添加, 移除和修改页面的某一部分.
常用的DOM方法:
1)查找
a) getElementById(id) //通过元素Id,唯一性
b) getElementsByTagName() //通过标签名称
c) getElementsByName() //通过元素的Name属性的值(IE容错能力较强,
2)添加、移除、替换、插入 复制
c) appendChild(node) // 可添加 可移动位置;可添加元素 可添加文本
d) removeChild(node)
e) replaceChild(取代别人的mode,已有节点) // 替换已有节点
f) insertBefore(插入节点,已有节点) //在已有的子节点前插入一个新的子节点
g) cloneNode(true/false) //深浅复制
3)创建
4)
i) getAttribute()
j) setAttribute()
5 常用的DOM属性
a) innerHTML 节点(元素)的文本值
b) parentNode 节点(元素)的父节点
c) childNodes
d) attributes 节点(元素)的属性节点
6.两个节点的关系
为了方便书写,以下用dom来表示获取的HTML的节点。
- dom.style.width/height
这种方式只能取到dom元素内联样式所设置的宽高,也就是说如果该节点的样式是在style标签中或外联的CSS文件中设置的话,通过这种方法是获取不到dom的宽高的。
- dom.currentStyle.width/height
这种方式获取的是在页面渲染完成后的结果,就是说不管是哪种方式设置的样式,都能获取到。
但这种方式只有IE浏览器支持。
- window.getComputedStyle(dom).width/height
这种方式的原理和2是一样的,这个可以兼容更多的浏览器,通用性好一些。
- dom.getBoundingClientRect().width/height
这种方式是根据元素在视窗中的绝对位置来获取宽高的
- dom.offsetWidth/offsetHeight
这个就没什么好说的了,最常用的,也是兼容最好的。
主要考核 事件处理程序 和event对象及其属性和方法
方法有很多,闭包法、立即执行函数法、、事件委托法;
但本题主要考核 DOM事件流 利用事件委托,减少dom操作,提高性能
原生的写法
何为异步? 异步与同步的概念
实现异步的方法:回调 事件 promise
Ajax最大特性:可以实现动态不刷新(局部刷新).
优点:
缺点
GET请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给WEB服务器。当然在Ajax请求中,这种区别对用户是不可见的。
GET方式请求的数据会被浏览器缓存起来,因此其他人就可以从浏览器的历史记录中读取到这些数据,例如账号和密码等。在某种情况下,GET方式会带来严重的安全问题。而POST方式相对来说就可以避免这些问题。
"GET方式提交的数据最多只能是1024字节",post无
get请求和post请求在服务器端的区别:在客户端使用get请求时,服务器端使用Request.QueryString来获取参数,而客户端使用post请求时,服务器端使用Request.Form来获取参数.
当请求无副作用时(如进行搜索),便可使用GET方法;当请求有副作用时(如添加数据行),则用POST方法。
- 请求的结果有持续性的副作用,例如,数据库内添加新的数据行。
- 若使用GET方法,则表单上收集的数据可能让URL过长。
- 要传送的数据不是采用7位的ASCII编码。
若符合下列任一情况,则用GET方法: - 请求是为了查找资源,HTML表单数据仅用来帮助搜索。
- 请求结果无持续性的副作用。
- 收集的数据及HTML表单内的输入字段名称的总长不超过1024个字符。
- 对cookie localStorage sessionStorage的理解
localStorage和sessionStorage都具有相同的操作方法,例如setItem、getItem和removeItem等
cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。
cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递。
sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
存储大小:
cookie数据大小不能超过4k。
sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
有期时间:
localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage 数据在当前浏览器窗口关闭后自动删除。
cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
作用域不同:
sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;
localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。
Web Storage 的 api 接口使用更方便。
sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。
而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。
Web Storage的概念和cookie相似,区别是它是为了更大容量存储设计的。cookie的大小是受限的,并且每次你请求一个新的页面的时候cookie都会被发送过去,这样无形中浪费了带宽,另外cookie还需要指定作用域,不可以跨域调用。
除此之外,Web Storage拥有setItem,getItem,removeItem,clear等方法,不像cookie需要前端开发者自己封装setcookie,getcookie。
总之:cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在 ,而Web Storage仅仅是为了在本地“存储”数据而生
cookie优点:极高的扩展性和可用性 缺点: 数量和长度受限、安全问题
cookie 和session 的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、所以个人建议:
IE支持currentStyle,FIrefox使用getComputStyle
IE 使用innerText,Firefox使用textContent
滤镜方面:IE:filter:alpha(opacity= num);Firefox:-moz-opacity:num
事件方面:IE:attachEvent:火狐是addEventListener
鼠标位置:IE是event.clientX;火狐是event.pageX
IE使用event.srcElement;Firefox使用event.target
IE中消除list的原点仅需margin:0即可达到最终效果;FIrefox需要设置margin:0;padding:0以及list-style:none
CSS圆角:ie7以下不支持圆角
原则,那就是this指的是调用函数的那个对象。
javascript 的this主要是看如何调用这个函数,而不是这个函数所在的作用域。obj.fn() fn中的 this 就是 obj。 fn() this是undifine, 而在js进入函数之前,会有 if(!this) { this = window} 这样的操作。
this 一共有六种不同的值:
普通函数调用,this为全局对象或是undefined
作为对象的方法,this为那个对象
new 表达式,this为以该函数为原型的新创建的对象
使用 apply/call指定 this
用bind绑定固定的this
事件处理函数中的this是当前的触发事件的DOM元素(event.currentTarget)
IE attachEvent添加的事件处理函数中this为window
1.函数的调用方式
- 方法调用模型 var obj = { func : function(){};} obj.func()
- 函数调用模式 var aa = function(){} aa();
- 构造器调用模式
- apply/ call调用模式
- 立即执行函数(function(){}())
区别:函数调用模式,有函数提升的;即aa() 无需必须在var aa = function(){} 后面
2.return的含义
注:return不一定非得用在function 中,也可以直接放在html中,如:οnsubmit="return false";
语法:return 表达式;
含义:语句结束函数执行,返回调用函数,而且把表达式的值作为函数的结果
通常函数经过一系列的处理后需要给外部返回一个值,这个值一般用return返回出去,也可以是说return是向函数返回返回值,并终止函数的运行.
return;
return false;
retrun true;
闭包是指有权访问另一个函数作用域中的变量的函数. 创建闭包常见方式,就是在一个函数内部创建另一个函数.
作用:
1.匿名自执行函数 (function (){ ... })(); 创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在执行完后很快就会被释放,关键是这种机制不会污染全局对象。
2.缓存, 可保留函数内部的值
3.实现封装
4.实现模板
5.给了js函数生成函数的能力,增加了js代码的抽象能力
缺点
1.造成内存泄露;变量内存无法被标记,导致内存不会被垃圾回收机制回收。
为什么要用
局部变量无法共享和长久的保存,而全局变量可能造成变量污染,所以我们希望有一种机制既可以长久的保存变量又不会造成全局污染。
如何使用
1.定义外层函数,封装被保护的局部变量。
2.定义内层函数,执行对外部函数变量的操作。
3.外层函数返回内层函数的对象,并且外层函数被调用,结果保存在一个全局的变量中。
apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
apply 、 call 、bind 三者都可以利用后续参数传参;
bind是返回对应函数,便于稍后调用;
apply 、call 则是立即调用 。
特性,即封装、继承、多态
此处内容较多,便不详细叙述。注意一下继承的方式
继承6方式:
1、拷贝继承:通用型 有new无new都可以用
2、类式继承:new构造函数---利用构造函数(类)继承的方式
3、原型继承:无new的对象---借助原型来实现对象继承对象
4. 属性继承:调用父类的构造函数call
5. 方法继承:用for in的形式 拷贝继承(jq也用拷贝继承)
严格模式”的目的,主要有以下几个:
- 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的Javascript做好铺垫。
“严格模式”体现了Javascript更合理、更安全、更严谨的发展方向
1.延迟加载有些 js 代码并不是页面初始化的时候就立刻需要的,而稍后的某些情况才需要的。延迟加载就是一开始并不加载这些暂时不用的js,而是在需要的时候或稍后再通过js 的控制来异步加载。
JS延迟加载有助于提高页面加载速度。
js的进程由解析和执行构成。所有的延迟加载方式都只是延迟了执行过程。解析从未停止
js的执行顺序是自上而下。
延迟加载几种方式:
2.同步加载,又称阻塞模式,会阻止浏览器的后续处理,停止了后续的解析,因此停止了后续的文件加载(如图像)、渲染、代码执行。
3.异步加载:也就是说第一个fun请求数据时,数据还未返回时便开始执行第二个fun了
代表:ajax 回调 事件 promise
4.预加载
一种浏览器机制,使用浏览器空闲时间来预先下载/加载用户接下来很可能会浏览的页面/资源,当用户访问某个预加载的链接时,如果从缓存命中,页面就得以快速呈现
5.图片延迟加载的方式
许多OO语言支持两种继承方式:接口继承和实现继承。
接口继承只继承方法签名,实现继承则继承实际的方法。
由于函数无签名,在Javascript中无法实现接口继承。所以只能实现方法继承。
实现继承主要依赖原型链。
基本思想:利用原型,让那个一个引用类型继承另一个引用类型的属性和方法。A.prototype= new B();让原型对象等于另一个类型的实例。
所有函数的默认原型都是Object的实例
即A继承了B ;B 继承了Object;
什么是原型对象。我们知道每个构造函数一旦创建都有prototype指针指向它的原型对象(构造函数.prototype)。而原型对象(构造函数.prototype)会默认生成一个constructor指针又指向构造函数。在创建实例时,每个实例有一个__proto__指向该原型对象。原型对象内创建的所有方法会被所有实例共享。
例:
原型对象中的方法属性是被所有实例共享的。如果含有引用类型的属性,如数组,修改person1中的数组属性,也会导致person2中的该属性发生变化。
什么是原型链?
函数的原型对象constructor默认指向函数本身,原型对象除了有原型属性外,为了实现继承,还有一个原型链指针proto,该指针指向上一层的原型对象,而上一层的原型对象的结构依然类似,这样利用proto一直指向Object的原型对象上,而Object的原型对象用Object.prototype.proto = null表示原型链的最顶端,如此变形成了javascript的原型链继承,同时也解释了为什么所有的javascript对象都具有Object的基本方法。
原型链就是创建一个构造函数,它会默认生成一个prototype属性并指向原型对象。使用下一个构造函数的原型对象作为这个构造函数的实例。即 A.prototype = new B(); 在下下一个构造函数的原型对象 = new nextFuction。这样下去就会构成一条实例与原型之间的链条,这就是原型链。
构造函数A()和实例a1 a2之间的关系;var a1 = new A(); var a2 = new A();
实例a1与实例a2是独立的
实例和原型的关系 a1.__proto__ = A.prototype
构造函数A()和其原型的关系 A.prototype.constructor=A
6种继承方式
原型链继承本质:
是子用类型B的原型等于超类型的实例,
B.prototype= new A()
构造函数继承本质:
是子用类型的构造函数内部调用A(),
B(){A.call(this,**);}
组合继承本质
原型链和构造函数的组合,原型继承方法,构造函数继承属性
原型式继承本质:基于已有对象创建一个对象,
即对象A的浅拷贝,
var b= Object.create(A)
寄生式继承本质:
创建一个用于封装继承过程的函数,
function b(A){var clone = Object.create(A) ;clone.=;return clone;}
寄生组合继承本质:
寄生式继承超类型A的原型,并将结果赋值给子类型的原型;
或对对象A的原型浅拷贝,
function B(**){
}
function c(A,B){var clone = Object.create(A.prototype); clone.constructor = B;B.prototype=clone;) ;}
事件处理程序 获取事件对象 事件目标
好处 减少DOM 操作 ,减少性能
造成跨域的原因:
浏览器的同源策略,即XMLHttpRequest(XHR)对象只能访问同一域中的资源
这是种防止恶意行为的安全策略。
第二个:浏览器中不同域的框架之间是不能进行js的交互操作的。
何谓同源:URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示它们同源。
在浏览器中,<script>、<img>、<iframe>、<link>等标签属于DOM, 非XHR对象,是可以加载跨域资源
跨域方法(实践中后两种最常用,所以重点介绍):
(1) 通过jsonp跨域
ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
(2) 通过修改document.domain来跨子域
(3) 使用window.name来进行跨域
(4) 使用HTML5中新引进的window.postMessage方法来跨域传送数据
(5) 使用代理服务器,使用代理方式跨域更加直接,因为同源限制是浏览器实现的。如果请求不是从浏览器发起的,就不存在跨域问题了。
(6) CORS全称是"跨域资源共享"(Cross-origin resource sharing),CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能 发送请求时,附加一个额外的Origin头部
IE:XDR(XDomainRequest) 创建一个xdr实例,调用open() ,再send()方法;
其他的,原生的支持,使用绝对的URL即可。
附:ajax的扩展,comment/Web Sockets
(7) fetch api
浏览器内核又可以分成两部分:
渲染引擎(layout engineer或者RenderingEngine)和JS引擎。
JS的引擎深入分析链接描述
10分钟理解JS引擎的执行机制
http://www.ruanyifeng.com/blo...
JS引擎负责对Javascript进行解释、编译和执行,以使网页达到一些动态的效果。
js的几种引入方式;
js引擎是单线程 异步的
--- 任务队列 事件 和回调函数 Event Loop
是通过的事件循环(event loop),实现单线程和异步的。
单线程:同一时刻只能执行一个代码块
将要执行的代码放在任务队列中,但js引擎执行代码块结束,事件循环会执行任务队列中的下一个任务。
Event Loop 负责监控代码执行和管理任务队列。
异步的,即可通过事件 回调等方式,向任务队列中添加新任务。
JS的执行机制是
首先判断JS是同步还是异步,同步就进入主进程,异步就进入event table
异步任务在event table中注册函数,当满足触发条件后,被推入event queue
同步任务进入主线程后一直执行,直到主线程空闲时,才会去event queue中查看是否有可执行的异步任务,如果有就推入主进程中
以上三步循环执行,这就是event loop
准确的划分方式是:
macro-task(宏任务):包括整体代码script,setTimeout,setInterval
micro-task(微任务):Promise,process.nextTick
按照这种分类方式:JS的执行机制是
执行一个宏任务,过程中如果遇到微任务,就将其放到微任务的【事件队列】里
当前宏任务执行完成后,会查看微任务的【事件队列】,并将里面全部的微任务依次执行完
重复以上2步骤,结合event loop(1) event loop(2) ,就是更为准确的JS执行机制了。
7 错误监控
前端错误的分类
- 运行时错误(代码错误)
- 资源加载错误
- 接口错误
错误的捕获方式
运行时错误的捕获方式:
资源加载错误:
接口错误:
结论
1.使用window.onerror捕获JS运行时错误
2.使用window.addEventListener(‘unhandledrejection’)捕获未处理的promise reject错误
3.重写console.error捕获console.error错误
4.在跨域脚本上配置crossorigin="anonymous"捕获跨域脚本错误
window.addEventListener(‘error’)捕获资源加载错误。因为它也能捕获js运行时错误,为避免重复上报js运行时错误,此时只有event.srcElement inatanceof HTMLscriptElement或HTMLlinkElement或HTMLImageElement时才上报
5.重写window.XMLHttpRequest和window.fetch捕获请求错误
延伸:跨域的js运行错误可以捕获吗,错误提示什么,应该怎么处理?