发表于: 2019-10-15 21:07:28
1 826
今天完成的事:看了一点es6和小课堂
明天要完成的事:任务2js写然后看es6文档;和小课堂
难题:文档太多看起来想吐;
收获:接着昨天的:
let:let
不允许在相同作用域内,重复声明同一个变量。因此不能在函数内部重新声明参数。
暂时性死区:在代码块内,使用let
命令声明变量之前,该变量都是不可用的;
总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
解构赋值是对赋值运算符的扩展。
他是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。
在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。
这个我最开始没看懂:后面去百度理解了不少
解构赋值允许指定默认值。
let [foo = true] = [];foo // true
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
注意,ES6 内部使用严格相等运算符(===
),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined
,默认值才会生效。
数组解构规则:
1.左右两边顺序是一一对应的
2.左右两边结构必须是一样的(模式匹配)
3.可以缺省,缺省时赋值为undefined
4.可以指定默认值
经被声明或者赋值的变量的解构赋值
针对已经被赋值的变量,我们用一个小括号把它们包裹起来方可解构赋值:
三、对象的解构赋值
规则:
1.左右两边的顺序可以不对应,但是右边的匹配名称很重要
2.左右两边结构必须是一样的(模式匹配)
3.可以缺省,缺省时赋值为undefined
4.可以指定默认值
5.变量的可以简写
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
先看赋值运算符(=)左侧的键值对中,冒号左边实际上用于匹配而不是真正的变量名称,冒号右边才是真正的变量名称。
同理,赋值运算符(=)右侧也是冒号左边用于匹配,右边则用于赋值。
字符串的解构赋值
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
类似数组的对象都有一个length
属性,因此还可以对这个属性解构赋值。
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined
和null
无法转为对象,所以对它们进行解构赋值,都会报错。
解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道。
由此带来的问题是,如果模式中出现圆括号怎么处理。ES6 的规则是,只要有可能导致解构的歧义,就不得使用圆括号。
但是,这条规则实际上不那么容易辨别,处理起来相当麻烦。因此,建议只要有可能,就不要在模式中放置圆括号。
用途
变量的解构赋值用途很多。
(1)交换变量的值
从函数返回多个值
函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。
)遍历 Map 结构
任何部署了 Iterator 接口的对象,都可以用for...of
循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。
7)输入模块的指定方法
加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。
不能使用圆括号的情况
以下三种解构赋值不得使用圆括号。
(1)变量声明语句
2)函数参数
函数参数也属于变量声明,因此不能带有圆括号。
赋值语句的模式
上面代码中,最后一个例子表明,大括号表示法与四字节的 UTF-16 编码是等价的。
有了这种表示法之后,JavaScript 共有 6 种方法可以表示一个字符。
'\z' === 'z' // true
'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true
'\u{7A}' === 'z' // true
上面代码表示,如果直接在\u后面跟上超过0xFFFF的数值(比如\u20BB7),JavaScript 会理解成\u20BB+7。由于\u20BB是一个不可打印字符,所以只会显示一个空格,后面跟着一个7。
ES6 对这一点做出了改进,只要将码点放入大括号,就能正确解读该字符。
看到这实在看不下去了停一会
ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名
Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的 Symbol 提供描述,用来显示在控制台或者作为字符串的时候使用,便于区分
使用场景
作为属性名
用法
由于每一个 Symbol 的值都是不相等的,所以 Symbol 作为对象的属性名,可以保证属性不重名。
Symbol 作为对象属性名时不能用.运算符,要用方括号。因为.运算符后面是字符串,所以取到的是字符串 sy 属性,而不是 Symbol 值 sy 属性。
先看一下小课堂吧:这文档想吐太多了
return 语句的作用是从当前函数退出,并从那个函数返回一个值。
用 return 语句来终止一个函数的执行,并返回 expression 的值。如果 expression 被省略, 或在函数内没有 return 语句被执行,则把值 undefined 赋给调用当前函数的表达式。
一、返回控制与函数结果,
语法为:return 表达式; 语句结束函数执行,返回调用函数,而且把表达式的值作为函数的结果
二、返回控制,
无函数结果,语法为:return;
在大多数情况下,为事件处理函数返回false,可以防止默认的事件行为.例如,默认情况下点击一个<a>元素,页面会跳转到该元素href属性指定的页.
Return False 就相当于终止符,Return True 就相当于执行符。
在js中return false的作用一般是用来取消默认动作的。比如你单击一个链接除了触发你的
onclick时间(如果你指定的话)以外还要触发一个默认事件就是执行页面的跳转。所以如果
你想取消对象的默认动作就可以return false。
return false 只在当前函数有效,不会影响其他外部函数的执行。只是跳出当前位置进入上一级;
return用在for循环中,for循环只返回return所返回的值,并不会执行下一次循环。
三:总结
retrun true; 返回正确的处理结果。
return false;返回错误的处理结果,终止处理。
return;把控制权返回给页面。
四:区别
1. return;返回null,起到中断方法执行的效果,只要不return false事件处理函数将会继续执行,表单将提交
2. return false;,事件处理函数会取消事件,不再继续向下执行。比如表单将终止提交。
break语句:
break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch语句。由于它是用来退出循环或者switch语句,所以只有当它出现在这些语句时,这种形式的break语句才是合法的。
continue语句:
continue语句和break语句相似。所不同的是,它不是退出一个循环,而是开始循环的一次新迭代。
continue语句只能用在while语句、do/while语句、for语句、或者for/in语句的循环体内,在其它地方使用都会引起错误!
简单来说就是执行到continue之后就停下,然后重新开始;
浏览器获取事件的两种方式:事件冒泡和事件捕获
delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。
使用 delegate() 方法的事件处理程序适用于当前或未来的元素(比如由脚本创建
Event 对象
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,函数不会在事件发生前被执行!
事件处理程序可以为现代web应用程序提供交互能力,因此许多开发人员会向页面中添加大量的处理程序。
但是在JavaScript中,添加到页面中的事件处理程序的数量会直接影响页面的整体运行性能。
理由:1.每个函数都是对象,都会占用内存。
2.事先指定所有的事件处理程序会导致DOM的访问次数增加,会延迟整个页面的交互时间。 对“事件处理程序过多”问题的解决方案就是事件委托(Delegation)。
事件委托的原理
事件委托是利用事件的冒泡原理来实现的,何为事件冒泡呢?
就是事件从最深的节点开始,然后逐步向上传播事件,
事件冒泡:先触发子元素的事件,再触发父元素的事件
事件捕获:先触发父元素的事件,再触发子元素的事件
主流浏览器均支持且优先使用事件冒泡机制
优点:
1.大量减少内存占用,减少事件注册。
2.新增元素实现动态绑定事件
看着小课堂里对事件委托的解释:感觉教材就是把简单的东西变复杂有木有?
为了方便理解,我先把事件委托的作用写一下。
支持为同一个DOM元素注册多个同类型事件
可将事件分成事件捕获和事件冒泡机制
实现方式:
一、可用addEventListener(); //所有主流浏览器,除了IE8及更早IE版本。
1.语法:element.addEventListener(event, function, useCapture);
event:必须。字符串,指定事件名。 不加'on',如click
function:必须。指定要事件触发时执行的函数。
useCapture:可选。布尔值,指定事件是否在捕获或冒泡阶段执行(true-事件句柄在捕获阶段执行;false-默认。事件句柄在冒泡阶段执行)。
2.移除事件监听:element.removeEventListener(event, function,useCapture)。移除时传入的参数与添加处理程序时使用的参数相同。这也意味着通过addEventListener()添加的匿名函数无法移除。
3.功能:可多次绑定同一个事件,并且不会覆盖上一个事件
二、attachEvent() //IE8及IE更早版本
1.用法:element.attachEvent(event,function);
(1)event事件加'on',onClick
(2)没有第三个参数,因为IE只有冒泡,没有反向冒泡。
(3)执行顺序按照绑定的反序(先执行后绑定的方法)。
2.移除事件监听:element.detachEvent(event,function)
事件捕获
当一个事件触发后,从Window对象触发,不断经过下级节点,直到目标节点。在事件到达目标节点之前的过程就是捕获阶段。所有经过的节点,都会触发对应的事件
事件捕获:
当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,
随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。
在这个过程中,事件相应的监听函数是不会被触发的。
事件目标:
当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。
事件冒泡
当事件到达目标节点后,会沿着捕获阶段的路线原路返回。同样,所有经过的节点,都会触发对应的事件
事件起泡:
从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被触发
(简单来说:就是给元素添加一个方法使其拥有某种事件并且useCapture为false时则为事件冒泡为true时则为事件捕获)为冒泡时则向上一级元素执行同样的事件知道window,为捕获时则是从元素向下执行同样的事件元素的每个子元素都会执行
适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。(所有用到按钮的事件,多数的鼠标事件和键盘事件)
值得注意的是,mouseover和mouseout虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。
不适合的就有很多了,举个例子,mousemove,每次都要计算它的位置,非常不好把控,在不如说focus,blur之类的,本身就没用冒泡的特性,自然就不能用事件委托了。
对冒泡啥的到是理解了target没太明白
评论