目录
前言
引入:html中嵌入javascript有三种方式
0. 变量(var、let)
1. 函数
1.1 普通函数 和 箭头函数
1.1.2 普通函数中的this
1.1.3 箭头函数没有自己的this
1.1.4 普通函数有arguments方法,箭头函数没有
1.1.5 箭头函数没有new.target
1.1.6 箭头函数没有变量提升
1.1.7 箭头函数不能作为构造函数使用
2、函数高级
2.1原型与原型链
2.1.1原型(prototype)
2.1.2显示原型与隐式原型
2.1.3原型链
2.1.4原型链属性问题
2.1.5 探索instanceof
2.1.6 原型面试题
2.2 闭包
2.2.1 理解闭包
2.2.2 常见的闭包
2.2.3 闭包的作用
2.2.4 闭包的生命周期
2.2.6 闭包的缺点及解决
2.3 Promise(异步)
Promise基础语法
Promise进阶语法
Promise.all的用法
3. 数据类型
3.0 基本类型、引用类型
3.1 String(简要)
3.2 Object(简要)
3.3 null、NaN和undefined 的区别
4. JS事件
4.1 常用事件
4.2 注册事件方式
4.3 设置节点的属性
4.4 捕捉回车键
4.5 JS的控制语句
5. DOM
5.1 文本框value
5.2 inner HTML和innerText属性
5.3 获取日期/日期 Date
6. BOM
6.1 open与close
6.2 弹出确认框
6.3 历史记录
6.4 设置地址栏的url
7. 有哪些方法可以通过浏览器往服务器发请求
Java运行在JVM当中,JavaScript运行在浏览器的脚本语言在内存当中,完整的javascript由语言基础,BOM,DOM组成
JavaScript包括三大块:
第一种方式:事件句柄="js代码"
//window可以省略
第二种方式:javascript脚本块
完整代码
HTML中嵌入JS代码的第二种方式
第三种方式:外部引入js文件
window.alert("hello js!");
window.alert("hello js!");
window.alert("hello js!");
var和let都用于声明变量,不同的是:
1.let声明的变量不能重复声明
2.let声明的变量不能变量提升:
当使用var声明一个var变量时,该变量会被提升到作用域的顶端,但是赋值的部分不会提升。
console.log(a);
var a = 'boo'
在声明a的语句之前就可以输出a,值为undefined,这就是变量提升。
使用let声明变量时不能变量提升。
3.var是函数作用域,let是块状作用域:
在函数里使用var声明了一个变量,那么这个变量在整个函数内都是有效的,例如在for循环里用var声明一个变量,在for循环外也是可以使用的。但是let作用域是块状作用域,只在作用域里有效,例如在for循环里用let声明一个变量,在for循环外面是不能被访问的。
4.使用let声明的变量不属于顶层对象
顶层对象,在浏览器中指的是window,在node环境中指的是global对象。
var声明的变量属于顶层对象window,因此可以通过 window. 变量名 来访问这些变量,而let和const声明的变量不能这样访问。
JS经常会看到如下写法来定义函数:
第一种:const App= () => {} //箭头函数
第二种:function App() {} //普通函数
1.1.1 写法不同
箭头函数比普通函数更简洁:
//普通函数
const sum = function sum(a, b) { return a + b
}
//箭头函数 相当于python的匿名函数了
const sum = (a, b) => a + b
箭头函数的写法跟Python中的匿名函数类似。
- test(); window
- p.test(); p
- new test(); 新创建的对象
- p.call(obj); obj
箭头函数不能作为构造函数,也没有自己的this,它只会在自己作用域的上一层继承this。所以箭头函数中this的指向在它在定义时已经确定了,之后不会改变:
var id = '1';
var obj = {id: '2',a: function(){console.log(this.id);},b: () => {console.log(this.id);}
};
obj.a(); // '2'
obj.b(); // '1'
new obj.a() // undefined
new obj.b() // Uncaught TypeError: obj.b is not a constructor
f1(12,23,45); //普通函数
const f1 = function () {console.log(arguments);//Arguments(3) [12, 23, 45, callee: (...), Symbol(Symbol.iterator): ƒ]
}//箭头函数
const f1 = () => console.log(arguments);// Throws an error - arguments is not defined
//箭头函数可以使用rest语法解决
const f1 = (...args) => console.log(args);//[12, 23, 45]
new.target是用来检测函数是否被当做构造函数使用,他会返回一个指向构造函数的引用:
箭头函数打印new.target
出现报错
普通函数
function Cls(a,b) {this.a=athis.b=b}let obj=new Cls(1,2)console.log(obj.a) //1
箭头函数
let Cls = (a, b) => {this.a = athis.b = b}let obj = new Cls(1, 2)console.log(obj.a)//undefiend
1.函数的prototype属性
2.给原型对象添加属性(一般都是方法)
1.每个函数function都有一个prototype,即显示原型(属性)
2.每个实例对象都有一个__proto__,可称为隐式原型(属性)
3.对象的隐式原型的值为其对应构造函数的显示原型的值
4.总结:
图解
原型链(别名:隐式原型链)
访问一个对象属性时,
先在自身属性中查找,找到返回
如果没有,再沿着__proto__这条链向上查找,找到返回
如果最终没有找到,则返回undefined
作用:
1.查找对象的属性(方法)
2.构造函数/原型/实体对象的关系(图解)
3.构造函数/原型/实体对象的关系2(图解)
图解
1.读取对象的属性值时,会自动到原型链中查找
2.设置对象的属性值时,不会查找原型链,如果当前对象中没有此属性,直接添加此属性并设置其值
3.方法一般定义在原型中,属性一般通过构造函数定义在对象本身上
1.instanceof是如何判断的?
表达式:A instanceof B
如果B函数的显示原型对象在A对象的原型链上,返回true,否则返回false
2.Function是通过new自己产生的实例
图解
1.如何产生闭包?
当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包。
2.闭包到底是什么?
理解一:闭包是嵌套的内部函数
理解二:包含被引用变量(函数)的对象
注:闭包存在于嵌套的内部函数中
3.产生闭包的条件?
函数嵌套
内部函数引用了外部函数的数据(变量/函数)
function fn1(){var a = 2;function fn2(){ //执行函数定义就会产生闭包(不用调用内部函数)console.log(a);}fn2();
}
fn1();
1.将函数作为另一个函数的返回值
2.将函数作为实参传递给另一个函数调用
/***********************************************/
//普通函数
//计数:函数内部需要调用函数外的变量(非闭包)
let a = 10
function base(){ a++;console.log(a);
}
base()
base()
a = 1000
base()/***********************************************/
//闭包写法
//计数:函数嵌套
function count(){ console.log('out'); let num = 10; //内部函数function inner(){ num++;console.log(num); } return inner;
}const closure = count(); // 执行外部函数:输出out ,返回内部函数(闭包)
// 闭包的调用使得变量num 成为一个私有变量
closure(); // 11
closure(); // 12
num = 1000
closure(); // 13
闭包的作用
1.缺点:
2.解决
Promise 是一种异步编程的解决方案。
- 简单来说,Promise是一个容器,里面包含着一个异步操作的结果
- 从语法上来说,promise(小写的p)是一个对象,从它可以获取异步操作的最终状态
- 而Promise是一个构造函数,自己身上由reject resolve all方法,原型上有then catch方法
Promise有三种状态,pending 初始态,fulfilled 成功状态,rejected失败状态,只有异步操作的结果可以决定当前是哪一种状态,其他任何操作都无法改变这个状态。Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,只能由 pending变成fulfilled或者由pending变成rejected
Promise主要解决的问题
/*Promise的语法+ Promise 是 ES6 内置的构造函数+ 语法:new Promise(function(){你要执行的异步的事情 })=> 实例化的时候,这个函数接收两个参数=> resolve,reject+ 语法:=>实例化对象身上由两个方法1. then()-> promise对象.then(function(){})2. catch()-> promise对象.catch(function(){})=> then方法的函数传递给了实例化的 resolve=> catch方法的函数传递给了实例化的 reject
*/const p = new Promise(function (resolve, reject) {// resolve是成功的回调函数 当你书写resolve()的时候,实际上是在调用then里面的函数// reject是失败的回调函数 当你书写reject()的时候,实际上是在调用catch里面的函数ajax({url: './server/a.php',dataType: 'json',success(res) {resolve(res)},error(err) {reject(err)}})
})// 在 new Promise里面做一些回调的事情
// 将回调的结果转移到外面 then catch中
// 在 promise中做一件异步的事情,把结果放在外部的函数中去执行
p.then(function (res) { console.log('我执行了', res) })
p.catch(function (err) { console.log('我失败了', err) })
/*Promise的进阶语法+ 当你在一个 promise对象的 then里面返回一个新的 promise对象+ 你可以在这个 then的后面继续来一个 then接收第一个 then里面 promise对象的结果
*/new Promise(function (resolve, reject) {ajax({ur1: './server/a.php',dataType: 'json',success(res) {resolve(res)}})
})
.then(function (res) {console.log('需求1:', res)return new Promise(function (resolve, reject) {ajax({ur1: './server/b.php',data: res,dataType: 'json',success(res) {resolve(res)}})})
})
.then(function (res) {console.log('需求2:', res)return new Promise(function (resolve, reject) {ajax({url: './server/b.php',data: res,dataType: 'json',success(res) {resolve(res)}})})
})
.then(function (res) {
const p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve('结果1')}, 1000);
})
const p2 = new Promise((resolve, reject) => {setTimeout(() => {resolve('结果2')}, 1000);
})
const p3 = new Promise((resolve, reject) => {setTimeout(() => {resolve('结果3')}, 1000);
})// 三个都成功则成功,只要有一个失败就失败
// 成功时则会返回一个数组
Promise.all([p1, p2, p3]).then(res => {console.log(res);
})
数据类型有: 基本类型、引用类型
基本类型:
引用类型:
var i;
alert(typeof i); // "undefined"var k = 10;
alert(typeof k); // "number"var f = "abc";
alert(typeof f); // "string"var d = null;
alert(typeof d); // "object" null属于Null类型,但是typeof运算符的结果是"object"var flag = false;
alert(typeof flag); // "boolean"var obj = new Object();
alert(typeof obj); // "object"function sayHello(){}
alert(typeof sayHello); // "function"
typeof:可以判断:undefined、数值、字符串、布尔值,不能判断: null与object object与array
instanceof:可以判断对象的具体类型
===:可以判断undefined、null
var d = null;
alert(typeof d); // "object" null属于Null类型,但是typeof运算符的结果是"object"
typeof运算符的语法格式:typeof 变量名function sum(a, b){if(typeof a == "number" && typeof b == "number"){return a + b;}alert(a + "," + b + "必须都为数字!");
}
在JS当中字符串可以使用单引号,也可以使用双引号,String是一个内置的类,可以直接用,String的父类是Object。
var s = 'a234234';
常用函数
函数名 | 功能 |
---|---|
indexOf | 获取指定字符串在当前字符串中第一次出现处的索引 |
lastIndexOf | 获取指定字符串在当前字符串中最后一次出现处的索引 |
replace | 替换 |
split | 拆分字符串 |
substring | 截取子字符串 |
toLowerCase | 转换小写 |
toUpperCase | 转换大写 |
alert("http://www.baidu.com".indexOf("http")); // 0
alert("http://www.baidu.com".indexOf("https")); // -1// 判断一个字符串中是否包含某个子字符串?
alert("http://www.baidu.com".indexOf("https") >= 0 ? "包含" : "不包含"); // 不包含// replace (注意:只替换了第一个)
alert("name=value%name=value%name=value".replace("%","&")); // name=value&name=value%name=value// 继续调用replace方法,就会替换第“二”个.
// 想全部替换需要使用正则表达式.
alert("name=value%name=value%name=value".replace("%","&").replace("%", "&")); // name=value&name=value&name=value
substr和substring的区别?
// substr(startIndex, length)
alert("abcdefxyz".substr(2,4)); //cdef,(下标,长度)
// substring(startIndex, endIndex) 注意:不包含endIndex
alert("abcdefxyz".substring(2,4)); //cd,【开始下标,结束下标)
Object类型是所有类型的超类,自定义的任何类型,默认继承Object
实例
/*
//定义函数的第一种方式
function User(a, b, c){ // a b c是形参,属于局部变量.// 声明属性 (this表示当前对象)// User类中有三个属性:sno/sname/sagethis.sno = a;this.sname = b;this.sage = c;
}// 创建对象
var u2 = new User(222, "jackson", 55);
alert(u2.sno);
alert(u2.sname);
alert(u2.sage);// 访问一个对象的属性,还可以使用这种语法
alert(u2["sno"]);
alert(u2["sname"]);
alert(u2["sage"]);
*///定义函数的第二种方式
Product = function(price){// 属性this.price = price;// 函数this.getPrice = function(){return this.price;}
}var xigua = new Product(4.0);
var pri = xigua.getPrice();
alert(pri);
动态扩展属性
属性有:prototype属性(常用的,主要是这个):作用是给类动态的扩展属性和函数。
// 可以通过prototype这个属性来给类动态扩展属性以及函数
Product.prototype.getPname = function(){return this.pname;
}// 调用后期扩展的getPname()函数
var pname = xigua.getPname();
alert(pname)// 给String扩展一个函数
String.prototype.suiyi = function(){alert("这是给String类型扩展的一个函数,叫做suiyi");
}"abc".suiyi();
JS语言怎么定义类,怎么创建对象?(弱类型)
User = function(username,password){this.username = username;this.password = password;
}
var u = new User();
var u = new User("zhangsan");
var u = new User("zhangsan","123");
// null NaN undefined 数据类型不一致.
alert(typeof null); // "object"
alert(typeof NaN); // "number"
alert(typeof undefined); // "undefined"// null和undefined可以等同.
alert(null == NaN); // false
alert(null == undefined); // true
alert(undefined == NaN); // false// 在JS当中有两个比较特殊的运算符
alert(null === NaN); // false
alert(null === undefined); // false
alert(undefined === NaN); // false
任何一个事件都会对应一个事件句柄,事件句柄是在事件前添加on
blur失去焦点 、focus获得焦点
(所谓焦点是光标的获得与失去)
click鼠标单击、dblclick鼠标双击
keydown键盘按下、keyup键盘弹起
mousedown鼠标按下、mouseover鼠标经过
mousemove鼠标移动、mouseout鼠标离开
mouseup鼠标弹起
reset表单重置、submit表单提交
change下拉列表选中项改变,或文本框内容改变
select文本被选定
load页面加载完毕(整个HTML页面中所有的元素全部加载完毕之后发生。)
通过点击一个按钮框,将其变为复选框
回车键的键值是13、ESC键的键值是27
按钮键是onclick,而回车键onkeydown
usernameElt.onkeydown = function(event){if(event.keyCode === 13){alert("正在进行验证....");}
}
var arr = [false,true,1,2,"abc",3.14];
for(var i = 0; i < arr.length; i++){alert(arr[i]);
}
for in结构
for(var i in arr){alert(arr[i]);
}
for in结构还可以遍历对象属性
// for..in语句可以遍历对象的属性
User = function(username,password){this.username = username;this.password = password;
}var u = new User("张三", "444");for(var item in u){alert(u[item]);//不用加双引号
}
with结构
with(u){alert(username + "," + password);
}
DOM:Document Object Model(文档对象模型)HTML文档被当做一棵DOM树来看待。
var domObj = document.getElementById("id");
DOM和BOM的区别:
1.通过点击按钮框获取value值
2.失去焦点对象获取value值,通过this指针
innerHTML会把后面的“字符串”当做一段HTML代码解释并执行。
innerText,即使后面是一段HTML代码,也只是将其当做普通的字符串来看待
// 当以上格式不是自己想要的,可以通过日期获取年月日等信息,自定制日期格式.
var t = new Date();
var year = t.getFullYear(); // 返回年信息,以全格式返回.
var month = t.getMonth(); // 月份是:0-11
// var dayOfWeek = t.getDay(); // 获取的一周的第几天(0-6)
var day = t.getDate(); // 获取日信息.
document.write(year + "年" + (month+1) + "月" + day + "日");
BOM编程中,window对象是顶级对象,代表浏览器窗口
打开window.open();
关闭window.close();
将当前窗口设置为顶级窗口 代码演示
if(window.top != window.self){window.top.location = window.self.location;
}
历史纪录的后退window.history().back();或window.history().go(-1);
历史纪录的前进window.open();
var xx = window.location;
xx.href = "http://网址";
//或者window.location.href = "http://网址";
//或者window.location = "http://网址";
//或者document.location.href = "http://网址";同理href可以省略
以上所有的请求方式均可以携带数据给服务器,只有通过表单提交的数据才是动态的
上一篇:Git上传项目三部曲
下一篇:二分——力扣篇