1.前提
Html是一种标记语言,用来结构化我们的网页内容并赋予内容含义,例如定义段落、标题和数据表,或在页面中嵌入图片和视频
2.简介
3.JavaScript 用法
如需在 HTML 页面中插入 JavaScript,请使用 <script> 标签
您无需理解上面的代码。只需明白,浏览器会解释并执行位于 <script> 和 </script>之间的 JavaScript 代码
那些老旧的实例可能会在 <script> 标签中使用 type=”text/javascript“。现在已经不必这样做了。JavaScript 是所有现代浏览器以及 HTML5 中的默认脚本语言
3.2 <body> 中的 JavaScript
JavaScript 会在页面加载时向 HTML 的 <body> 写文本
<!DOCTYPE html>
<html>
<body>
.
.
<script>
document.write(“<h1>这是一个标题</h1>”);
document.write(“<p>这是一个段落</p>”);
</script>
.
.
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction()
{
document.getElementById(“demo“).innerHTML=”我的第一个 JavaScript 函数“;
}
</script>
</head>
<body>
<h1>我的 Web 页面</h1>
<p id=”demo“>一个段落</p>
<button type=”button” οnclick=”myFunction()”>尝试一下</button>
</body>
</html>
3.4外部的 JavaScript
可以把脚本保存到外部文件中。外部文件通常包含被多个网页使用的代码
如需使用外部文件,请在 <script> 标签的 “src” 属性中设置该 .js 文件:
<!DOCTYPE html>
<html>
<body>
<script src=”myScript.js”></script>
</body>
</html>
function myFunction()
{
document.getElementById(“demo“).innerHTML=”我的第一个 JavaScript 函数”;
}
4.Chrome 浏览器中执行 JavaScript
如何在 Chrome 浏览器上进行 JavaScript 代码的运行与调试
我们在 Chrome 浏览器中可以通过按下 F12 按钮或者右击页面,选择“检查“来开启开发者工具
也可以在右上角菜单栏选择 “更多工具“=》”开发者工具” 来开启
打开开发者工具后,我们可以在 Console 窗口调试 JavaScript代码,如下图
上图中我们在 > 符号后输入我们要执行的代码 console.log(“runoob”),按回车后执行。
我们也可以在其他地方复制一段代码过来执行,比如复制以下代码到 Console 窗口,按回车执行
我们也可以在 Chrome 浏览器中创建一个脚本来执行,在开发者工具中点击 Sources 面板,选择 Snippets 选项卡,在导航器中右击鼠标,然后选择 Create new snippet 来新建一个脚本文件
如果你没看到 Snippets ,可以点下面板上到 >> 就能看到了
点击 Create new snippet 后,会自动创建一个文件,你只需在右侧窗口输入以下代码,然后按 Command+S(Mac)或 Ctrl+S(Windows 和 Linux)保存更改即可
5.JavaScript 输出
- 使用 window.alert() 弹出警告框。
- 使用 document.write() 方法将内容写到 HTML 文档中。
- 使用 innerHTML 写入到 HTML 元素。
- 使用 console.log() 写入到浏览器的控制台
<script>
document.getElementById(“demo“).innerHTML = “段落已修改。”;
</script>
<button οnclick=”myFunction()”>点我</button>
<script>
function myFunction() {
document.write(Date());
}
</script>
6.JavaScript 语法
JavaScript 代码
JavaScript 代码块
function myFunction()
{
document.getElementById(“demo“).innerHTML=”你好Dolly”;
}
JavaScript 会忽略多余的空格 您可以向脚本添加空格,来提高其可读性
7.JavaScript 注释
8.JavaScript 变量
变量声明之后,该变量是空的(它没有值)
如需向变量赋值,请使用等号:
不过,您也可以在声明变量时对其赋值:
在下面的例子中,我们创建了名为 carname 的变量,并向其赋值 “Volvo“,然后把它放入 id=”demo” 的 HTML 段落中:
var carname=”Volvo“;
document.getElementById(“demo“).innerHTML=carname;
您可以在一条语句中声明很多变量。该语句以 var 开头,并使用逗号分隔变量即可:
声明也可横跨多行:
一条语句中声明的多个变量不可以同时赋同一个值:
9.JavaScript 数据类型
字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol
注:Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值
对象(Object)、数组(Array)、函数(Function),两个特殊的对象:正则(RegExp)和日期(Date)
JavaScript 拥有动态类型。这意味着相同的变量可用作不同的类型:
typeof “John” // 返回 string
typeof 3.14 // 返回 number
typeof false // 返回 boolean
typeof [1,2,3,4] // 返回 object
typeof {name:’John’, age:34} // 返回 object
JavaScript 数字
JavaScript 只有一种数字类型。数字可以带小数点,也可以不带
JavaScript 布尔
JavaScript 数组
var cars=new Array();
cars[0]=”Saab“;
cars[1]=”Volvo“;
cars[2]=”BMW”;
JavaScript 对象
对象由花括号分隔。在括号内部,对象的属性以名称和值对的形式 (name : value) 来定义。属性由逗号分隔
var person={firstname:”John”, lastname:”Doe”, id:5566};
var cars=[“Saab“,”Volvo“,”BMW”];
cars=null;
声明变量类型
var carname=new String;
var x= new Number;
var y= new Boolean;
var cars= new Array;
var person= new Object;
<p id=”demo”></p>
<script>
var person = {
firstName: “John”,
lastName : “Doe”,
id : 5566,fullName : function()
{
return this.firstName + ” ” + this.lastName;
}
};document.getElementById(“demo”).innerHTML = person.fullName(); //调用对象方法
</script>
JavaScript 函数
<script> function myFunction() {
} </script>
JavaScript 函数语法
函数就是包裹在花括号中的代码块,前面使用了关键词 function
<button οnclick=”myFunction(‘Harry Potter’,’Wizard’)”>点击这里</button>
<script>
function myFunction(name,job){
alert(“Welcome ” + name + “, the ” + job);
}
</script>
带有返回值的函数
有时,我们会希望函数将值返回调用它的地方。
在使用 return 语句时,函数会停止执行,并返回指定的值
function myFunction()
{
var x=5;
return x;
}var myVar=myFunction();
function myFunction(a,b) { return a*b; } document.getElementById(“demo”).innerHTML=myFunction(4,3);
10.JavaScript 作用域
11.JavaScript 事件
当在 HTML 页面中使用 JavaScript 时, JavaScript 可以触发这些事件
通常,当事件发生时,你可以做些事情。
HTML 元素中可以添加事件属性,使用 JavaScript 代码来添加 HTML 元素
在以下实例中,按钮元素中添加了 onclick 属性 (并加上代码)
<button οnclick=”getElementById(‘demo’).innerHTML=Date()”>现在的时间是?</button>
或者
<p>点击按钮执行 <em>displayDate()</em> 函数.</p>
<button οnclick=”displayDate()”>点这里</button>
<script>
function displayDate(){
document.getElementById(“demo”).innerHTML=Date();
}
</script>
<p id=”demo”></p></body>
其它事件
12.JavaScript 字符串
var carname = “Volvo XC60″;
var txt = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”;
13.JavaScript 运算符
逻辑运算符
14.JavaScript if…Else 语句
通常在写代码时,您总是需要为不同的决定来执行不同的动作。您可以在代码中使用条件语句来完成该任务。
在 JavaScript 中,我们可使用以下条件语句:
- if 语句 – 只有当指定条件为 true 时,使用该语句来执行代码
- if…else 语句 – 当条件为 true 时执行代码,当条件为 false 时执行其他代码
- if…else if….else 语句– 使用该语句来选择多个代码块之一来执行
- switch 语句 – 使用该语句来选择多个代码块之一来执行
15.JavaScript switch 语句
switch(n)
{
case 1:
执行代码块 1
break;
case 2:
执行代码块 2
break;
default:
与 case 1 和 case 2 不同时执行的代码
}
16.JavaScript for 循环
for 循环
for (var i=0; i<5; i++)
{
x=x + “该数字为 ”
}
For/In 循环
var person={fname:”Bill”,lname:”Gates“,age:56};
for (x in person) // x 为属性名
{
txt=txt + person[x];
}
while 循环
17.JavaScript break 和 continue 语句
for (i=0;i<10;i++){
if (i==3){
break;
}
x=x + “The number is ” + i + “<br>”;
}
for (i=0;i<=10;i++){
}
18.JavaScript typeof, null, 和 undefined
typeof “John” // 返回 string
typeof 3.14 // 返回 number
typeof false // 返回 boolean
typeof [1,2,3,4] // 返回 object
typeof {name:’John’, age:34} // 返回 object
null
在 JavaScript 中 null 表示 “什么都没有“。
var person = null; // 值为 null(空), 但类型为对象
在 JavaScript 中, undefined 是一个没有设置值的变量
19.JavaScript 正则表达式
20.JavaScript 表单验证
以下实例代码用于判断表单字段(fname)值是否存在, 如果不存在,就弹出信息,阻止表单提交
function validateForm() {
var x = document.forms[“myForm“][“fname”].value;
if (x == null || x == “”) {
alert(“需要输入名字。”);
return false;
}
}
<form name=”myForm” action=”demo_form.php” οnsubmit=”return validateForm()” method=”post“>
名字: <input type=”text” name=”fname”>
<input type=”submit” value=”提交“>
</form>
如果表单字段 (fname) 的值为空, required 属性会阻止表单提交
<form action=”demo_form.php” method=”post“>
<input type=”text” name=”fname” required=”required“>
<input type=”submit” value=”提交“>
</form>
21.JavaScript this 关键字
但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变
- 在方法中,this 表示该方法所属的对象
- 如果单独使用,this 表示全局对象
- 在函数中,this 表示全局对象
- 在函数中,在严格模式下,this 是未定义的(undefined)
- 在事件中,this 表示接收事件的元素
- 类似 call() 和 apply() 方法可以将 this 引用到任何对象
方法中的 this
在上面一个实例中,this 表示 person 对象
fullName 方法所属的对象就是 person
<script>
// 创建一个对象
var person = {
firstName: “John”,
lastName : “Doe”,
id : 5566,
fullName : function() {
return this.firstName + ” ” + this.lastName;
}
};// 显示对象的数据
document.getElementById(“demo”).innerHTML = person.fullName();
</script>
事件中的 this
在 HTML 事件句柄中,this 指向了接收事件的 HTML 元素
<button οnclick=”this.style.display=’none‘”>点我后我就消失了</button>
下面实例中,this 是 person 对象,person 对象是函数的所有者
<script>
// 创建一个对象
var person = {
firstName : “John”,
lastName : “Doe”,
id : 5566,
myFunction : function() {
return this;
}
};// 显示表单数据
document.getElementById(“demo”).innerHTML = person.myFunction();
</script>
在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法。这两个方法异常强大,他们允许切换函数执行的上下文环境(context),即 this 绑定的对象。
在下面实例中,当我们使用 person2 作为参数来调用 person1.fullName 方法时, this 将指向 person2, 即便它是 person1 的方法:
<script>
var person1 = {
fullName: function() {
return this.firstName + ” ” + this.lastName;
}
}
var person2 = {
firstName:”John”,
lastName: “Doe”,
}
var x = person1.fullName.call(person2);
document.getElementById(“demo”).innerHTML = x;
</script>
22. let 和 const区别
ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const。
const 声明一个只读的常量,一旦声明,常量的值就不能改变。
在 ES6 之前,JavaScript 只有两种作用域: 全局变量 与 函数内的局部变量
var carName = “Volvo“;
// 这里可以使用 carName 变量
function myFunction() {
// 这里也可以使用 carName 变量
}
全局变量在 JavaScript 程序的任何地方都可以访问。
// 这里不能使用 carName 变量
function myFunction() {
var carName = “Volvo”;
// 这里可以使用 carName 变量
}
// 这里不能使用 carName 变量
函数内使用 var 声明的变量只能在函数内访问,如果不使用 var 则是全局变量。
使用 var 关键字声明的变量不具备块级作用域的特性,它在 {} 外依然能被访问到。
{ var x = 2; } // 这里可以使用 x 变量
let 声明的变量只在 let 命令所在的代码块 {} 内有效,在 {} 之外不能访问。
{
let x = 2;
}
// 这里不能使用 x 变量
重新定义变量
在块中重新声明变量也会重新声明块外的变量:
var x = 10;
// 这里输出 x 为 10
{
var x = 2;
// 这里输出 x 为 2
}
// 这里输出 x 为 2
let 关键字就可以解决这个问题,因为它只在 let 命令所在的代码块 {} 内有效。
var x = 10;
// 这里输出 x 为 10
{
let x = 2;
// 这里输出 x 为 2
}
// 这里输出 x 为 10
循环作用域
使用 var 关键字:
var i = 5;
for (var i = 0; i < 10; i++) {
// 一些代码…
}
// 这里输出 i 为 10
使用 let 关键字:
var i = 5;
for (let i = 0; i < 10; i++) {
// 一些代码…
}
// 这里输出 i 为 5
在第一个实例中,使用了 var 关键字,它声明的变量是全局的,包括循环体内与循环体外。
在第二个实例中,使用 let 关键字, 它声明的变量作用域只在循环体内,循环体外的变量不受影响。
变量提升
JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明
x = 5; // 变量 x 设置为 5
elem = document.getElementById(“demo”); // 查找元素
elem.innerHTML = x;
// 在元素中显示 xvar x; // 声明 x
var x = 5; // 初始化 x
var y; // 声明 yelem = document.getElementById(“demo”); // 查找元素
elem.innerHTML = x + ” ” + y; // 显示 x 和 yy = 7; // 设置 y 为 7
const 关键字
const 用于声明一个或多个常量,声明时必须进行初始化,且初始化后值不可再修改
const PI = 3.141592653589793;
PI = 3.14; // 报错
PI = PI + 10; // 报错
const 的本质: const 定义的变量并非常量,并非不可变,它定义了一个常量引用一个值。
使用 const 定义的对象或者数组,其实是可变的。下面的代码并不会报错:
// 创建常量对象
const car = {type:”Fiat”, model:”500″, color:”white”};
// 修改属性:
car.color = “red“;
// 添加属性
car.owner = “Johnson”;
// 创建常量数组
const cars = [“Saab“, “Volvo”, “BMW”];
// 修改元素
cars[0] = “Toyota”;
// 添加元素
cars.push(“Audi“);
23.JavaScript JSON
什么是 JSON
JSON 数据格式为 键/值 对,就像 JavaScript 对象属性。
“name”:”Runoob”
JSON 对象
JSON 对象保存在大括号内。
就像在 JavaScript 中, 对象可以保存多个 键/值 对:
JSON 数组
“sites”:[
{“name”:”Runoob”, “url“:”www.runoob.com”},
{“name”:”Google”, “url“:”www.google.com”},
{“name”:”Taobao”, “url“:”www.taobao.com”}
]
var text = ‘{ “sites” : [‘ +
‘{ “name”:”Runoob” , “url“:”www.runoob.com” },’ +
‘{ “name”:”Google” , “url“:”www.google.com” },’ +
‘{ “name”:”Taobao” , “url“:”www.taobao.com” } ]}’;
然后,使用 JavaScript 内置函数 JSON.parse() 将字符串转换为 JavaScript 对象:
最后,在你的页面中使用新的 JavaScript 对象:
var text = ‘{ “sites” : [‘ +
‘{ “name”:”Runoob” , “url“:”www.runoob.com” },’ +
‘{ “name”:”Google” , “url“:”www.google.com” },’ +
‘{ “name”:”Taobao” , “url“:”www.taobao.com” } ]}’;
obj = JSON.parse(text);
document.getElementById(“demo”).innerHTML = obj.sites[1].name + ” ” + obj.sites[1].url;
函数 | 描述 |
---|---|
JSON.parse() | 用于将一个 JSON 字符串转换为 JavaScript 对象。 |
JSON.stringify() | 用于将 JavaScript 值转换为 JSON 字符串。 |
要实现从JSON字符串转换为JS对象,使用 JSON.parse() 方法
//结果是 {a: 'Hello', b: 'World'} 一个对象 var obj = JSON.parse('{"a": "Hello", "b": "World"}');
要实现从JS对象转换为JSON字符串,使用 JSON.stringify() 方法
//结果是 ‘{“a”: “Hello“, “b”: “World”}’ 一个JSON格式的字符串
var json = JSON.stringify({a: 'Hello', b: 'World'});
javascript:void(0)
<a href=”javascript:void(0)”>单击此处什么也不会发生</a>
24.异步编程
异步(Asynchronous, async)是与同步(Synchronous, sync)相对的概念
程序的运行是同步的(同步不意味着所有步骤同时运行,而是指步骤在一个控制流序列中按顺序执行)。而异步的概念则是不保证同步的概念,也就是说,一个异步过程的执行将不再与原有的序列有顺序关系
回调函数
回调函数就是一个函数,它是在我们启动一个异步任务的时候就告诉它:等你完成了这个任务之后要干什么。这样一来主线程几乎不用关心异步任务的状态了,他自己会善始善终
setTimeout(function () {
document.getElementById(“demo”).innerHTML=”RUNOOB!”;
}, 3000);
25.JavaScript Promise
Promise 是一个 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务
由于 Promise 是 ES6 新增加的,所以一些旧的浏览器并不支持
构造 Promise
现在我们新建一个 Promise 对象
通过新建一个 Promise 对象好像并没有看出它怎样 “更加优雅地书写复杂的异步任务“。我们之前遇到的异步任务都是一次异步,如果需要多次调用异步函数呢?例如,如果我想分三次输出字符串,第一次间隔 1 秒,第二次间隔 4 秒,第三次间隔 3 秒
setTimeout(function () {
console.log(“First“);
setTimeout(function () {
console.log(“Second”);
setTimeout(function () {
console.log(“Third”);
}, 3000);
}, 4000);
}, 1000);
这段程序实现了这个功能,但是它是用 “函数瀑布” 来实现的。可想而知,在一个复杂的程序当中,用 “函数瀑布” 实现的程序无论是维护还是异常处理都是一件特别繁琐的事情,而且会让缩进格式变得非常冗赘。
现在我们用 Promise 来实现同样的功能:
new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(“First“);
resolve();
}, 1000);
}).then(function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(“Second”);
resolve();
}, 4000);
});
}).then(function () {
setTimeout(function () {
console.log(“Third”);
}, 3000);
});
Promise 的构造函数
Promise 构造函数是 JavaScript 中用于创建 Promise 对象的内置构造函数。
Promise 构造函数接受一个函数作为参数,该函数是同步的并且会被立即执行,所以我们称之为起始函数。起始函数包含两个参数 resolve 和 reject,分别表示 Promise 成功和失败的状态。
起始函数执行成功时,它应该调用 resolve 函数并传递成功的结果。当起始函数执行失败时,它应该调用 reject 函数并传递失败的原因。
Promise 构造函数返回一个 Promise 对象,该对象具有以下几个方法:
下面是一个使用 Promise 构造函数创建 Promise 对象的例子
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
if (Math.random() < 0.5) {
resolve(‘success‘);
} else {
reject(‘error‘);
}
}, 1000);
});
promise.then(result => {
console.log(result);
}).catch(error => {
console.log(error);
});
在上面的例子中,我们使用 Promise 构造函数创建了一个 Promise 对象,并使用 setTimeout 模拟了一个异步操作。如果异步操作成功,则调用 resolve 函数并传递成功的结果;如果异步操作失败,则调用 reject 函数并传递失败的原因。然后我们使用 then 方法处理 Promise 成功状态的回调函数,使用 catch 方法处理 Promise 失败状态的回调函数。
resolve 和 reject 都是函数,其中调用 resolve 代表一切正常,reject 是出现异常时所调用的
new Promise(function (resolve, reject) {
var a = 0;
var b = 1;
if (b == 0) reject(“Divide zero“);
else resolve(a / b);
}).then(function (value) {
console.log(“a / b = ” + value);
}).catch(function (err) {
console.log(err);
}).finally(function () {
console.log(“End”);
});
Promise 类有 .then() .catch() 和 .finally() 三个方法,这三个方法的参数都是一个函数,.then() 可以将参数中的函数添加到当前 Promise 的正常执行序列,.catch() 则是设定 Promise 的异常处理序列,.finally() 是在 Promise 执行的最后一定会执行的序列。 .then() 传入的函数会按顺序依次执行,有任何异常都会直接跳到 catch 序列
new Promise(function (resolve, reject) {
console.log(1111);
resolve(2222);
}).then(function (value) {
console.log(value);
return 3333;
}).then(function (value) {
console.log(value);
throw “An error“;
}).catch(function (err) {
console.log(err);
});
但是请注意以下两点:
Promise 函数
上述的 “计时器” 程序看上去比函数瀑布还要长,所以我们可以将它的核心部分写成一个 Promise 函数
function print(delay, message) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(message);
resolve();
}, delay);
});
}
print(1000, “First“).then(function () {
return print(4000, “Second”);
}).then(function () {
print(3000, “Third”);
});
异步函数
异步函数(async function)是 ECMAScript 2017 (ECMA-262) 标准的规范,几乎被所有浏览器所支持,除了 Internet Explorer。
在 Promise 中我们编写过一个 Promise 函数
function print(delay, message) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(message);
resolve();
}, delay);
});
}
print(1000, “First”).then(function () {
return print(4000, “Second”);
}).then(function () {
print(3000, “Third”);
});
我们可以将这段代码变得更好看
async function asyncFunc() {
await print(1000, “First”);
await print(4000, “Second”);
await print(3000, “Third”);
}
asyncFunc();
异步函数 async function 中可以使用 await 指令,await 指令后必须跟着一个 Promise,异步函数会在这个 Promise 运行中暂停,直到其运行结束再继续运行
async function asyncFunc() {
try {
await new Promise(function (resolve, reject) {
throw “Some error”; // 或者 reject(“Some error”)
});
} catch (err) {
console.log(err);
// 会输出 Some error
}
}
asyncFunc();
如果 Promise 有一个正常的返回值,await 语句也会返回它
async function asyncFunc() {
let value = await new Promise(
function (resolve, reject) {
resolve(“Return value”);
}
);
console.log(value);
}
asyncFunc();
- 1、Promise 对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)
- 2、Promise构造函数接收一个函数作为参数,该函数的两个参数分别是 resolve 和 reject
- 3、一个promise对象只能改变一次状态,成功或者失败后都会返回结果数据。
- 4、then 方法可以接收两个回调函数作为参数,第一个回调函数是Promise对象的状态改变为 resoved 是调用,第二个回调函数是 Promise 对象的状态变为 rejected 时调用。其中第二个参数可以省略。
- 5、catch 方法,该方法相当于最近的 then 方法的第二个参数,指向 reject 的回调函数,另一个作用是,在执行resolve回调函数时,如果出错,抛出异常,不会停止运行,而是进入catch 方法中。
注意:catch 只捕获最近的 then 的回调函数,前面的then的执行不成功的结果,有后面 then 的 reject 回调函数执行,如果没有后续 then 回调函数执行,则会被 catch 捕获执行
var promise =new Promise(function(resolve,reject){
//To Do 要异步执行的事情,这个异步执行的事情有可能成功执行完毕,那么Promise将是 fulfilled状态,如果执行失败则是rejected;
//下面测试代码,人为设置为rejected状态;
reject(“将当前构建的Promise对象的状态由pending(进行中)设置为rejected(已拒绝)”); //当然此处也可以设置为fulfilled(已完成)状态
})promise.then(//调用第一个then()
success=>{
console.log(“异步执行成功,状态为:fulfilled,成功后返回的结果是:”+success);
return(” 当前 success “);
},
error=>{
console.log(“异步执行失败,状态为rejected,失败后返回的结果是:”+error);
return(” 当前 error “);
}
).then(
//调用第二个then() 因为调用第一个then()方法返回的是一个新的promise对象,此对象的状态由上面的success或者error两个回调函数的执行情况决定的:
//如果回调函数能正常执行完毕,则新的promise对象的状态为fulfilled,下面执行success2,如果回调函数无法正常执行,则promise状态为rejected;下面执行error2
success2=>{
console.log(“第一个then的回调函数执行成功 成功返回结果:”+success2);
throw(” 当前 success2 “);//自定义异常抛出
},
error2=>{
console.log(“第一个then的回调函数执行失败 失败返回结果:”+error2);
return(” 当前 error2 “);
}
).catch(err=>{
//当success2或者error2执行报错时,catch会捕获异常;
console.log(“捕获异常:”+err);
});
26.JavaScript 函数
JavaScript 函数定义
JavaScript 使用关键字 function 定义函数。
函数可以通过声明定义,也可以是一个表达式
函数声明
function myFunction(a, b) { return a * b;}
函数表达式
var x = function (a, b) {return a * b};
var z = x(4, 3);
Function() 构造函数
在以上实例中,我们了解到函数通过关键字 function 定义。
函数同样可以通过内置的 JavaScript 函数构造器(Function())定义
var myFunction = new Function(“a”, “b”, “return a * b”);
var x = myFunction(4, 3);
实际上,你不必使用构造函数。上面实例可以写成
var myFunction = function (a, b) {return a * b};
var x = myFunction(4, 3);
箭头函数
ES6 新增了箭头函数。
(参数1, 参数2, …, 参数N) => { 函数声明 }
(参数1, 参数2, …, 参数N) => 表达式(单一)
// 相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }
当只有一个参数时,圆括号是可选的
(单一参数) => {函数声明}
单一参数 => {函数声明}
没有参数的函数应该写成一对圆括号
() => {函数声明}
// ES5
var x = function(x, y) {
return x * y;
}
// ES6
const x = (x, y) => x * y;
有的箭头函数都没有自己的 this。 不适合定义一个 对象的方法。
当我们使用箭头函数的时候,箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的。
箭头函数是不能提升的,所以需要在使用之前定义。
使用 const 比使用 var 更安全,因为函数表达式始终是一个常量。
如果函数部分只是一个语句,则可以省略 return 关键字和大括号 {},这样做是一个比较好的习惯
const x = (x, y) => { return x * y };
(参数) => { 函数体 }
// 普通函数
let sum = function(a, b) {
return a + b;
}// 箭头函数
let sum1 = (a, b) => {
return a + b;
}
省略包含参数的小括号
// 有效
let sum = (x) => {
return x;
};
// 有效
let sum1 = x => {
return x;
};
// 没有参数需要括号
let sum2 = () => {
return 1;
};
// 有多个参数需要括号
let sum3 = (a, b) => {
return a + b;
};
省略包含函数体的大括号
// 有效
let sum = (a, b) => {
return a + b;
};
// 有效
let sum1 = (a, b) => a + b; // 相当于 return a + b;
// 无效的写法
let sum2 = (a, b) => return a + b;
嵌入函数
let arr = [1, 2, 3, 4, 5];
arr.map(val => val * 2); // [2, 4, 6, 8, 10]
箭头函数不能使用arguments
// 普通函数
let sum = function() {
return arguments.length;
}
sum(1, 2, 3); // 3// 箭头函数
let sum1 = () => {
return arguments.length;
}sum1(1, 2); // Uncaught ReferenceError: arguments is not defined
虽然箭头函数中没有 arguments 对象,但可以在包装函数中把它提供给箭头函数:
function foo() {
let bar = () => {
console.log(arguments.length);
}
bar();
}
foo(5, 5, 5); // 3
箭头函数中this 指向
let num = 11;
const obj1 = {
num: 22,
fn1: function() {
let num = 33;
const obj2 = {
num: 44,
fn2: () => {
console.log(this.num);
}
}
obj2.fn2();
}
}
obj1.fn1(); // 22
fn2中得到的结果为:22
原因箭头函数没有this,箭头函数的this是继承父执行上下文里面的this ,这里箭头函数的执行上下文是函数fn1(),所以它就继承了fn1()的this,obj1调用的fn1,所以fn1的this指向obj1, 所以obj1.num 为 22。
注意:简单对象(非函数)是没有执行上下文的!
如果fn1也是个箭头函数呢?
let num = 11;
const obj1 = {
num: 22,
fn1: () => {
let num = 33;
const obj2 = {
num: 44,
fn2: () => {
console.log(this.num);
}
}
obj2.fn2();
}
}
obj1.fn1();
上述结果为undefined,因为fn1也是一个箭头函数,所以它就只能继续向上找也就是window了。
这里涉及到var和let声明变量的一个区别:使用 let 在全局作用域中声明的变量不会成为 window 对象的属性,var 声明的变量则会(不过,let 声明仍然是在全局作用域中发生的,相应变量会在页面的生命周期内存续,所以使用window访问会为undefined):
var a = 1;
window.a; // 1
将let改成var后:
var num = 11; //
const obj1 = {
num: 22,
fn1: () => {
let num = 33;
const obj2 = {
num: 44,
fn2: () => {
console.log(this.num);
}
}
obj2.fn2();
}
}
obj1.fn1();
此时结果为window.num => 11
JavaScript 函数参数
参数传递
function foo(a, b) {
console.log([a, b]);
}foo(1, 2); // 输出 [1, 2]
这个例子中,a
和 b
属于函数中的局部变量,只能在函数中访问。调用函数时,传递的数据会根据位置来匹配对应,分别赋值给 a
和 b
。
创建函数时,function 函数名
后面括号中设定的参数被称为形参;调用函数时,函数名后面括号中传入的参数被称为实参。
因为形参是已声明的变量,所以不能再用 let
和 const
重复声明
function foo(a, b) {
let a = 1; // 报错,a 已声明
const b = 1; // 报错,b 已声明
}
从一个变量赋值到另一个变量
function add(num) {
return num + 1;
}let count = 5;
let result = add(count); // 此处参数传递的过程可以看作是 num = countconsole.log(count); // 5
console.log(result); // 6
引用值:
function setName(obj) {
obj.name = “小明“;
}let person = {};
setName(person); // 此处参数传递的过程可以看作是 obj = person;
console.log(person); // {name: “小明“}
理解参数
JavaScript 中的函数既不会检测参数的类型,也不会检测传入参数的个数。定义函数时设置两个形参,不意味着调用时必须传入两个参数。实际调用时不管是传了一个还是三个,甚至不传参数也不会报错。
所有函数(非箭头)中都有一个名为 arguments 的特殊的类数组对象(不是 Array 的实例),它保存着所有实参的副本,我们可以通过它按照数组的索引访问方式获取所有实参的值,也可以访问它的 arguments.length 属性来确定函数实际调用时传入的参数个数。
function foo(a, b) {
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments.length);
}foo(10, 20); // 依次输出 10、20、2
将对象属性用作实参
当一个函数包含的形参有多个时,调用函数就成了一种麻烦,因为你总是要保证传入的参数放在正确的位置上,有没有办法解决传参顺序的限制呢?
由于对象属性是无序的,通过属性名来确定对应的值。因此可以通过传入对象的方式,以对象中的属性作为真正的实参,这样参数的顺序就无关紧要了。
function foo(obj) {
console.log(obj.name, obj.sex, obj.age);
}
参数默认值
如果调用函数时缺少提供实参,那么形参默认值为 undefined
。
有时候我们想要设置特定的默认值,在 ES6 之前还不支持显式地设置默认值的时候,只能采用变通的方式
function sayHi(name) {
name = name || ‘everyone’;
console.log( ‘Hello ‘ + name + ‘!’);
}
// if 语句判断
function sayHi(name) {
if (name === undefined) {
name = ‘everyone’;
}
console.log( ‘Hello ‘ + name + ‘!’);
}// 三元表达式判断
function sayHi(name) {
name = (name !== undefined) ? name : ‘everyone’;
console.log( ‘Hello ‘ + name + ‘!’);
}
function sayHi(name = ‘everyone’) { // 定义函数时,直接给形参赋值
console.log( ‘Hello ‘ + name + ‘!’);
}sayHi(); // 输出 ‘Hello everyone!’
sayHi(‘Tony’); // 输出 ‘Hello Tony!’
sayHi(undefined); // 输出 ‘Hello everyone!’
参数默认值的位置
function fn(x, y = 2) {
console.log([x, y]);
}fn(); // 输出 [undefined, 2]
fn(1); // 输出 [1, 2]
fn(1, 1) // 输出 [1, 1]
ES6 提供了**剩余参数(rest)**的语法(...变量名
),它可以收集函数多余的实参(即没有对应形参的实参),这样就不再需要使用 arguments
对象来获取了。形参使用了 ...
操作符会变成一个数组,多余的实参都会被放进这个数组中。
function sum(a, …values) {
for (let val of values) {
a += val;
}
return a;
}sum(0, 1, 2, 3); // 6
参数位置
// 报错
function fn1(a, …rest, b) {
console.log([a, b, rest]);
}// 正确写法
function fn2(a, b, …rest) {
console.log([a, b, rest]);
}fn2(1, 2, 3, 4) // 输出 [1, 2, [3, 4]]
function sum(…values) {
let sum = 0;
for (let val of values) {
sum += val;
}
return sum;
}let arr = [1, 2, 3, 4];
sum(arr); // “01,2,3,4”
把所有传进来的数值累加,如果直接传入一个数组,就得到我们想要的结果
sum(…arr); // 10 // 相当于 sum(1,2,3,4);
sum(-1, …arr); // 9
sum(…arr, 5); // 15
sum(-1, …arr, 5); // 14
sum(-1, …arr, …[5, 6, 7]); // 27
JavaScript 对象
对象只是一种特殊的数据。对象拥有属性和方法。
创建了对象的一个新实例,并向其添加了四个属性
JavaScript 对象就是一个 name:value 集合
person=new Object();
person.firstname=”John”;
person.lastname=”Doe”;
person.age=50;
person.eyecolor=”blue“;
{ name1 : value1, name2 : value2,…nameN : valueN }
原文地址:https://blog.csdn.net/qq_44438941/article/details/132731514
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_31614.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!