引言
- 1995年网景公司首次运用在浏览器上的脚本语言
1)在浏览器中,大部分是以解释性语言运行的。
ja执行引擎,谷歌js执行引擎(v8),在以往的v8版本中,为了提升js运行效率,把js直接编译成机器码,然后浏览器直接运行机器码文件,最新版的v8采用半解释半编译。
变量与类型
- var创建的变量有什么特点?
1)没有数据类型
2)拥有var赋予给变量的作用域
① 全局作用域,只要声明,随时随地可以调用,但是赋值操作根据代码顺序进行。
② 函数作用域,在函数中定义的,和全局是父子关系,一旦函数中定义全局已经定义的变量名称,优先使用函数,不管声明顺序。
3)var作用域拥有的问题
① 同级别作用域下,后者声明覆盖前者。
② 不是函数但拥有代码块的语句(for,if),不拥有独立的作用域 - 图中的问题原因var与setTimeout
- ES5中的数据类型,js声明是没有类型的,但是执行的时候,会根据值动态赋予类型
1)string
2)number
3)boolean
4)undefined
5)对象类型
①json
②array
③date
④function
typeof(查看当前值得类型)
- typeof所有的返回值都是字符串
function one(){}
console.log(typeof "abc");
console.log(typeof 123);
console.log(typeof null); //object
console.log(typeof undefined);
console.log(typeof false);
console.log(typeof []);
console.log(typeof {});
console.log(typeof one);//function
输出,debugger
- 输出
console.log("abc");
console.ingo("abc");
console.debug("abc");
console.warn("abc");
console.error("abc");
console.table([1,2,3,4,5]);//默认展开一个数组
- debugger
在需要调错的位置上写上debugger,打开 F12 控制台,会出现调试页面,可以一步一步的执行代码,找出错误原因。
Number常用方法
- Math.random() 0~1之间的随机数
- number.toFixed() 可以保留指定的小数的后几位
- 字符串转整数类型
1)Number(“11”)
2)+“11” 自动转换字符串
3)number+string = string拼接
4)numer * string = number * number
5)number - string = number - number - “asd” * 11 = NaN (not a number):当结果js也不知道返回什么时,返回NaN 。
NaN永远不等于NaN
字符串常用
- 下标
可以根据下标取值,但是不能赋值 - 长度
length属性 - indexOf(“a”)
返回当前字符串第一次出现的位置,如果没有当前字符串,则返回-1 - lastIndexOf(“a”)
返回当前字符串最后一次出现的位置,如果没有当前字符串,则返回-1 - substring()
根据下标截取字符串 - split("")
分割当前字符串变成数组,可以指定分隔符号 - toString()
将当前对象变成字符串
数组常用方法
- 下标
数组可以通过下标取值和赋值。 - 长度
lenth属性 - indexOf()
当前值出现在数组中的位置,如果数组内没有,则返回-1。 - unshift()
在数组的第一个位置添加元素,返回值为最新的数组长度。 - shift()
删除第一个位置的元素,返回值为删除的元素的值。 - push()
在数组的末尾添加元素,返回值为最新的数组长度。 - pop()
删除数组的末尾元素,返回删除的元素值。 - concat()
拼接多个数组,返回最新的拼接数组
例:concat(arrt1,arrt2,arrt3), - toString()
将数组字符串形式输出,保留拼接符 - join(“”)
将当前对象变成字符串,变字符串的同时可以指定分隔符号,将分隔符号作为参数传递给json() - reverse()
翻转数组内的所有内容 - sort()
排序,默认升序排列,可以传入一个function自定义排列结果
var result=arr.sort(function(a,b){
return b-a;//降序
return a-b;//升序,默认
})
- slice()
截取数组元素,返回截取元素的最新数组 - splice()
可以删除或修改数组中的元素
1)传入俩个值,对应的是删除操作,第一个值是指定删除元素的下标,第二个值是删除几个
2)传入三个值,最后一个值是替换前面删除值的位置
json对象
- json是javascript支持的对象,以key-value构成,以{ }来定义一个json对象
key必须是基本类型,value可以是任何类型的数据 - 取值赋值操作
1)json.key 取值get方法
2)json.key = value 赋值set方法
3)json[key] 取值get方法支持动态获取的key的值
4)json[key] = value 赋值set方法支持动态获取的key的值
- 如果调用json的set方法添加不存在的key,默认是可以的,当前的json对象中会创建对应的key和vlaue
- 删除操作 delete user{“name”];
- JSON.parse()将json格式的字符串转换为json对象。
- JSON.stringify() 将json或数组转换成字符串格式的格式的对象。
运算符与布尔比较
- + - * / %与java中的用法一样
1)number+string = string拼接
2)numer * string = number * number
3)number - string = number - number
4)arr+string = [1,2,3]+11=“1,2,3111”
数组的末尾做拼接,其余位置的数据toString()处理
5)arr-number 如果数组长度为1,那么可以做整数类型的运算,如果长度大于1 NaN
6)arr*number 如果数组长度为1,那么可以做整数类型的运算,如果长度大于1 NaN - “= =“与”= = =”
1)"= =“是判断数据是否相同。
2)”= = =“是判断数据类型与数据是否相同。
3)在日常判断中,建议使用”= = ="。 - 布尔运算
1)js中的分支语句中不仅仅支持布尔表达式,还支持数据的默认布尔转换
2)js中0就是false,1就是true
① 等于false的情况:0 null undefined “” NaN
② 所有对象类型都是true
③ null与undefined的区别:null一般都是认为赋予的值,undefined一般都是变量的默认值
循环
- for
- while
- forEach
1)value1(值) value2(下标) value3(遍历的对象) - for in 可以遍历数组,遍历json对象
1)数组遍历的是下标
2)json遍历的是key,需要用json[key]取值
错误与异常的处理
try catch finally:目的就是不让进程直接受到异常的影响
try{
console.log("开始执行");
throw "自定义异常"
}catch{
console.log(e);
}finally{
console.log("最后执行");
}
补充
函数
- function 定义一个函数
1)有名称的函数
2)没名称(通过匿名应用最多的就是回调)
3)函数名称引用优先级最高 - arguments对象,承载所有传递给函数的数据
- 所有函数中的this,默认直接指向调用者window
- 如何为函数的参数赋予默认值
function one(a,b){
a = a || 0;//||的左边的a如果是false,就使用右边的默认值,如果是true直接使用
b = b || 0;
return a+b;
}
构造函数
- 构造函数的创建通过new
function user(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
console.log(this)
}
var user1 = new user("小黑",20,"男");
this
- 构造函数中的最外层this默认指向创建的堆空间,但是如果构造函数中嵌套了其他函数,那么其他函数中的this默认指向全局window,放置this指向出现滚乱的问题
1)将堆空间的this赋予给一个变量供其他函数直接使用。
2)在构造函数内部的其他函数调用时使用bind(this)把this传递给执行的函数,让其他函数内部使用的this都是外部的this
function user(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
function one(){
console.log(this);
}
one.bind(this)();
}
2. json中的this问题
json中的对应的key的value中直接使用this,默认指向当前json的堆空间。
var user = {name:"小黑",age:20,say:function(){console.log(this)}};
var s = user.say;
s();//输出window
闭包
- 函数套函数,外部函数定义的变量可以被内部函数使用
1)优点:
① 对象直接创建在内存中保存,直接使用,效率高,而且可以承接执行状态
② 简化代码的书写,让复杂的代码看上去使用简单
③ 对外隐藏细节,内部创建的变量,外部无法观测和获取
2)缺点:
① 内存占用率太高,容易造成内存泄漏
②不好写,可读性差 - 需要创建一个数组,数组中存放5个function,手动调用对应下标的function后,分别输出0-4
创建一个闭包函数,外层加载变量a,赋予当前i的值,保存在内存中,然后将当前返回的function push进数组中,那么这些数组中保存的都是由闭包返回的内部的function,内部function引用了外部创建的a变量
补充
//一。
function add(a){
return function(b){
return function(c){
return a*b*c;
}
}
}
add(a)(b)(c);
//二。
function one(){
var i=0;
return function(){
return i++;
}
}
var fun = one();//执行one函数后,i 变量创建在内存中,没有被销毁,因为内部的闭包函数被引用了 i
console.log(fun());
console.log(fun());
计时事件
- setTimeout() 指定一定时间后再执行内部匿名函数中的代码
1)参数1:function(){}执行的逻辑代码
2)参数2:时间,单位:ms - setInterval 隔一段时间就执行一次内部匿名函数中的代码,需要合理的使用,在指定条件下终止
1)参数1:function(){}执行的逻辑代码
2)参数2:时间,单位:ms - clearTimeout() 取消当前延时执行事件
- clearInterval() 取消当前循环计时执行事件
setTimeout是伪异步非阻塞(同步非阻塞)
计时事件执行会触发Event Loop,Event Loop中的代码都是非堵塞的
- 当遇到计时时间时,由于非阻塞的特性,会让下面的代码先执行,等到主线程空闲时,才会执行非阻塞的代码
回调
ajax是浏览器开启的线程,完成的url的访问
- 回调就是把函数当做另一个函数的参数作为传递
同步代码没有必要使用回调
//异步执行的代码
function one(count,callback){
for(var i=0;i<count;i++){
if(i === (count-1)){
callback("执行完毕");
}
}
}
//本地进程中定义的callback
one(5,function (data) {
console.log(data);
})
正则表达式
正则表达式的效率比较低
-
主要应用场景
1)输入的内容格式的匹配
2)爬虫:访问url获取响应的数据,过滤出我们想要的数据 -
创建方式
1)/匹配规则/
2)new ReqExp("","") 动态拼接正则表达式
①value1,匹配规则
②value2,参数i,g -
常用方法
1)search 查找字符出现的下标 i 不区分大小写
2)replace 替换指定字符的内容 g 全局匹配后替换
var str="";
var reg=/(a|A)/g;
str.replace(reg,"呵呵");
3)test
① $ 结尾有指定的字符,才符合匹配规则
② ^ 开头有指定的字符,才符合匹配规则
var str="";
var reg=/(.jpg|.png)$/;
str.test(reg);
Date
var date = new Date();
date.toLocaleString();
var my_date="2015-10-1 22:10:10";
var simple = "YYYY-MM-DD";
//百度搜索js实现SimpleDateFormat
function simpleFormat(simple){
new date = new Date();
var rule={
"YYYY":date.getFullYear(),
"MM":date.getMonth(),
"DD":date.getDate()
}
return rule;
}
百度搜索js实现SimpleDateFormat
/**
* 时间格式化
*/
function SimpleDateFormat(pattern){
var fmt = new Object();
fmt.pattern = pattern;
fmt.parse = function(source){
try{
return new Date(source);
}catch(e){
console.log("字符串 "+source+" 转时间格式失败!");
return null;
}
};
fmt.format = function(date){
if(typeof(date) == "undefined" || date == null || date==""){
return "";
}
try{
date = new Date(date);
}catch(e){
console.log("时间 "+date+" 格式化失败!");
return "";
}
var strTime = this.pattern;//时间表达式的正则
var o = {
"M+": date.getMonth() + 1, //月份
"d+": date.getDate(), //日
"H+": date.getHours(), //小时
"m+": date.getMinutes(), //分
"s+": date.getSeconds(), //秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
};
if (/(y+)/.test(strTime)){
strTime = strTime
.replace(RegExp.$1, (date.getFullYear() + "")
.substr(4 - RegExp.$1.length));
}
for (var k in o){
if (new RegExp("(" + k + ")").test(strTime)){
strTime = strTime.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return strTime;
};
return fmt;
}
使用
var fmt = SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
var aTime = fmt.parse("2020-12-31 23:59:59");//Date 类型
var strTime = fmt.format(aTime);//String 类型
- 日期类型
1)Date.now() 时间戳,1970年至今的毫秒数
2)getTime() 时间戳,1970年至今的毫秒数
3)toLocaleString() 将日期转换成本地风格输入,返回String类型的数据
4)getFullYear() 获取当前年份
5)getMonth() 获取当前月份 月份起始值是0,默认需要加1
6)getDate() 获取当前月份的第几天
7)getHours() 获取当前小时
8)getMinutes() 获取当前分钟
9)getSeconds() 获取当前秒 - 字符串转date
new Date(“2015-1-1 10:10:10”) 格式固定 - 自定义SimpleDateFormat
https://blog.csdn.net/maozexijr/article/details/78727325
原型
所有函数都有原型,对象只有原型指针proto指向父的原型
一个对象能干什么是有他构造函数的原型来决定的
- prototype 只有函数function有原型
- _ _ proto_ _ 只有对象拥有_ _ proto_ _
console.log(one instanceof Object)
console.log(one instanceof Function)
console.log(Object instanceof Function)
console.log(Function instanceof Object)
console.log(Object instanceof Object)
console.log(Function instanceof Function)
- 基本类型的原型链
基本类型默认就是没有任何属性和方法,js对于基本类型的默认行为是在调用基本类型的属性和方法是默认加new Number(a),让基本类型也可以拥有属性和方法。
(调用一个对象的__proto__,来查看当前原型链结构)
var a=11;
//一旦返回null,即是到达顶层结构
console.log(a.__proto__.__proto__)
instanceof
- 判断一个对象在不在被判断对象的原型链上
- a instanceof b 判断a在不在b的原型链上
call,apply
- call 使用一个函数替换另一个函数的实现,可以传递参数
add.call(sub,1,2);
- apply 使用一个函数替换另一个函数的实现,可以传递参数
add.apply(sub,[1,2]);
- call与apply的区别
传参形式不同,apple需要数组形式传参
继承
js当中没有明确的概念和语法来实现或描述继承
- 原型继承
1) 优点
a、简单易于实现
b、原型继承很准确的描述了继承关系
2)缺点
a、不能继承时传递参数
b、不能多继承
c、如果为子添加了新的属性或方法,必须在继承代码后添加
function Animal(){
this.name="";
}
function Dog(){
this.sex="";
}
//Dog是一个function,就拥有prototype
Dog.prototype.say = "呵呵";
Dog.prototype = new Animal();
var d = new Dog();
console.log(d.name);
- call和apply继承
1)优点
a、多继承
b、可以继承时传参
c、随便为子添加属性或新方法
2)缺点
a、实现内部没有任何继承概念的体现
function Animal1(){
this.name1 = "动物1";
}
function Animal2(){
this.name2 = "动物2";
}
function Dog(){
Animal1.call(this);
Animal2.call(this);
this.sex = "男";
}
var dog = new Dog();
console.log(dog instanceof Animal1);
观察者模式
观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己
/*主体
* 1.用户可以订阅(监听)
* 2.用户可以退订
* 3.推送给所有订阅的用户
* */
var Event = {};
/* list存放订阅我主体的用户 */
Event.list = {};
/* 写一个订阅功能 */
Event.on = function (user,callback) {
this.list[user] = callback;
}
/* 写一个推送功能 */
Event.emit = function (user,mes) {
this.list[user](mes)
}
/* 推送给所有订阅我的用户 */
Event.emitAll = function (mes) {
for(var u in this.list){
this.list[u](mes)
}
}
/*用户1使用主体的订阅功能*/
Event.on("user1",function (mesg) {
console.log(mesg);
})
//官方推送消息
Event.emit("user1","这是一条广告")
浅拷贝和深拷贝
- 浅拷贝
(对象类型)
var arr1 = [1,2,3,4];
var arr2 = arr1;
只拷贝引用(地址)不拷贝堆内容,没有开辟新的空间
- 深拷贝
1)如果是数组,循环出需要拷贝的内容赋予给新的数组对象
//第二种
var arr1 = [2,1,3,4];
var arr2 = arr1.concat();
//第三种
var user1 = {name:"hehe",age:20};
var user2 = {};
for(var u in user1){
user[u] = user1[u];
}
//第四种
var arr1 = [2,1,3,4]; (es6语法)
var arr2 = […arr1];
DOM与BOM
BOM全称Browser Object Model ,也叫浏览器对象,每个浏览器之间可能有差异
DOM是HTML标签对象,也可以w3c标准对象模型.
典型的Window 对象
- window.document.getElementById(“header”);
- 屏幕分辨率的高: window.screen.height
- 屏幕分辨率的宽: window.screen.width
- 获取滚动举例,兼容多个浏览器
var tpScrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop一般是监听window的滚动条 - 监听某个div内的滚动条,只需要传入当前的this,然后this.scrollTop获取
window对象:
- window.screen.height
- window.screen.width
- window.location.reload()
- window.location.href = “”;
- 弹框alert
- confirm 确认弹出框
- prompt 用户输入提交框
js操作dom 语法
- document.querySelector()
- getElementById
- getElementsByTagName(返回的数组)
- value
- textContent
- remove
- setAttribute
- appendChild
- append
- innerHTML
- innerText
- createElement