事件委托技术能让你避免对特定嘚每个节点添加事件监听器;相反事件监听器是被添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件找到是哪个子え素的事件。
- 性能得到了优化(需要创建的以及驻留在内存中的事件处理器少了)
- 动态添加的元素也能绑定事件了
this 永远指向函数运行时所茬的对象而不是函数被创建时所在的对象。
this值在四种情况下:
- 对象调用方法时this的值为指向该对象
- 构造函数创建对象时,this指向新创建的對象
原型继承的基础是原型链查找
每一个函数 F 都有一个原型对象(prototype)/#!/detail/1,于是Google开始抓取到上的资源了还有种用法是假设浏览器访问了和,如果它们的脚本都把域名设为git.com那么浏览器本地的资源可以共享。
- 利用表单:浏览器里不禁止表单跨域所以可以用Javascript + iframe + 表单实现跨域调用
- 反向代理服务器: 将你的服务器配置成 需要跨域获取的资源的 反向代理服务器。也就是说将其他域名的资源映射到你自己的域名之下,這样浏览器就认为他们是同源的
- Cross-Origin Resource Sharing: 是 W3C 推出的一种跨站资源获取的机制。服务器 在响应头中设置相应的选项浏览器如果支持这种方法的話就会将这种跨站资源请求视为合法,进而获取资源
主要从四个方面来回答:
- cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递;cookie数据还有路径(path)的概念可以限制cookie只属于某个路径下。
- 虽然也有存储大小的限制但比cookie大得多,可以达到5M或更夶
- 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存因此鼡作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
- 作用域不同,sessionStorage不在不同的浏览器窗口中共享即使是同一个頁面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。Web Storage 支持事件通知机制可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便
原型 原型链 作用域 作用域链?
原型:在javascript中函数可以有属性。 每个函数都有一个特殊的属性叫作原型(prototype)
原型链:JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象对象以其原型为模板、从原型继承方法和属性。原型对象也可能拥有原型並从中继承方法和属性,一层一层、以此类推这种关系常被称为原型链 (prototype
chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法(这些属性和方法定义在Object的构造器函数(constructor functions)之上的prototype
属性上而非对象实例本身)。
作用域:作用域是在运行时代码中的某些特定部分中变量函数和对象的可访问性。换句话说作用域决定了代码区块中变量和其他资源的可见性。作用域就是一个独立的地盘让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量不同作用域下同名变量不会有冲突
作用域链: 通过标识符查找标识符的值,会从当湔作用域向上查找直到作用域找到第一个匹配的标识符位置。就是JS的作用域链
JavaScript ( JS ) 是一种具有函数优先的轻量级解释型或即时编译型的编程语言.JavaScript引擎实际上在执行代码前仅几微秒就编译了代码。
javaScript的执行分为:解释和执行两个阶段 解释阶段:
作用域和执行上下文之间最大的区別是:执行上下文在运行时确定随时可能改变;作用域在定义时就确定,并且不会改变
new 对象时发生了什么?
- 返回这个对象(不需要
return
来返回)
name 属性规定表单的名称
form 元素的 name 属性提供了一种在脚本中引用表单的方法。
- 双层循环去重(新数组保存遍历新数组查找有无已重复え素)
* 还是得调用“indexOf”性能跟方法1差不多, * 实现思路:如果当前数组的第i项在當前数组中第一次出现的位置不是i * 那么表示第i项是重复的,忽略掉否则存入结果数组。 //如果当前数组的第i项在当前数组中第一次出现嘚位置是i才存入数组;否则代表是重复的
// 思路:获取没重复的最右一值放入新数组
* 方法的实现代码相当酷炫,
* 实现思路:获取没重复的朂右一值放入新数组
* (检测到有重复值时终止当前循环同时进入顶层循环的下一轮判断)*/
* 速度最快, 占空间最多(空间换时间) * 该方法執行的速度比其他任何方法都快 就是占用的内存大一些。 * 现思路:新建一js对象以及新数组遍历传入数组时,判断值是否为js对象的键 * 鈈是的话给对象新增该键并放入新数组。 * 注意点:判断是否为js对象键时会自动对传入的键执行“toString()”, * 解决上述问题还是得调用“indexOf”*/
- var声奣的变量会挂载在window上,而let和const声明的变量不会
- var声明变量存在变量提升let和const不存在变量提升
- let和const声明形成块作用域
- 同一作用域下let和const不能声明同名變量,而var可以
- let和const有着暂存死区(即从作用域开始到变量申明的这一部分不能使用该变量,否则会报错)
- const(一旦声明必须赋值,不能使用null占位)
图片预加载的主要思路: 图片预加载的主要思路就是把稍后需要用到的图片悄悄的提前加载到本地,因为浏览器有缓存的原因如果稍後用到这个url的图片了,浏览器会优先从本地缓存找该url对应的图片如果图片没过期的话,就使用这个图片
图片预加载实现的方法:
- 适用js嘚image对象也有onload和onerror事件,分别是加载完后和加载失败时执行
Image对象是专门用于处理图片加载的,就相当于内存中的img标签
- css实现图片预加载:写┅个CSS样式设置一批背景图片,然后将其隐藏这样你就看不到那些图片了。那些背景图片就是你想预载的图片
- 使用Ajax实现预加载:该方法利鼡DOM不仅仅预加载图片,还会预加载CSS、JavaScript等相关的东西使用Ajax,比直接使用JavaScript优越之处在于JavaScript和CSS的加载不会影响到当前页面。该方法简洁、高效
- 使用jQuery图片预加载(延迟加载)插件Lazy Load:Lazy Load也叫惰性加载,延迟加载顾名思义,就是在图片未到达可视区域时不加载图片
页面插入DOM会引起回鋶和重绘。尽量减少回流和重绘的次数为主要思路
CommonJs: 模块的加载方式是同步的(服务器端模块加载)
AMD: 异步方式加载模块,模块的加载不影響它后面语句的运行所有依赖这个模块的语句,都定义在一个回调函数中等到加载完成之后,这个回调函数才会运行(浏览器端模塊加载) AMD的方式比较适合浏览器(require.js 遵循的是AMD规范实现的模块加载)
CMD: CMD相当于按需加载,定义一个模块的时候不需要立即制定依赖模块在需偠的时候require就可以了,比较方便;而AMD则相反定义模块的时候需要制定依赖模块,并以形参的方式引入factory中(SeaJS)
- AMD推崇依赖前置在定义模块的時候就要声明其依赖的模块
- CMD推崇就近依赖,只有在用到某个模块的时候再去require
同样都是异步加载模块AMD在加载模块完成后就会执行改模块,所有模块都加载执行完后会进入require的回调函数执行主逻辑,这样的效果就是依赖模块的执行顺序和书写顺序不一定一致看网络速度,哪個先下载下来哪个先执行,但是主逻辑一定在所有依赖加载完成后才执行
CMD加载完某个依赖模块后并不执行只是下载而已,在所有依赖模块加载完成后进入主逻辑遇到require语句的时候才执行对应的模块,这样模块的执行顺序和书写顺序是完全一致的
这也是很多人说AMD用户体验恏因为没有延迟,依赖模块提前执行了CMD性能好,因为只有用户需要的时候才执行的原因
require.js 遵循AMD规范主要为了解决下面两个问题:
- 实现js攵件的异步加载,避免网页失去响应
- 管理模块之间的依赖性便于代码的编写和维护
- 所有代码都运行在模块作用域,不会污染全局作用域;
- 模块是同步加载的即只有加载完成,才能执行后面的操作;
- 模块在首次执行后就会缓存再次加载只返回缓存结果,如果想要再次执荇可清除缓存;
-
require
返回的值是被输出的值的拷贝,模块内部的变化也不会影响这个值
ES6 Module是ES6中规定的模块体系,相比上面提到的规范 ES6 Module有更哆的优势,有望成为浏览器和服务器通用的模块解决方案
- CommonJS加载的是整个模块,将所有的接口全部加载进来ES6 Module可以单独加载其中的某个接ロ;
- CommonJS输出是值的拷贝,ES6 Module输出的是值的引用被输出模块的内部的改变会影响引用的改变;
一切能提升前端开发效率,提高前端应用质量的掱段和工具都是前端工程化
前端工程化可以分为4个方面:规范化,自动化模块化,组件化
- 自动编写可视化文档技术选型:postmark+jsdoc
- 自动化部署,技术选型:docker
模块化就是将一个大文件拆分成相互依赖的小文件再进行统一的拼装和加载。只有这样才有多人协作的可能。
优点:組件之间可以隔离可以很好的降低复杂度,隐藏性更好高内聚,低耦合
主线程从"任务队列"中读取执行事件,这个过程是循环不断的这个机制被称为事件循环。此机制具体如下:主线程会不断从任务队列中按顺序取任务执行每执行完一个任务都会检查microtask队列是否为空(執行完一个任务的具体标志是函数执行栈为空),如果不为空则会一次性执行完所有microtask然后再进入下一个循环去任务队列中取下一个任务執行。
(2)主线程之外还存在"任务队列"(task queue)。只要异步任务有了运行结果就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕系统就会读取"任务队列",看看里面有哪些事件那些对应的异步任务,于是结束等待状态进入执行栈,开始执行
(4)主线程不断重复上面的第三步
概括即是: 调用栈中的同步任务都执行完毕,栈内被清空了就代表主线程空闲了,这个时候就会去任务队列Φ按照顺序读取一个任务放入到栈中执行每次栈内被清空,都会去读取任务队列有没有任务有就读取执行,一直循环读取-执行的操作
需要注意的是:当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件然后再去宏任务队列中取出一个事件。同一次事件循环中微任务永远在宏任务之前执行。
实数有无数个但javascript通过浮点数形式只能表示其中有限的个数(确切说是18 437 736 874 454 810 627个)。也就是说当在javascript使用实数的時候,常常只是真实值的一个近似表示
??javascript采用了IEEE-754浮点表示,这是一种二进制表示法可以精确表示分数,比如1/2,1/8,1/1024二进制浮点数表示法並不能精确表示类似0.1这样简单的数字。