数组是一种特殊类型的对象。在JavaScript中对数组使用typeof运算符会返回“object”。
但是,JavaScript数组最好以数组来描述。
数组使用数字来访问其“元素”。比如person[0]访问person数组中的第一个元素。
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript 对象</h1>
<p>JavaScript 使用名称来访问对象属性。</p>
<p id="demo"></p>
<script>
var person = {firstName:"Bill", lastName:"Gates", age:19};
document.getElementById("demo").innerHTML = person["firstName"];
</script>
</body>
</html>
同样也可以用这种方式进行修改对象中的属性
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript 对象</h1>
<p>JavaScript 使用名称来访问对象属性。</p>
<p id="demo"></p>
<script>
var person = {firstName:"Bill", lastName:"Gates", age:19};
person["firstName"]="Tom"
document.getElementById("demo").innerHTML = person["firstName"];
</script>
</body>
</html>
遍历数组元素
比较常用的方法就是for循环
var fruits, text, fLen, i;
fruits = ["Banana", "Orange", "Apple", "Mango"];
fLen = fruits.length;
text = "<ul>";
for (i = 0; i < fLen; i++) {
text += "<li>" + fruits[i] + "</li>";
}
还有一种方法就是foreach()函数
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript 数组</h1>
<p>Array.forEach() 为每个数组元素调用函数。</p>
<p>Internet Explorer 8 以及更早的版本不支持 Array.forEach()。</p>
<p id="demo"></p>
<script>
var fruits, text;
fruits = ["Banana", "Orange", "Apple", "Mango"];
text = "<ul>";
fruits.forEach(myFunction);
text += "</ul>";
document.getElementById("demo").innerHTML = text;
function myFunction(value) {
text += "<li>" + value + "</li>";
}
</script>
</body>
</html>
数组和对象的区别
在JS中,数组使用数字索引;对象使用命名索引。
数组是特殊类型的对象,具有数字索引。
那么什么时候使用数组,什么时候使用对象?
①js不支持关联数组
②如果希望元素名为字符串(文本)则应该使用对象。
③如果希望元素名为数字则应该使用数组
如何识别数组
常见的问题是:我如何知道某个变量是否是数组?
问题在于JS运算符typeof返回"object"
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript 数组</h1>
<p>typeof 运算符在数组上使用时返回 object:</p>
<p id="demo"></p>
<script>
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = typeof fruits;
</script>
</body>
</html>
还可以用ECMAscript 5定义的新方法Array.isArray():
Array.isArray(fruits); // 返回 true
假如对象由给定的构造器创建,则可以用instanceof运算符看返回的结果是否为true:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits instanceof Array // 返回 true
JavaScript Hoisting
提升(Hoising)是JavaScript将声明移至顶部的默认行为。
JavaScript声明会被提升
在JavaScript中,可以在使用变量之后对其进行声明。
换句话说,可以在声明变量之前使用它。
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
x = 5; // 把 5 赋值给 x
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x; // 在这个元素中显示 x
var x; // Declare x
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var x; // 声明 x
x = 5; // 把 5 赋值给 x
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x; // 在这个元素中显示 x
</script>
</body>
</html>
Hoisting是JavaScript将所有声明提升到当前作用域顶部的默认行为(提升到当前脚本或当前函数的顶部)
注意:用let 或const声明的变量和常量不会被提升!
JavaScript初始化不会被提升
JavaScript只提升声明,而非初始化。
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var x = 5; // 初始化 x
var y = 7; // 初始化 y
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y; // 显示 x 和 y
</script>
</body>
</html>
这里的两个值会正常显示
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var x = 5; // 初始化 x
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = "x is " + x + " and y is " + y; // 显示 x 和 y
var y = 7; // Initialize y
</script>
</body>
</html>
这里的7就会显示未定义。
因为只有声明(var 7)而不是(=7)被提升到顶部。
由于hoisting,y在其使用前已经被声明,但是由于未对初始化进行提升,y的值仍然是未定义。如下所示:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var x = 5; // 初始化 x
var y; // 声明 y
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y; // 显示 x 和 y
y = 7; // Assign 7 to y
</script>
</body>
</html>
所以,我们需要在顶部声明变量!
hoisting(对很多开发者来说)是JavaScript的一种未知的或被忽视的行为。如果开发者不理解hoisting,程序也许会包含bug(错误)。为了避免bug,请始终在每个作用域的开头声明所有变量。这就是JavaScript解释代码的方式,请保持这个好习惯。严格模式中的JavaScript不允许在未被声明的情况下使用变量。
JavaScript严格模式
“use strict”;定义JavaScript代码应该以“严格模式”执行。
“use strict”不算一条语句,而是一段文字表达式,更早版本的JavaScript会忽略它。
“use strict”;的作用是指示JavaScript代码应该以“严格模式”执行。
在严格模式中,无法使用未声明的变量。
<!--
* @Author: RealRoad
* @Date: 2023-03-11 10:10:06
* @LastEditors: Mei
* @LastEditTime: 2023-03-11 10:59:53
* @FilePath: \vscode\特殊.html
* @Description:
*
* Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
"use strict"
x=3.14;
</script>
</head>
<body>
</body>
</html>
当我们加上声明,就不会报错
<script>
"use strict"
var x=3.14;
</script>
在函数中声明严格模式,拥有局部作用域(只有函数中的代码以严格模式执行):
x = 3.14; // 这不会引发错误
myFunction();
function myFunction() {
"use strict";
y = 3.14; // 这会引发错误
}
那么为什么要使用严格模式呢?
严格模式使我们更容易编写“安全的”JavaScript。
严格模式把之前可接受的“坏语法”转变为真实的错误。
举例来说,在普通的JavaScript中,错打变量名会创建新的全局变量。在严格模式中,此举将抛出错误,这样就不可能意外创建全局变量。
在普通JavaScript中,如果向不可写属性赋值,开发者不会得到任何错误反馈。
在严格模式中,向不可写的、只能读取的、不存在的属性赋值,或者向不存在的变量或对象赋值,将抛出错误。
删除变量(或对象)是不允许的:
<!--
* @Author: RealRoad
* @Date: 2023-03-11 10:10:06
* @LastEditors: Mei
* @LastEditTime: 2023-03-11 11:08:56
* @FilePath: \vscode\特殊.html
* @Description:
*
* Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
"use strict"
var x=3.14;
delete x;
</script>
</head>
<body>
</body>
</html>
重复函数名是不允许的:
"use strict";
function x(p1, p1) {}; // 这将引发错误
八进制数值文本是不允许的:
"use strict";
var x = 010; // 这将引发错误
转义字符是不允许的:
"use strict";
var x = \010; // 这将引发错误
写入只读属性是不允许的:
"use strict";
var obj = {};
Object.defineProperty(obj, "x", {value:0, writable:false});
obj.x = 3.14; // 这将引发错误
写入获取的属性是不允许的:
"use strict";
var obj = {get x() {return 0} };
obj.x = 3.14; // 这将引发错误
删除不可删除的属性是不允许的:
"use strict";
delete Object.prototype; // 这将引发错误
with语句也是不允许的:
"use strict";
with (Math){x = cos(2)}; // 这将引发错误
不允许eval()在其被调用的作用域中创建变量:
"use strict";
eval("var x = 2");
alert (x); // 这将引发错误
严格模式中不允许使用为未来预留的关键词。它们是:
implements
interface
let
package
private
protected
public
static
yield
<!--
* @Author: RealRoad
* @Date: 2023-03-11 10:10:06
* @LastEditors: Mei
* @LastEditTime: 2023-03-11 11:16:12
* @FilePath: \vscode\特殊.html
* @Description:
*
* Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
"use strict"
var public=3.14;
// delete x;
</script>
</head>
<body>
</body>
</html>
注意:use strict指令只能在脚本或函数的开头被识别。
this
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript <b>this</b> 关键词</h1>
<p>在本例中,<b>this</b> 代表 <b>person</b> 对象。</p>
<p>因为 person 对象“拥有” fullName 方法。</p>
<p id="demo"></p>
<script>
// 创建对象:
var person = {
firstName: "Bill",
lastName : "Gates",
id : 678,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
// 显示来自对象的数据:
document.getElementById("demo").innerHTML = person.fullName();
</script>
</body>
</html>
this关键字指的是它所属的对象。
它拥有不同的值,具体取决于它的使用位置:
在方法中,this指的是所有者对象。
单独的情况下,this指的是全局对象。
在函数中,this指的是全局对象。
在函数中,严格模式下,this是undefined
在事件中,this指的是接收事件的元素
比如call()和apply()这样的方法可以将this引用到任何对象。
函数中的this(默认)
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript <b>this</b> 关键词</h1>
<p>在本例中,<b>this</b> 代表“拥有” myFunction 的对象:</p>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = myFunction();
function myFunction() {
x="123"
return this.x;
}
</script>
</body>
</html>
这里的结果就是this.x的输出为123.
事件处理程序中的this
在HTML事件处理程序中,this值得是接收此事件的HTML元素:
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript <b>this</b> 关键词</h1>
<button onclick="this.style.display='none'">单击来删除我!</button>
</body>
</html>