js基础
变量类型和计算
1.js只有两种储存方式类型:值类型和引用类型
值类型:字符串string 、数字number、布尔值boolean、null、undefined
引用类型:对象object、数组arrary、函数function
2.值类型和引用类型区别:
值类型:保存与复制的是值本身,使用typeof检测数据的类型
引用类型:保存与复制的是指向对象的一个指针,使用instanceof检测数据类型,使用new()方法构造出的对象是引用型
例: arr instanceof Array; 变量arr是否是数组
3.JSON不过是js对象而已:
JSON.stringify({a:10,b:20}) //将对象转化为字符串,常用保存'{"a":10,"b":20}'
JSON.parse('{"a":10,"b":20}') //将字符串转化为对象,常用获取{a:10,b:20}
4.变量计算:强制转化类型
A.字符串拼接:10+'10' //数字加字符串,会转化为字符串'1010'
B.==和===:100=='100' //true ''==0 //true null==undefined //true
===不会进行强制类型转化
C.if() 条件里面 字符串、数字都会转化为true,但是'空字符串'、0、NaN、null、undefined为转化为false
原型和原型链
1.构造函数:默认是返回一个this是空对象,我们所做的,就是不断扩充这个空对象
2.原型规则:
A.所有引用类型(数组、对象、函数),都具有对象的特性,即可自由扩展属性
B.所有引用类型(数组、对象、函数),都有一个隐式原型__proto__属性,属性值是一个普通对象
C.所有引用类型(数组、对象、函数),都有一个显示原型prototype属性,属性值是一个普通对象
D.所有引用类型(数组、对象、函数)的隐式原型__proto__属性指向构造函数的显示原型prototype属性
当我们试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会从它的__proto__(即它的构造函数中的prototype)中寻找;
如下这个例子:
f是new一个函数,那么f就有对象特征,
当调用f.alertName()时,f本身是没有这个属性,就找不到,
此时,f.__proto__就会悄悄指向f的构造函数Foo.prototype属性,
并引导f在Foo.prototype上找alertName属性,
扩展:f.hasOwnProperty(item)判断是否是原型上的属性
for...in会将所有属性循环,加上判断,只输出原型上的属性
3.原型链: 原型继承就用到原型链的概念
const f=new Foo();实例化一个对象
当要获取f的一个属性,而f本身没有时,f.__proto__就会指向Foo.prototype属性上找,
如果Foo.prototype上还是没有,而Foo.prototype本身也是一个对象,也有__proto__属性
Foo.prototype.__proto__就会指向Object.prototype属性上找,
Object.prototype也有__proto__属性,但会指向null,JS防止死循环做的最终处理
作用域和闭包
1.变量提升:不仅全局有变量提升,而且函数内部也遵循变量提升规则
在JS机制中var 开头变量,在JS执行过程中,首先会被提升到最前面占位,然后赋值undefined,所以下面第一个打印是undefined
在JS机制中function开头,在JS执行过程中,首先会被提升到最前面占位,但不会读取函数内部,当调用函数时,才会读取函数内部;所以下面fn()执行后能打印出1
2.this:要在执行时才能确认值,定义时无法确认
扩展.call()和apply()属于Function.prototype的属性,所以每个函数都有这两个方法,可以改变this的指向;
区别,传递参数方式不同,call()参数必须依次写,apply()是数组;
简单理解就是:call字段前的方法给call字段后的方法用,例:num.call(obj,3,4); 将num函数给obj用,num里面的this就指向obj, 顺便传递3,4参数进去
3.作用域链:注意,是从里面向外面找,比较违背常理,要注意
例打印a的值,会先在f2的作用域找,找不到就在f1作用域找,再找不到,就去最外面的作用域找,一旦找到,就停止,这就是作用域链
4.闭包:函数作为返回值,函数作为参数传递,闭包其实核心原理就是作用域链
经典闭包案例:
错误案例:
正确方式1:使用es6的let
正确方式2:使用闭包
异步与同步:JS的执行时单线程的
异步:在单线执行时,也可以同时执行其他的,
同步:从头到尾执行下去
区别:同步会阻塞代码的执行,异步不会
异步使用场景:
定时任务:setTimeout、setInterval
网络请求:ajax请求,动态<img>加载
事件绑定
日期和math
1.日期date:
补充:dt.getDay() //获取今天是星期几
扩展:var dt = new Date(''2019/09/20 10:08:00');
就可以获取指定的时间信息
2.Math:
数组API
1.forEach:对数组循环,可接收三个参数,值、下标、循环的数组
缺点:无法修改数组数据,不能终止循环,break,continue不能使用
扩展:for...in for...of
for..in扩展的属性也会遍历,常用来遍历对象
for...of常用来遍历数组,可以弥补forEach的缺点
2.every():用来判断所有的数组元素,是否都满足一个条件
some():用来判断数组中元素,只要有一个满足条件,都返回true;
3.sort():数组排序
4.map():将数组元素每一个重新包装,返回一个新的数组
5.filter():通过条件过滤数组元素,返回一个新的数组
对象API
for..in遍历对象,但是注意会遍历扩展的属性
注意:有时候 需要用obj.hasOwnProperty(item)判断是否是原型上的属性