1、javascript 单线程,同步执行(一个等一个,一个完成在执行下一个)
2、变量、函数声明提前
变量定义会声明提前,赋值留在原地,后面会覆盖前面
函数是一等公民,会提前到变量之前,定义赋值同步提升
3、函数名指针,指向一个地址(存储空间):堆内存 (先进先出)
4、函数执行会将上下文压入执行环境栈:栈内存(先进后出,后进先出)
5、变量和函数会在不用的时候,或者浏览器关闭的时候自动销毁
6、作用域:变量或函数起作用的区域(生命周期),分为全局及私有作用域,私有作用域内部变量(局部变量),外部无法访问
7、作用域链:如果当前有,使用自己的,如果当前没有,继续往上查找,形成的链式结构
8、匿名函数自调:形成私有作用域不受外界干扰改变内部变量,定义执行
9、this:指针对象,指向当前调用的对象,默认指向全局window
10、数据类型:基本、引用,基本是操作值,引用是操作地址
11、闭包:内部地址(私有作用域)被外部的变量引用,从而无法释放内存,作用:延长生命周期,保护局部变量,外部可以获取函数内部变量,缺点:内存泄漏
12、javascript中一切皆对象
13、 Object是基类
14、对象都是通过函数创建的
15、函数的父类是对象,对象的父类是函数
16、javascript中一切函数实际都是函数对象,函数是一种特殊的对象,函数对象(Objcect、Function)有prototype和__proto__
17、 Array,Number,String等这些内置对象是Object的子类,也是Function的子类
18、proto__低版本IE浏览器,存在兼容问题
19、对象有__proto(原型指针),函数有prototype原型,函数对象既有prototype,也有__proto__
20、函数有arguments(类数组对象),name(函数名,不常见:(undefined:匿名函数自调),("":无名函数),(anonymousnew:Function方式创建),(bind 函数名:通过bind方式创建的函数)),length(缺省为形参长度,当形参有缺省值,length为当前有缺省值的形参下),call,apply,bind,caller属性,call,apply,bind方法是Function原型上的方法,是在Function原型上的一个方法,故所有实例化的对象都可以使用
21、arguments
arguments有callee属性
作用:指向正被执行的 Function 对象,也就是函数本身,表示对函数对象本身的引用
arguments有length属性
arguments.length是实参长度
arguments.callee.length是形参长度
var fn= function(a){
console.log(arguments.length);//2
console.log(arguments.callee.length);//1
return "fn"
}
console.log(fn(1,2));
22、call是一个对象,是在Function原型上的一个方法,故所有函数都有call方法
作用:让函数执行,改变函数的this(指针),第一个参数为改变this的参数(不可以省略),第二个参数为接收参数
var fn= function(a){
console.log(this.name) // window.name缺省为空
}
fn();
var obj={
name:'shi'
}
fn.call(obj,1); //shi fn函数执行,改变fn的this为obj
----------------------------------------------------------------------
var fn= function(){
console.log(this); // Number对象实例,Number对象没有name属性
console.log(typeof(this)); //object
console.log(this instanceof Object); // true
console.log(this instanceof Function);// false
console.log(this instanceof Number);// true
}
// fn();
var obj={
name:'shi'
}
fn.call(obj,1)
fn.call(1);//转换为包装类型new Number(1)去改变函数this,第一个参数不可以省略
23、apply和call作用相当,区别为第二个参数是接收数组
fn.apply(obj,[1,2,3]);
//借助apply求数组最大值
var ary=[1,2,3,4,5];
var max = Math.max.apply(null,ary)
console.log(max);
24、bind和call类似,改变this
区别:call会执行,而bind不会
call、bind 综合实例:
function change(n){
this.innerHTML=parseInt(this.innerHTML)+n;
}
box.onclick=function(){
change.call(this,2)
}
box.onclick=function(){
this.change = change;
this.change(1);
}
// 借助第三个参数
// setInterval(function(ele){
// ele.change=change;
// ele.change(1)
// },1000,box)
// 使用call改变change指针
// setInterval(function(){
// change.call(box,2)
// },1000)
//bind于call类似,改变this
//区别:bind 不会执行
setInterval(change.bind(box,1),1000)
25、caller指向调用当前函数的引用,说明这个函数调用了当前函数
26、检测数据类型
typeof 仅检查基本数据类型,null为object ,引用数据类型不可详细检测,为Object或Function
instanceof 检测一个实例是否属于某个类,对于基本数据类型,使用字面量方式创建的结果为false,构造函数方式创建可以检测
constructor 获取数据类型
// var ary=[1,2,3,4,5];
// console.dir(ary);
// console.log(ary.__proto__);//数组通过new Array 方式创建,Array函数对象(类)的原型(__proto__)上有constructor 指向Array,所以construcotr.name 就是当前所属函数对象(类)的名字
// console.log(ary.constructor.name);//Array
Object.prototype.toString.call("1").slice(8,-1); // [object String].slice(8,-1) -> String
27、for in 遍历对象
遍历会将自有的和原型上的方法都遍历出来,需要使用hasOwnProperty过滤,只要私有的
Object.getOwnPropertyDescriptor(FF.prototype,"counstructor")
configurable: true //是否可配置
enumerable: false//是否可枚举,true属性的可以使用for in
value: ƒ ()
writable: true //是否可写
28、eval 函数可计算某个字符串,并执行其中的的 JavaScript 代码
改变数据类型
// var aryStr='[1,2,3,4,5]';
// var ary=[1,2,3,4,5];
// var obj={a:1,b:2};
// var objStr='{a:1,b:2}'
// //字符串数组转为数组
// console.log(eval(aryStr));
// //字符串对象转为对象
// console.log(eval("("+objStr+")"));
29、window 对象有JSON对象,JSON有两个方法
//将JSON对象转为JSON字符串
JSON.stringify(obj)
JSON.stringify(ary) //数组也是对象,也可以转
//将JSON字符串转为JSON对象
JSON.parse(str)
30、重写数组方法
//var ary=[1,2,3,4,5];
//末尾出去一个,并返回当前弹出元素
// Array.prototype.pop=function(){
// var num = this[this.length-1];
// this.length--;
// return num;
// }
// console.log(ary);
// ary.pop();
// console.log(ary);
//末尾进来一个或者多个
// Array.prototype.push=function(){
// for(var i=0;i<arguments.length;i++){
// this[this.length] = arguments[i];
// }
// }
// ary.push(4,5);
// console.log(ary);
// Array.prototype.shift=function(){
// var num = this[0];
// for(var i=1;i<this.length;i++){
// this[i-1]=this[i];
// }
// this.length--;
// return num;
// }
// //前面出去一个,并返回当前元素
// ary.shift();
// console.log(ary);
// Array.prototype.unshift=function(){
// var str='';
//两数组拼接
// for(var i=0;i<arguments.length;i++){
// str+=arguments[i]+',';
// }
// for(var i=0;i<this.length;i++){
// str+=this[i]+',';
// }
// 字符串转换为数组
// var ary= eval("["+str+"]");
// this.length = ary.length;
//将新数组赋值回原数组,达到改变原数组的目的
// for(var i=0;i<ary.length;i++){
// this[i]=ary[i];
// }
// return ary.length;
// }
// // //前面进来一个或者多个,并返回元素的长度
// console.log(ary.unshift(0,1));
// console.log(ary);
31、重写call方法
function fn(){
console.log(this);
}
var obj={"name":"shi"};
Function.prototype.call=function(){
//参数为空执行,执行当前函数
if(arguments == undefined){
this();
}else{
//如果传进来的第一个参数不是对象,将第一个参数转换为对象
var obj = Object(arguments[0]);
//在对象所属类的原型上添加fn方法
obj.__proto__.fn = this;
//执行
obj.fn();
//使用完之后删除
delete obj.fn;
}
}
fn.call(obj,1,2,3);
下面通过一个实例说明一下对象与函数的关系
// 构造函数对象(类)存在prototype(原型对象)和__proto__(原型指针,指向所属的函数对象(类)的原型->Function prototype)
// 构造函数对象(类)的prototype(原型对象)中存在constructor和__proto__(原型指针)
// 构造函数对象(类)的prototype(原型对象)的constructor 指向当前构造函数
// 构造函数对象(类)的prototype(原型对象)的__proto__(原型指针,指向所属的函数对象(类)的原型->Object prototype)
// Object 函数对象存在prototype(原型对象)和__proto__(原型指针,指向所属的函数对象(类)的原型->Function prototype
// Object 函数对象存在prototype(原型对象)中存在constructor
// Object prototype(原型对象)中的constructor 指向所属的函数对象(类)->Object
// Object prototype(原型对象)中无__proto__,因为Object已经处于原型链最顶端,无法继续往上查找
// Function 函数对象(类)存在prototype(原型对象)和__proto__(原型指针,指向所属的函数对象(类)的原型->Function prototype)
// Function 函数对象(类)的prototype(原型对象)中存在constructor和__proto__(原型指针)
// Function 函数对象(类)的prototype(原型对象)中的constructor 指向所属类->Function
// Function 函数对象(类)的prototype(原型对象)中的__proto__(原型指针,指向所属的函数对象(类)的原型 ->Object prototype)
function fn(a){
this.a=a;
}
fn.prototype.getA=function(){//原型上存放共有方法
console.log(this.a);
}
//实例对象的原型指针,指向所属类的原型-> fn.prototype,fn函数对象的原型对象中的原型指针__proto__,指向所属的函数对象(类)的原型->Object prototype
// Object函数对象(类)的__proto__(原型指针,指向所属的函数对象(类)的原型 ->Function prototype)
var obj1 = new fn();//生成新对象
var obj2 = new fn();
var obj3 = new Function();
var obj4 = new Object();
// console.log(obj1.__proto__ == fn.prototype) //true
// console.log(obj1.getA == obj2.getA);//true
// console.log(fn instanceof Function)//true
// console.log(fn instanceof Object)//true 构造函数,即函数对象(类),即是函数,也是对象
// console.log(typeof(obj1)) //object
// console.log(obj1 instanceof Object)//true
// console.log(obj1 instanceof Function)//false 对象不是函数
// console.log(obj2 instanceof Object)//true
// console.log(obj2 instanceof Function)//false 对象不是函数
// console.log(typeof(obj3)) //function
// console.log(obj3 instanceof Object)//true
// console.log(obj3 instanceof Function)//true 基于函数对象(类)实例化出的实例既是对象,也是函数
// console.log(typeof(obj4)) //object
// console.log(obj4 instanceof Object)//true
// console.log(obj4 instanceof Function)//false 基于对象实例化出的实例是对象,不是函数
// console.log(Function instanceof Object) 函数的父类是对象,对象是基类
// console.log(Object instanceof Function) 对象的父类是函数,对象通过函数创建
// 类的实例的原型上的constructor指向的函数名就是当前函数对象(内置类)
// Number string object function
// undefined null 没有
var a=1;
var b='1';
var c=true;
var d=undefined;
var e=null;
var obj={a:'a'};
function fn(){
console.log(0111)
}
console.log([1,2,3,4].constructor.name);//Array
console.log(a.constructor.name);//Number
console.log(b.constructor.name);//String
console.log(c.constructor.name);//Boolean
console.log(d.constructor.name);//
console.log(e.constructor.name);//
console.log(obj.constructor.name);//Object
console.log(fn.constructor.name);//Function
--------------------------------------------------------------------
function Person(){
}
Person.prototype = {
name : "Nicholas",
age : 29,
job : "Software Engineer",
sayName : function () {
alert(this.name);
}
};
var person = new Person();
//person.constructor 指向所属类
console.dir(person.constructor.__proto__.__proto__); //person.contructor -> Object .__proto__ ->Function.prototype .__proto__ ->Object.prototype
console.log(Object.__proto__ == Function.prototype); //true
console.log(Object.__proto__.__proto__ == Object.prototype); //true
32、定时器是异步的,定时器使用完,不在使用的时候清除定时器
33、正则表达式
匹配字符串的规则
\b 单词边界
\B 非单词边界
\d 数字
\D 非数字
\w 数字、字母、下划线
\W 非数字、字母、下划线
\n 空格
. 任何单个字符
* 0或多
+ 1或多
? 0或1
^ 开头
$ 结尾
| 或
\ 转义
{n} 量词,至少匹配n 次
{n,} 量词,至少匹配n 次
{n,m} 量词,可以重复前面匹配的字符n-m次,至少n次,最多m次。
[] 任选其一
[^] 取反
() 组
// var reg=/\b666\b/; // 边界
// console.log(reg.test("666"));
// var reg=/\d/; // 数字
// console.log(reg.test("123a"));
// var reg=/\w/; //数字、字母、下划线
// console.log(reg.test("123a_"));
// var reg=/[0-9][a-z][A-Z_]/; //数字、字母、下划线
// console.log(reg.test("123a_"));
// var reg=/[^5|4]/; //不是5 或 4
// console.log(reg.test("6"));
// var reg=/^(1|2)$/;
// console.log(reg.test("2")); // 1 2
// var reg=/^[12]\d{2}$/;
// console.log(reg.test("112")); // 1 或 2 开头 两个数字结尾
// var reg=/^[1-5]$/;
// console.log(reg.test("1")); // 1 2 3 4 5
// var reg=/^[1-]$/; // 1 _
// console.log(reg.test("-"));
// var reg=/^[a-d]$/;//a b c d
// console.log(reg.test("d"));
// var reg=/^(1|2)|(3|5)$/; //1 2 3 4 5
// console.log(reg.test("5"));
// var reg=/1\d{10}/; // 手机号码
// console.log(reg.test("13552887318"));
// \1第一个分组的内容
var str="1aa";
var str2="1ee";
//var reg=/^1(\w)\1/;
//console.log(reg.test(str));//true
//console.log(reg.test(str2));//true
var reg=/[a-zA-z]([a-zA-z])\1[a-zA-z]/;
console.log(reg.test("look"));//true
test匹配一次仅匹配一个,查找到,不继续往后进行查找,如果想同时将字符串中所有符合的都查找出来,有两种方式:
1、使用while循环,将查找出的元素放入数组中,直到没有为止
2、使用match方法,可以一次性查找到,例如str.match(/1a/g);
exec捕获,结果4个属性:匹配到的元素,下标,原字符串,group
var reg=/\w/;
console.log(reg.exec("a1_")); //["a", index: 0, input: "a1_", groups: undefined]
注:如果捕获中有分组,会将分组补货内容,位于捕获内容和下标之间依次显示
var reg=/\w(\d)\w(\d)\w(\d)/;
console.log(reg.exec("a1b2v3d4")); //["a1b2v3", "1", "2", "3", index: 0, input: "a1b2v3d4", groups: undefined]
捕获应用:
//想单独捕获就使用分组,如果分组中的内容不想要,就在分组中添加?:
var str='html:2000+css:3000+js:4000+react:5000+vue:6000';
var reg=/(?:^|\+)([a-z]+:(\d+))/g;
console.log(reg.exec(str));// ["html:2000", "html:2000", "2000", index: 0, input: "html:2000+css:3000+js:4000+react:5000+vue:6000", groups: undefined]
console.log(reg.exec(str));//["+css:3000", "css:3000", "3000", index: 9, input: "html:2000+css:3000+js:4000+react:5000+vue:6000", groups: undefined]
console.log(reg.exec(str));//["+js:4000", "js:4000", "4000", index: 18, input: "html:2000+css:3000+js:4000+react:5000+vue:6000", groups: undefined]
console.log(reg.exec(str));//["+react:5000", "react:5000", "5000", index: 26, input: "html:2000+css:3000+js:4000+react:5000+vue:6000", groups: undefined]
console.log(reg.exec(str));//["+vue:6000", "vue:6000", "6000", index: 37, input: "html:2000+css:3000+js:4000+react:5000+vue:6000", groups: undefined]
match与exec的区别
exec是正则的方法,match是字符串的方法
正则中有g修饰符时,match 不会捕获分组内容
正则中不添加g修饰符时,match等同于exec,会捕获分组内容
不加修饰符g的时候是一样的,加上g的时候会有区别
exec 一次捕获一个,会捕获分组内容
match全部捕获,不会捕获分组内容
结论:
如果一次性全部捕获用match
如果捕获分组内容用exec
var reg=/(\d)\w/g;
var str='1a2b3c4d';
console.log(str.match(reg));//[1a,2b,3c,4d]
var reg2=/(\d)\w/g;
var str='1a2b3c4d';
console.log(reg2.exec(str));// ["1a", "1", index: 0, input: "1a2b3c4d", groups: undefined]
var reg3=/(\d)\w/;
var str='1a2b3c4d';
console.log(reg3.exec(str));// ["1a", "1", index: 0, input: "1a2b3c4d", groups: undefined]
var reg4=/(\d)\w/;
var str='1a2b3c4d';
console.log(str.match(reg4));//["1a", "1",index: 0, input: "1a2b3c4d", groups: undefined]
?出现场合
/(?:)/ 出现在小括号中,与冒号一起使用时,表示忽略分组
/\d?/ 出现在元字符后,表示出现0或1次
/\d{2,7}?/ 出现在量词之后,表示解决贪婪模式,按照最小值捕货
创建正则的方式
1、字面量方式创建
var reg=//;
2、构造函数方式创建
var reg=new RegExp("正则内容","修饰符");
var reg=new RegExp("\\d+","g");
console.log(reg.test("123"));
注:正则中遇到\,写成\\,因为第一个正则是字符串的形式
通过构造函数方式创建好处:正则字符串可以拼接,可以动态查找不同的内容
var str1='html:1000+css:2000+js:3000+react:4000+vue:5000';
function test(str){
var reg=new RegExp(str+":(\\d+)");
return reg.exec(str1)[1];
}
console.log(test("html"));//1000
console.log(test("js"));//3000
34、字符串的方法
1、split 按照匹配的内容,将字符串拆分为数组,允许匹配内容为正则
var str="html:1000+css:2000+js:3000";
console.log(str.split(/[:+]/));//[html,1000,css,2000,js,3000]
2、search 在字符串中查找匹配内容,返回匹配内容的索引,与indexof类似
var str="abc123def";
var reg=/\d+/;
console.log(str.search(reg));//3
3、replace 替换指定字符串为新的字符串值,允许指定字符串为正则
var str='abc123asd123'
var newStr=str.replace(/[a-z]+\d+/g,"A");
console.log(newStr); //"AA"
replace 将url参数转换为对象
var str='www.baidu.com?wd=3&rsv_spt=1&rsv_bp=0';
var str=str.split("?")[1]; // 一分为二,获取?后面部分
// type= 3 &name= 4;
// type:'3 &name:'4
// type:'3',name:'4
//{type:'3',name:'4'}
//{type:"3",name:"4"}
var obj=eval("({"+str.replace(/=/g,":'").replace(/&/g,"',")+"'})");
console.log(obj);//{wd: "3", rsv_spt: "1", rsv_bp: "0"}
35、H5 form表单属性
<form action="index.html" novalidate>
<input type="text" name="username" pattern="^[a-zA-Z0-9_]{4,16}$" >
<br>
<input type="password" name="password" maxlength="10" pattern="^[a-zA-Z]\w{5,17}$">
<br>
<input type="number" name="number">
<br>
<input type="tel" name="tel">
<br>
<input type="date" name="date">
<br>
<input type="url" name="url">
<br>
<input type="email" name="email">
<br>
<input type="color" name="color">
<br>
<input type="submit">
<br>
<input type="reset">
</form>
36、js盒子模型
//var height = getComputedStyle(box).height;
// console.log(height);//有单位
//以下属性无单位
// console.log(box.clientWidth);//120 内容宽+左右padding
// console.log(box.clientHeight);//120 内容高+上下padding
// console.log(box.clientTop);//1 上边框
// console.log(box.clientLeft);//1 左边框
// console.log(box.offsetWidth);//122 内容宽+左右padding+左右边框
// console.log(box.offsetHeight);//122 内容高+上下padding+上下边框
// console.log(box.offsetTop);//10 盒子距离父元素的上偏移量
// console.log(box.offsetLeft);//10 盒子距离父元素的左偏移量
console.log(box.offsetParent); //获取父级参照物
console.log(box.scrollWidth);//120
console.log(box.scrollHeight);//220 //内容没有溢出,
//并设置高度,和clientHeight一致,
//没有设置高度,内容的高度+上下padding
//内容有溢出,
//并设置高度,内容的高度+上padding
//没有设置高度,内容的高度+上下padding
console.log(box.scrollLeft); 横向滚动的距离
console.log(box.scrollTop) ; 纵向滚动过的距离
注:仅仅scrollLeft,scrollTop允许设置和获取,其他属性只允许读取
//元素滚动过的距离
box.onscroll=function(){
console.log(this.scrollTop);//边界值 最小-最大
}
//获取浏览器一屏的宽/高
document.documentElement.clientWidth||document.body.clientWidth
document.documentElement.clientHeight||document.body.clientHeight
//获取整个网页的宽/高
document.documentElement.scrollWidth||document.body.scrollWidth
document.documentElement.scrollHeight||document.body.scrollHeight
未完,待续…