1.包含在函数内的代码叫做函数代码,而在所有函数以外的代码叫做全局代码
2.js不能选择和修改还没创建的节点,所以script要放在底部
3.所有在某个js代码执行期间用户创建的全局变量都能正常的被其他脚本元素中的js代码所访问到。
4.addeventListener可以为dom注册多个事件
5.箭头函数 ,如果函数体是一个代码块,那么返回值则与普通函数一样,如果没有return语句,返回值是undefined,反之,返回值就是return表达式的值。例如:
var a=(()=>{"bbb"})();//a=undefined
var a=(()=>{return "bbb";})();//a="bbb"
6.argumrnts[x]改变,会影响对应的函数参数值
function a(aaa){
console.log(aaa);
arguments[0]=12;
console.log(aaa);
}
a(1);
//1
//12
7.this的值:
7.1作为函数直接被调用时,非严格模式下this的值为window,严格模式下this的值为undefined
如果一个函数没有作为方法、构造函数或者通过apply和call调用的话,我们就称之为函数被直接调用
function a(){return this;};
a();//this为window
var a=function(){return this;};
a();//this为window
(function(){return this;})();//this为window
7.2当函数被赋值给对象的属性,并通过对象属性引用的方式调用时,this的上下文就是这个对象,例如:
function getName(){return this;};
var a={
name:getName,
age:12
}
console.log(a.name());//{name: ƒ, age: 12}
7.3当使用new调用函数时:
1. 创建一个空对象
2. 该对象作为this参数传递给构造函数,从而成为构造函数的函数上下文
3. 新构造的对象作为new运算符的返回值
构造函数的目的是创建一个新对象,并进行初始化设置,然后将新对象作为构造函数的返回值
构造函数的返回值:
如果构造函数返回一个对象,则该对象将作为整个表达式的值返回,而传入构造函数的this将被丢弃
如果构造函数返回的是非对象类型,则忽略返回值,返回新创建的对象。
例如:
function a(){
this.b=function(){return this;}
return 1;
};
var c=new a();
console.log(c);// a {b: ƒ}
var d={e:false}
function a(){
this.b=function(){return this;}
return d;
};
var c=new a();
console.log(c);// {e: false}
构造函数通常以所描述的构造对象的名词命名,以大写字母开头
8. 不能将一个全新的值赋给const变量,但是,我们可以修改const已有的变量,例如数组 push值和对象添加属性
9.var声明的变量实际上总是在距离最近的函数内或者全局词法环境中注册的,不关注块级作用域,所以以下代码:
function a(){
for(var i=0;i<2;i++){
var f=12;i++
}
console.log(i,f)
}
a();//2 12
for循环内就是块级作用域,所以脱离for循环仍可以访问
10.js对于在哪儿定义函数并不挑剔,在调用前和调用后声明函数都可以,函数声明可以在函数声明前后调佣,函数表达式和箭头函数则不行。
11.第112页
12.先是函数声明,然后再是变量提升(fun=undefined)
console.log(fun);//输出的是函数而不是undefined
var fun=3;
function fun(){};
13.next方法返回一个携带着生成值的对象,该对象中包含着另一个属性done也向我们指示了生存器是否还会追加生成值
14.如果需要为生成器提供一个初始值,可以调用生成器自身,就像n("aaa");
function* a(b){
var c=yield(1+b);
console.log(c,111);//3
return yield(c+b);
}
var ss=a(1);
var dd=ss.next(2);console.log(dd.value);
var cc=ss.next(3);console.log(cc.value);
输出:
2
3 111
4
上面的过程:
首次调用yield(1+b),a函数开始执行,直到遇到第一个yield
表达式为止。next
方法返回一个对象,它的value
属性就是当前yield
表达式的值2
,done
属性的值false
,表示遍历还没有结束
第二次调用,函数从上次yield
表达式停下的地方,一直执行到下一个yield
表达式。next
方法返回的对象的value
属性就是当前yield
表达式的值c+b,done
属性的值false
,表示遍历还没有结束。而c的值为第二次调用时所传参数
总的来说,像c这样的,第n个的c的值会是第n+1次next的传参
16.一般情况下,当程序从一个标准函数返回后,对应的执行环境上下文会从栈中弹出。并被完整地销毁,但在生成器中不是这样,拿上述代码来说,var dd=ss.next(2);语句执行后,产生了一个值,一般情况下相对应的函数a的执行上下文会从栈中弹出,但在生成器里由于ss还保存着对他的引用,所以他不会被销毁,所以后面还能接着next,你可以把它看作一种类似闭包的事物。谨记一点,当我们从生成器中取得控制权后,生成器的执行环境上下文是一直保存的。
16.第140页
17.primise 状态确定后就不会变了
var p=new Promise((r,e)=>{
r(1);
e(3);
});
p.then((v)=>{console.log(v,222);})
.catch(e=>{console.log(e,111)});
结果只输出1,222,也就是只执行了then
18.
function* Gen(val){
val=yield val*2;
yield val;
}
var gen=Gen(2);
console.log(gen.next(3).value);//4
console.log(gen.next(5).value);//5
输出的原因:看看上面14就知道了,差不多的代码。
19.Object.setPrototypeOf() 方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或 null
。
20.constructor属性是创建实例对象的函数的引用。
21.instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置,通过执行instanceof操作符,我们可以判断函数是否继承原型链上的对象功能。instanceof函数的真正语义是检查右边的函数原型是否存在于操作符左边的对象的原型链上。所以能解释下面的输出:
function A(){};
var a=new A();
A.prototype={};
console.log(a instanceof A);//false
22.如果想调整属性的配置信息看使用Object.defineProperty方法,该方法传入3个属性:属性所在对象,属性名,属性描述对象
23.static可以定义静态方法,静态方法new出来的实例不能访问,class本身可以访问。
24.在class a extends A{}的写法里面,a通过super关键字调用了基类Person的构造函数。
25.可以通过defineProperty+get和set实现私有对象,例如:
function A(){
let _c=0;
Object.defineProperty(this,'c',{
get:()=>{return _c;},
set:(val)=>{_c=val;}
})
}
var a=new A();
console.log(a.c);//0
a.c=10;
console.log(a.c);//10
26.可以利用getset对数据赋值前进行一些校验和计算。
27.使用代理可以实现控制访问,检测性能,控制日志,自动填充属性等。代理会带来性能问题,效率不高。
28.pop和push的速度比shift和unshift快,因为后者要调整所有顺序
29.find方法可返回第一个为true的元素,findIndex方法返回元素索引
30.map有get,set,size(映射数目),has,delete,clear
31.map可使用for of遍历,遍历时,可使用XXX.keys()遍历所有key,可使用XXX.vlues()遍历所有value,直接遍历map的话(for item of aaa),item[0]为key,item[1]为value。
32.p289页
33.commonjs是node.js的语法,不显式的支持浏览器,
34.导入模块默认导出的内容,不需要使用{},可以任意指定名称。导入已命名的导出内容必须使用花括号
35. .id和set/getAttribute()是差不多的,但是对于自定义的属性,我们只能用set/getAttribute()访问
36.样式对象(.style)中不反映从css样式表中(style或者外部样式文件)继承的任何样式信息。例如:
<style>
div {
color: black;
}
</style>
<script>
window.onload = function() {
const div = document.querySelector('div');
console.log(div.style.color);
console.log(div.style.borderWidth);//无输出
}
</script>
</head>
<body>
<div style="border:1px solid #000">565464</div>
</body>
37.getComputedStyle(),有两个参数,元素和伪类。第二个参数不是必须的,当不查询伪类元素的时候可以忽略或者传入 null
let my_div = document.getElementById("myDiv");
let content= window.getComputedStyle(my_div, '::after').content;
let style = window.getComputedStyle(div, null);
for (var i = 0; i < style.length; i++) {
let item = style[i];
console.log(" " + item + " : " + style.getPropertyValue(item) + "\n");
}
38.隐藏元素的offsetWidth和offsetHeight为0,要获取隐藏元素的宽高,可以这样来:
1.display:block; 2.visibility:hidden; 3.position:absolute 4.获取尺寸 5.恢复尺寸
39.批量的读写修改style属性可以优化性能
40.单次循环迭代中,最多处理一个宏任务,而队列里所有的微任务都会被处理
41.P335-P347
在微任务完成之前都不允许重新渲染页面,无法停止微任务运行
42.addEventListener第三个参数为true表示采用事件捕获,反之为事件冒泡。默认采用事件冒泡
43.在事件处理器内部,this指向事件处理器所注册的元素(XXX.addEventListener,this就指向XXX),不一定是发生事件的元素(考虑到事件冒泡和事件捕获),而event.target会始终指向发生事件的元素,例如点击div的时候,body上的this会指向body,但是event.target会始终指向div.
44.自定义事件
function trigger(target,eventType,eventDetail){
const event=new CustomEvent(eventType,{detail:eventDetail});
target.dispatchEvent(event);
}
45.const {name:myname,age:myage} from obj;
46.chrome可以添加条件断点,console.assert可以做断言