原型链
1.Object.prototype属性是整个原型链的顶端 2.原型链通过prototype原型和__proto__属性来查找的. 3.实例本身的属性和方法如果没有找到,就会去找原型对象的属性和方法。如果在某一级找到了,就会停止查找,并返回结果 4.说白了,其实就是有限的实例对象和原型之间组成有限链,就是用来实现共享属性和继承的 5.
类
1.ES6以后的语法(可以看做是ES5的语法糖) 2.ES6 的类,可以看作构造函数的另一种写法。 3.类的数据类型就是函数,类本身就指向构造函数 注意点: 1.类的内部所有定义的方法,都是不可枚举的(non-enumerable)。 ES5 的写法,prototype上的方法就是可枚举的。 2.类的方法都定义在prototype对象上面,所以类的新方法可以添加在prototype对象上面。Object.assign方法可以很方便地一次向类添加多个方法 3.类和模块的内部,默认就是严格模式 4.constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象 5.Es6类不存在变量提升,这一点与 ES5 完全不同
继承
1.继承的本质是原型链 2.原型链继承
(1)特点:实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!) (2)缺点:1.新实例无法向父类构造函数传参 2.继承单一 3.所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原型属性也会被修改!) 3.借用构造函数继承
重点:用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制)) (1)特点: ①1.只继承了父类构造函数的属性,没有继承父类原型的属性。 ②解决了原型链继承缺点 ③可以继承多个构造函数属性(call多个)。 ④在子实例中可向父实例传参。 (2)缺点: ①只能继承父类构造函数的属性。 ②无法实现构造函数的复用。(每次用每次都要重新调用) ③每个新实例都有父类构造函数的副本,臃肿 4.组合继承(组合原型链继承和借用构造函数继承)(常用)
重点:结合了两种模式的优点,传参和复用 (1)特点 ①可以继承父类原型上的属性,可以传参,可复用。 ②每个新实例引入的构造函数属性是私有的 (2)缺点 ①调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数 5.原型式继承
重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。 (1)特点 ①类似于复制一个对象,用函数来包装。 (2)缺点 ①所有实例都会继承原型上的属性。 ②无法实现复用。(新实例属性都是后面添加的) 6.寄生式继承
重点:就是给原型式继承外面套了个壳子。 (1)优点 ①没有创建自定义类型,因为只是套了个壳子返回对象(这个),这个函数顺理成章就成了创建的新对象 (2)缺点 ①没用到原型,无法复用。 7.寄生组合式继承(常用)
(1)寄生:在函数内返回对象然后调用 (2)组合:1、函数的原型等于另一个实例。2、在函数中用apply或者call引入另一个构造函数,可传参 重点:修复了组合继承的问题
作用域
1.js没有块级作用域,有函数作用域、全局作用域。es6出现才有块级作用域。 2.作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性。换句话说,作用域决定了代码区块中变量和其他资源的可见性 3.作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。 4.ES6 之前 JavaScript 没有块级作用域,只有全局作用域和函数作用域。ES6 之后,为我们提供了‘块级作用域’,可通过新增命令 let 和 const 来体现。 5.全局作用域 在代码中任何地方都能访问到的对象拥有全局作用域 6.函数作用域:jQuery、Zepto 等库的源码,所有的代码都会放在(function(){....})()中。因为放在里面的所有变量,都不会被外泄和暴露,不会污染到外面,不会对其他的库或者 JS 脚本造成影响。这是函数作用域的一个体现。 7.块级作用域:块级作用域可通过新增命令 let 和 const 声明,所声明的变量在指定块的作用域外无法被访问 (1)声明变量不会提升到代码块顶部 (2)禁止重复声明 (3)在一个函数内部或者在一个代码块(由一对花括号包裹)内部 8.作用域链:www.cnblogs.com/leftJS/p/11…
闭包
1.闭包是函数和声明该函数的词法环境的组合 2.使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。 3.特征: (1)函数嵌套函数 (2)函数内部可以引用外部的参数和变量 (3)参数和变量不会被垃圾回收机制回收
Js运行机制
1.介绍: (1)javascript是单线程的,主线程拥有一个执行栈以及一个任务队列,主线程会依次执行代码,当遇到异步函数时候,会先将该函数入栈,所有主线程函数运行完毕后再将异步函数出栈,直到所有的异步函数执行完毕即可。
2.运行机制 (1)整体的script(作为第一个宏任务)开始执行的时候,会把所有代码分为两部分:“同步任务”、“异步任务”; (2)同步任务会直接进入主线程依次执行; (3)异步任务会再分为宏任务和微任务; (4)宏任务进入到Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中; (5)微任务也会进入到另一个Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中; (6)当主线程内的任务执行完毕,主线程为空时,会检查微任务的Event Queue,如果有任务,就全部执行,如果没有就执行下一个宏任务; (7)上述过程会不断重复,这就是Event Loop事件循环;
Js数据类型
1.值类型/ 基本数据类型:undefined、string、number、boolean 2.对象、数组、函数 3.基本数据类型存储在栈中,复杂数据类型存储在堆中 4.false: 0、NaN、’’、null、undefined 5.typeof只能区分值类型 js中的内置函数/内置对象 1.内置函数 (1)Number、String、Boolean、Array、Object、Function、Date、RegExp、Error 2.内置对象 (1)Math,Json
字符串方法
1.Concat:将两个或多个字符的文本组合起来,返回一个新的字符串。 2.indexOf:返回字符串中一个子串第一处出现的索引(从左到右搜索)。如果没有匹配项,返回 -1 。 3.charAt:返回指定位置的字符。 4.lastIndexOf:返回字符串中一个子串最后一处出现的索引(从右到左搜索),如果没有匹配项,返回 -1 。 5.Match:检查一个字符串匹配一个正则表达式内容,如果么有匹配返回 null。 6.Substring:返回字符串的一个子串,传入参数是起始位置和结束位置。 7.Substr:返回字符串的一个子串,传入参数是起始位置和长度 8.Replace:用来查找匹配一个正则表达式的字符串,然后使用新字符串代替匹配的字符串。 9.Search:执行一个正则表达式匹配查找。如果查找成功,返回字符串中匹配的索引值。否则返回 -1 。 10.Slice:返回字符串的一个子串,传入参数是起始位置和结束位置。 11.Split:通过将字符串划分成子串,将一个字符串做成一个字符串数组。 12.Length:返回字符串的长度,所谓字符串的长度是指其包含的字符的个数。 13.toLowerCase:将整个字符串转成小写字母。 14.toUpperCase:将整个字符串转成大写字母。
数组方法
1.join():就是把数组转换成字符串,然后给他规定个连接字符,默认的是逗号( ,) 2.push(): 把里面的内容添加到数组末尾,并返回修改后的长度。 3.pop():移除数组最后一项,返回移除的那个值,减少数组的length。 4.shift():删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined 5.unshift:将参数添加到原数组开头,并返回数组的长度 。 6.sort():将数组里的项从小到大排序 7.reverse():反转数组项的顺序 8.concat() :将参数添加到原数组中。这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。在没有给 concat()方法传递参数的情况下,它只是复制当前数组并返回副本。 9.slice():返回从原数组中指定开始下标到结束下标之间的项组成的新数组。slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。 10.splice():删除、插入和替换。 (1)删除:指定 2 个参数:要删除的第一项的位置和要删除的项数。 (2)插入:可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、 0(要删除的项数)和要插入的项。 (3)可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。 11.indexOf():接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找。 12.lastIndexOf:接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找。 13.forEach():对数组进行遍历循环,对数组中的每一项运行给定函数。这个方法没有返回值。参数都是function类型,默认有传参,参数分别为:遍历的数组内容;第对应的数组索引,数组本身。 14.map():指“映射”,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。 15.filter():“过滤”功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组。 16.every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true。 17.some():判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。 18.reduce()/reduceRight():这两个方法都会迭代数组中的所有项,然后生成一个最终返回值。他们都接收两个参数,第一个参数是每一项调用的函数,函数接受四个参数分别是初始值,当前值,索引值,和当前数组,函数需要返回一个值,这个值会在下一次迭代中作为初始值。第二个参数是迭代初始值,参数可选,如果缺省,初始值为数组第一项,从数组第一个项开始叠加,缺省参数要比正常传值少一次运算。 19.Array.from():方法是用于类似数组的对象(即有length属性的对象)和可遍历对象转为真正的数组。 20.Array.of():方法是将一组值转变为数组,参数不分类型,只分数量,数量为0返回空数组。 21.find():方法返回通过测试(函数内判断)的数组的第一个元素的值。方法为数组中的每个元素都调用一次函数执行。当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。如果没有符合条件的元素返回 undefined。回调函数可以接收3个参数,依次为当前的值(currentValue)、当前的位置(index)、原数组(arr),注意:find() 对于空数组,函数是不会执行的。find() 并没有改变数组的原始值。 22.findIndex ():findIndex和find差不多,不过默认返回的是索引,如果没有符合条件的元素返回 -1 23.fill(): (1)fill()方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。 (2)语法:array.fill(value, start, end) (3)value:必需。填充的值。 (4)start:可选。开始填充位置。如果这个参数是负数,那么它规定的是从数组尾部开始算起。 (5)end:可选。停止填充位置 (默认为 array.length)。如果这个参数是负数,那么它规定的是从数组尾部开始算起 24.遍历数组方法 keys()、values()、entries():这三个方法都是返回一个遍历器对象,可用for...of循环遍历,唯一区别:keys()是对键名的遍历、values()对键值的遍历、entries()是对键值对的遍历。 25.includes():方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。 (1) 26.copyWithin():方法用于从数组的指定位置拷贝元素到数组的另一个指定位置中,会覆盖原有成员 (1)
内存泄漏
www.cnblogs.com/yuanzhiguo/… 1.内存泄漏指任何对象在您不再拥有或需要它之后仍然存在 2.意外的全局变量:js对未声明变量会在全局最高对象上创建它的引用,(是以属性存在的,而不是变量),如果在游览器上就是window对象,如果在node环境下就是global;如果未声明的变量缓存大量的数据,它可能只有在页面被刷新或者被关闭的时候才会释放内存,这样就造成了内存意外泄漏 3.console.log:作为前端平时使用console.log在控制台打出相对应的信息可以说是非常常见。但如果没有去掉console.log可能会存在内存泄漏。因为在代码运行之后需要在开发工具能查看对象信息,所以传递给console.log的对象是不能被垃圾回收。 4.闭包:首先闭包是一个函数A返回一个内联的函数B,及时A函数执行完函数B也可以访问函数A里面的变量,这就是一个简单的闭包。本质上闭包是将函数内部和外部连接起来的一座桥梁 5.DOM泄漏:游览器中DOM和js采用的是不一样的引擎,DOM采用的是渲染引擎,而js采用的是v8引擎,所以在用js操作DOM时会比较耗费性能,因为他们需要桥来链接他们。为了减少DOM的操作,我们一般将常用的DOM。我们会采用变量引用的方式会将其缓存在当前环境。如果在进行一些删除、更新操作之后,可能会忘记释放已经缓存的DOM 6.被遗忘的timers:js中常用的定时器setInterval()、setTimeout().他们都是规定延迟一定的时间执行某个代码,而其中setInterval()和链式setTimeout()在使用完之后如果没有手动关闭,会一直存在执行占用内存,所以在不用的时候我们可以通过clearInterval()、clearTimeout() 来关闭其对应的定时器
通信
1.同源策略:同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。 2.源:协议、域名、端口 3.解决跨域的几种方式 (1)Jsonp:script标签的异步加载 ①回调函数:当响应到来时要放在当前页面被调用的函数。 ②数据:就是传入回调函数中的json数据,也就是回调函数的参数了。 (2)使用跨域资源共享(CORS)来跨域 ①一种跨域访问的机制,可以让AJAX实现跨域访问;CORS允许一个域上的网络应用向另一个域提交跨域AJAX请求。 ②服务器设置Access-Control-Allow-Origin HTTP响应头之后,浏览器将会允许跨域请求. ③就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。 (3)Web sockets: ①web sockets: 是一种浏览器的API,它的目标是在一个单独的持久连接上提供全双工、双向通信。(同源策略对web sockets不适用) ②web sockets原理:在JS创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web sockt协议。 (4)Webpack:反向代理接口
虚拟DOM
1.用js模拟dom结构,提高重绘性能。 深拷贝和浅拷贝 深拷贝: 1.最简单的方法就是JSON.parse(JSON.stringify()) 2.用递归去复制所有层级属性 浅拷贝: 1.object.assign(target,source) 2.for···in只循环第一层 3.直接用=赋值 Js原生api 1.Anchor 对象:指HTML超链接 (1)修改一个链接的文本,链接和target 2.Document 对象:指 页面文档文本 (1)1.document输出流输出 文本 或者 HTML ①document.write("Hello World!") //Hello World ②document.write(document.title) //返回当前页面的标题 ③document.URL , document.referrer , location.href 的区别: 1)从输出结果上,document.URL 和 windows.location.href 没有区别。 2)非要说区别的话,你只可以读取document.URL的值,不能修改它。windows.location.href的值你即可以读取也可以修改,可以使用它进行页面跳转。 3) referrer则是返回前一个来源页面的URL,并不是当前页面 (2)元素选择 ①第一个返回选中id,其余则是返回一个数组 ②document.getElementById() ③document.getElementsByName() ④document.getElementsByClassName() ⑤document.getElementsByTagName() 3.Event 对象 (1)1.获取鼠标的按键,返回按键索引 event.button (2)2.获取光标的坐标 event.clientX (3)3.获取按键码 event.keyCode (4)4.获取光标相对于屏幕的 位置 event.screenX (5)5.得到事件元素 和 事件类型 vent.target event.type