script标签
所有的内容都应放在script标签内
<script>
document.getElementById("demo").innerHTML = "我的第一段 JavaScript";
</script>
给p标签设置id
<p id="demo">JavaScript 能够改变 HTML 内容。</p>
button标签使用。
<button type="button" onclick='document.getElementById("demo").innerHTML = "Hello JavaScript!"'>点击我!</button>
修改p标签文字内容
这条语句告诉浏览器在 id="demo" 的 HTML 元素中输出 "Hello JavaScript.":
'document.getElementById("demo").innerHTML = "Hello JavaScript!"'
如果不想点击button修改位置也可以
<script>
document.getElementById("demo").innerHTML = "我的第一段 JavaScript";
</script>
document.write
该代码会直接在网页中添加一个标签,但仅用于测试
<script>
document.write(5 + 6)
</script>
警告框
<button type="button" onclick="window.alert(5 + 6)">试一试</button>
log
debugger 中选择 "Console"。然后再次点击运行按钮。
<script>
console.log(5 + 6);
</script>
变量
这里的 x,y,z都没给数据类型,应该像swift一样有类型推断。 String类型也可以直接用 + 号连接起来。
<script>
var x, y, z; // 语句 1
x = 22; // 语句 2
y = 11; // 语句 3
z = x + y; // 语句 4
document.getElementById("demo").innerHTML =
"d 的值是"+ z + "。";
</script>
并且字符串可以跟Int类型相加。。。。令我十分惊讶。。
var x = "8" + 3 + 5; x: "835"
var x = 3 + 5 + "8"; x: "88"
JavaScript 关键词
| 关键词 | 描述 |
|---|---|
| break | 终止 switch 或循环。 |
| continue | 跳出循环并在顶端开始。 |
| debugger | 停止执行 JavaScript,并调用调试函数(如果可用)。 |
| do ... while | 执行语句块,并在条件为真时重复代码块。 |
| for | 标记需被执行的语句块,只要条件为真。 |
| function | 声明函数。 |
| if ... else | 标记需被执行的语句块,根据某个条件。 |
| return | 退出函数。 |
| switch | 标记需被执行的语句块,根据不同的情况。 |
| try ... catch | 对语句块实现错误处理。 |
| var | 声明变量。 |
注:JavaScript 关键词指的是保留的单词。保留词无法用作变量名。
JavaScript 与驼峰式大小写
JavaScript 程序员倾向于使用以小写字母开头的驼峰大小写:
firstName, lastName, masterCard, interCity
全局作用域变量
全局(在函数之外)声明的变量拥有全局作用域。
<script>
var carName = "porsche";
myFunction();
function myFunction() {
document.getElementById("demo").innerHTML =
"I can display " + carName;
}
</script>
JavaScript 块作用域
通过 var 关键词声明的变量没有块作用域。
块内部生命的变量,可以在块外部访问,而且块内部的变量声明会覆盖掉外部的变量。(JavaScript允许两个名字一模一样的变量)
※※※※※※※※※※※※※※※※※※※※※※※※※※※※
这点需要特别注意,JS中可重新声明同名变量。如变量使用 var 标记,那么函数内部会修改函数外部的变量值,下面有“重新声明“的使用说明
※※※※※※※※※※※※※※※※※※※※※※※※※※※※
<script>
var x = 10;
// Here x is 10
{
var x = 2;
// Here x is 2
}
// Here x is 2
document.getElementById("demo").innerHTML = x;
</script>
通过 let 关键词声明的变量拥有块作用域。
<script>
var x = 10;
// Here x is 10
{
let x = 2;
// Here x is 2
}
// Here x is 2
document.getElementById("demo").innerHTML = x;
</script>
浏览器支持
Internet Explorer 11 或更早的版本不完全支持 let 关键词。
下表定义了第一个完全支持 let 关键词的浏览器版本:
| Chrome 49 | IE / Edge 12 | Firefox 44 | Safari 11 | Opera 36 |
|---|---|---|---|---|
| 2016 年 3 月 | 2015 年 7 月 | 2015 年 1 月 | 2017 年 9 月 | 2016 年 3 月 |
循环作用域
在循环中使用 var:
var i = 7;
for (var i = 0; i < 10; i++) {
// 一些语句
}
// 此处,i 为 10
在循环中使用 let:
let i = 7;
for (let i = 0; i < 10; i++) {
// 一些语句
}
// 此处 i 为 7
HTML 中的全局变量
使用 JavaScript 的情况下,全局作用域是 JavaScript 环境。
在 HTML 中,全局作用域是 window 对象。
通过 var 关键词定义的全局变量属于 window 对象:
var carName = "porsche";
// 此处的代码可使用 window.carName
通过 let 关键词定义的全局变量不属于 window 对象:
let carName = "porsche";
// 此处的代码不可使用 window.carName
重新声明
允许在程序的任何位置使用 var 重新声明 JavaScript 变量:(这个特性令我很惊讶)
var x = 10;
// 现在,x 为 10
var x = 6;
// 现在,x 为 6
在相同的作用域,或在相同的块中,通过 let 重新声明一个 var 变量是不允许的:
var x = 10; // 允许
let x = 6; // 不允许
{
var x = 10; // 允许
let x = 6; // 不允许
}
在相同的作用域,或在相同的块中,通过 let 重新声明一个 let 变量是不允许的:
let x = 10; // 允许
let x = 6; // 不允许
{
let x = 10; // 允许
let x = 6; // 不允许
}
在相同的作用域,或在相同的块中,通过 var 重新声明一个 let 变量是不允许的:
let x = 10; // 允许
var x = 6; // 不允许
{
let x = 10; // 允许
var x = 6; // 不允许
}
在不同的作用域或块中,通过 let 重新声明变量是允许的:
let x = 6; // 允许
{
let x = 7; // 允许
}
{
let x = 8; // 允许
}
大概理解了一些,`var`是可变的。`let`是不可变的。
首先同作用于内他们两个不可相互重新声明,再者`let`标记的不可变对象不可重新声明。
重新声明特性,只针对标记为`var`的变量。
var 提升
又一个令我惊讶的特性!!! 声明为var的变量可以在声明前使用。
let不支持
const不支持
<script>
carName = "Audi";
document.getElementById("demo").innerHTML = carName;
var carName;
</script>
JavaScript Const
ES2015 引入了两个重要的 JavaScript 新关键词:let 和 const。
通过 const 定义的变量与 let 变量类似,但不能重新赋值:
他必须在声明时赋值
//正确
const PI = 3.14159265359;
//错误
const PI1;
PI1 = 3.14159265359
常量对象不可重新赋值
const PI = 3.141592653589793;
PI = 3.14; // 会出错
PI = PI + 10; // 也会出错
但是可以修改常量对象的属性
// 您可以创建 const 对象:
const car = {type:"porsche", model:"911", color:"Black"};
// 您可以更改属性:
car.color = "White";
// 您可以添加属性:
car.owner = "Bill";
无法为常量对象赋值
const car = {type:"porsche", model:"911", color:"Black"};
car = {type:"Volvo", model:"XC60", color:"White"}; // ERROR
常量数组可以修改内容
// 您可以创建常量数组:
const cars = ["Audi", "BMW", "porsche"];
// 您可以更改元素:
cars[0] = "Honda";
// 您可以添加元素:
cars.push("Volvo");
但是常量数组不可以重新赋值
const cars = ["Audi", "BMW", "porsche"];
cars = ["Honda", "Toyota", "Volvo"]; // ERROR
浏览器支持
Internet Explorer 10 或更早版本不支持 const 关键词。
下表定义了第一个完全支持 const 关键词的浏览器版本:
| Chrome 49 | IE / Edge 11 | Firefox 36 | Safari 10 | Opera 36 |
|---|---|---|---|---|
| 2016 年 3 月 | 2013 年 10 月 | 2015 年 2 月 | 2016 年 9 月 | 2016 年 3 月 |
运算符
比较运算符
记录两个特别的
| 运算符 | 描述 |
|---|---|
| === | 等值等型 |
| !== | 不等值或不等型 |
类型运算符
| 运算符 | 描述 |
|---|---|
| typeof | 返回变量的类型。 |
| instanceof | 返回 true,如果对象是对象类型的实例。 |
算数
+ - * / % ++ -- 就不用说了。
说一下 幂**
取幂运算符(**)将第一个操作数提升到第二个操作数的幂。
var x = 5;
var z = x ** 3; // 结果是 125 5*5*5
JavaScript 数据类型
JavaScript 拥有动态类型
这里重新var声明重新赋值,可以替换掉原来的数据类型
var x; // 现在 x 是 undefined
var x = 7; // 现在 x 是数值
var x = "Bill"; // 现在 x 是字符串值
字符串中使用引号 ""&''
var answer = "It's alright"; // 双引号内的单引号
var answer = "He is called 'Bill'"; // 双引号内的单引号
var answer = 'He is called "Bill"'; // 单引号内的双引号
超大或超小的数值可以用科学计数法来写:
var y = 123e5; // 12300000
var z = 123e-5; // 0.00123
ECMAScript 定义类或对象/字典
var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"};
//可以直接使用点语法,通过key获取value
person.age
这里的重点是 fullName,它是一个函数,也就是说通过key:value的方式可以在对象内部声明一个函数,这简直是太神奇了。
var person = {
firstName: "Bill",
lastName : "Gates",
id : 678,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
下面这个例子,我感慨 这个类型推断太好用了 。
工厂方式创建对象
function createCar(sColor,iDoors,iMpg) {
var oTempCar = new Object;
oTempCar.color = sColor;
oTempCar.doors = iDoors;
oTempCar.mpg = iMpg;
oTempCar.showColor = function() {
alert(this.color);
};
return oTempCar;
}
var oCar1 = createCar("red",4,23);
var oCar2 = createCar("blue",3,25);
oCar1.showColor(); //输出 "red"
oCar2.showColor(); //输出 "blue"
甚至可以这样创建对象:
构造函数创建对象
function Car(sColor,iDoors,iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.showColor = function() {
alert(this.color);
};
}
var oCar1 = new Car("red",4,23);
var oCar2 = new Car("blue",3,25);
原型方式
function Car() {
}
Car.prototype.color = "blue";
var oCar1 = new Car();
var oCar2 = new Car();
检测对象是否是某个类型
instanceof 运算符检查给定变量指向的对象的类型。因此,下面的代码将输出 TRUE:
alert(oCar1 instanceof Car); //输出 "true"
原型方式的问题
原型方式看起来是个不错的解决方案。遗憾的是,它并不尽如人意。
首先,这个构造函数没有参数。使用原型方式,不能通过给构造函数传递参数来初始化属性的值,因为 Car1 和 Car2 的 color 属性都等于 "blue",doors 属性都等于 4,mpg 属性都等于 25。这意味着必须在对象创建后才能改变属性的默认值,这点很令人讨厌,但还没完。真正的问题出现在属性指向的是对象,而不是函数时。函数共享不会造成问题,但对象却很少被多个实例共享。请思考下面的例子:
function Car() {
}
Car.prototype.color = "blue";
Car.prototype.doors = 4;
Car.prototype.mpg = 25;
Car.prototype.drivers = new Array("Mike","John");
Car.prototype.showColor = function() {
alert(this.color);
};
var oCar1 = new Car();
var oCar2 = new Car();
oCar1.drivers.push("Bill");
alert(oCar1.drivers); //输出 "Mike,John,Bill"
alert(oCar2.drivers); //输出 "Mike,John,Bill"
上面的代码中,属性 drivers 是指向 Array 对象的指针,该数组中包含两个名字 "Mike" 和 "John"。由于 drivers 是引用值,Car 的两个实例都指向同一个数组。这意味着给 oCar1.drivers 添加值 "Bill",在 oCar2.drivers 中也能看到。输出这两个指针中的任何一个,结果都是显示字符串 "Mike,John,Bill"。
由于创建对象时有这么多问题,你一定会想,是否有种合理的创建对象的方法呢?答案是有,需要联合使用构造函数和原型方式。
问题
- 1.创建Car的时候里面有默认值,需要在创建后修改
- 2.对象内的属性对象共享
解决方案
- 需要联合使用构造函数和原型方式
混合的构造函数/原型方式
推荐使用的方法。
function Car(sColor,iDoors,iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike","John");
}
Car.prototype.showColor = function() {
alert(this.color);
};
var oCar1 = new Car("red",4,23);
var oCar2 = new Car("blue",3,25);
oCar1.drivers.push("Bill");
alert(oCar1.drivers); //输出 "Mike,John,Bill"
alert(oCar2.drivers); //输出 "Mike,John"
typeof 运算符
typeof 运算符可返回以下两种类型之一:
- function
- object
typeof {name:'Bill', age:62} // 返回 "object"
typeof [1,2,3,4] // 返回 "object" (并非 "array",参见下面的注释)
typeof null // 返回 "object"
typeof function myFunc(){} // 返回 "function"
typeof 运算符把数组返回为 "object",因为在 JavaScript 中数组即对象。
原始数据
原始数据值是一种没有额外属性和方法的单一简单数据值。
typeof 运算符可返回以下原始类型之一:
- string
- number
- boolean
- undefined
typeof "Bill" // 返回 "string"
typeof 3.14 // 返回 "number"
typeof true // 返回 "boolean"
typeof false // 返回 "boolean"
typeof x // 返回 "undefined" (假如 x 没有值)
这里需要特别注意
这里 firstName 是原始数据 String
var firstName = "Bill"
这里 firstName 是new出来的对象
var firstName = new String("Bill")
var x = "Bill";
var y = new String("Bill");
// typeof x 将返回 string
// typeof y 将返回 object
请不要把字符串创建为对象。它会拖慢执行速度。
new 关键字使代码复杂化。也可能产生一些意想不到的结果:
当使用 == 相等运算符时,相等字符串是相等的:
var x = "Bill";
var y = new String("Bill");
// (x == y) 为 true,因为 x 和 y 的值相等
当使用 === 运算符时,相等字符串是不相等的,因为 === 运算符需要类型和值同时相等。
var x = "Bill";
var y = new String("Bill");
// (x === y) 为 false,因为 x 和 y 的类型不同(字符串与对象)
甚至更糟。对象无法比较:
var x = new String("Bill");
var y = new String("Bill");
// (x === y) 为 false,因为 x 和 y 是不同的对象
JavaScript 对象无法进行对比,比较两个 JavaScript 将始终返回 false。
Undefined 与 Null 的区别
typeof undefined // undefined
typeof null // object
null === undefined // false
null == undefined // true
函数
JavaScript 函数语法
JavaScript 函数通过 function 关键词进行定义,其后是函数名和括号 ()。
函数名可包含字母、数字、下划线和美元符号(规则与变量名相同)。
function name(参数 1, 参数 2, 参数 3) {
要执行的代码
}
令我感觉到惊讶的是,函数参数不用指定类型。他会自动类型推断
function testFun(a, b, c) {
return a+b+c
}
let temp = testFun("1", 2, 3) //输入“123”
上面函数声明为下面形式就不行了,不知道为何,后面知道了在来补充
function testFun(a:String, b, c) {
return a+b+c
};
声明空的对象/字符串
var x = new String(); // 把 x 声明为 String 对象
var y = new Number(); // 把 y 声明为 Number 对象
var z = new Boolean(); // 把 z 声明为 Boolean 对象
HTML 事件
HTML 事件可以是浏览器或用户做的某些事情。
下面是 HTML 事件的一些例子:
- HTML 网页完成加载
- HTML 输入字段被修改
- HTML 按钮被点击
通常,当事件发生时,用户会希望做某件事。
JavaScript 允许您在事件被侦测到时执行代码。
| 事件 | 描述 |
|---|---|
| onchange | HTML 元素已被改变 |
| onclick | 用户点击了 HTML 元素 |
| onmouseover | 用户把鼠标移动到 HTML 元素上 |
| onmouseout | 用户把鼠标移开 HTML 元素 |
| onkeydown | 用户按下键盘按键 |
| onload | 浏览器已经完成页面加载 |
HTML DOM 事件
HTML DOM 事件允许 JavaScript 在 HTML 文档中的元素上注册不同的事件处理程序。
表格
字符串方法String
长度
var txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var sln = txt.length;
查找字符串中的字符串
如果找到返回首字符位置,找不到返回-1
var str = "The full name of China is the People's Republic of China.";
var pos = str.indexOf("China");
var pos = str.lastIndexOf("China");
var pos = str.indexOf("China",18);//从第18个下标向后查找
var pos = str.lastIndexOf("China", 50);//从第50个下标向前查找
var pos = str.search("China");//search() 方法返回字符串中指定文本第一次出现的位置:
str..match("China") //返回 China
//搜索China 返回数组 [China,China]
str.match(/China/g)
//不区分大小写搜索 China 返回数组 [China,China]
str.match(/China/gi)
//字符串中是否存在该值
str.includes("China") // 返回 true
indexOf() 与 search()这两种方法是不相等的。区别在于:
- search() 方法无法设置第二个开始位置参数。
- indexOf() 方法无法设置更强大的搜索值(正则表达式)。
String.includes()浏览器支持。
Internet Explorer 不支持 String.includes()。
| Chrome 41 | Edge 12 | Firefox 40 | Safari 9 | Opera 28 |
|---|---|---|---|---|
| 2015 年 3 月 | 2015 年 7 月 | 2015 年 8 月 | 2015 年 10 月 | 2015 年 3 月 |
string.includes(searchvalue, start)
| searchvalue | 必需。需要搜索的字符串。 |
|---|---|
| start | 可选。默认为 0. 开始搜索的位置。 |
| 返回: | 如果字符串包含该值则返回 true,否则返回 false。 |
| JS 版本: | ES6 (2015) |
检查字符串是否包含 "world",从位置 12 开始搜索:
let text = "Hello world, welcome to the universe.";
text.includes("world", 12) // 返回 false
提取部分字符串
有三种提取部分字符串的方法:
- slice(start, end)
- substring(start, end)
- substr(start, length)
var str = "Apple, Banana, Mango";
var res = str.slice(7,13);//7-13 不包括7 Banana
var res = str.slice(-13,-7);//-13 - -7 不包括-7 Banana
var res = str.slice(7);//省略第二个参数,将裁剪字符串的剩余部分 Banana, Mango
var res = str.slice(-13);省略第二个参数,将裁剪字符串的剩余部分 Banana, Mango
substring() 方法
substring() 类似于 slice()。
不同之处在于 substring() 无法接受负的索引。
var str = "Apple, Banana, Mango";
var res = str.substring(7,13);
如果省略第二个参数,则该 substring() 将裁剪字符串的剩余部分。
String.startsWith()
如果字符串以指定值开头,则 startsWith() 方法返回 true,否则返回 false:
string.startsWith(searchvalue, start)
| 参数 | 描述 |
|---|---|
| searchvalue | 必需。需要搜索的值。 |
| start | 可选。默认为 0。开始搜索的位置。 |
let text = "Hello world, welcome to the universe.";
text.startsWith("world") // 返回 false
let text = "Hello world, welcome to the universe.";
text.startsWith("world", 5) // 返回 false
let text = "Hello world, welcome to the universe.";
text.startsWith("world", 6) // 返回 true
注释:startsWith() 方法区分大小写。
Internet Explorer 不支持 startsWith() 方法。
| Chrome 41 | Edge 12 | Firefox 17 | Safari 9 | Opera 28 |
|---|---|---|---|---|
| 2015 年 3 月 | 2015 年 7 月 | 2015 年 8 月 | 2015 年 10 月 | 2015 年 3 月 |
String.endsWith()
如果字符串以指定值结尾,则 endsWith() 方法返回 true,否则返回 false:
string.endsWith(searchvalue, length)
| 参数 | 描述 |
|---|---|
| searchvalue | 必需。需要搜索的值。 |
| length | 可选。要搜索的长度。 |
检索以 "world" 结尾的字符串的前 11 个字符:
let text = "Hello world, welcome to the universe.";
text.endsWith("world", 11) // 返回 true
注释:endsWith() 方法区分大小写。
Internet Explorer 不支持 endsWith() 方法。
第一个完全支持该方法的浏览器版本是:
| Chrome 51 | Edge 15 | Firefox 54 | Safari 10 | Opera 38 |
|---|---|---|---|---|
| 2016 年 5 月 | 2017 年 4 月 | 2017 年 6 月 | 2016 年 9 月 | 2016 年 6 月 |
substr() 方法
substr() 类似于 slice()。
不同之处在于第二个参数规定被提取部分的长度。
var str = "Apple, Banana, Mango";
var res = str.substr(7,6);//Banana
//如果省略第二个参数,则该 substr() 将裁剪字符串的剩余部分。
var res = str.substr(7);//Banana, Mango
//如果首个参数为负,则从字符串的结尾计算位置。
var res = str.substr(-5);//Mango
第二个参数不能为负,因为它定义的是长度。
替换字符串内容
replace() 方法用另一个值替换在字符串中指定的值:
str = "Please visit Microsoft!";
var n = str.replace("Microsoft", "W3School");//Please visit W3School!
replace() 方法不会改变调用它的字符串。它返回的是新字符串。
默认地,replace() 只替换首个匹配:
str = "Please visit Microsoft and Microsoft!";
var n = str.replace("Microsoft", "W3School");//Please visit W3School and Microsoft!
默认地,replace() 对大小写敏感。因此不对匹配 MICROSOFT:
str = "Please visit Microsoft!";
var n = str.replace("MICROSOFT", "W3School");
如需执行大小写不敏感的替换,请使用正则表达式 /i(大小写不敏感):
str = "Please visit Microsoft!";
var n = str.replace(/MICROSOFT/i, "W3School");//Please visit W3School!
请注意正则表达式不带引号。
如需替换所有匹配,请使用正则表达式的 g 标志(用于全局搜索):
str = "Please visit Microsoft and Microsoft!";
var n = str.replace(/Microsoft/g, "W3School");//Please visit W3School and W3School!
转换为大写和小写
通过 toUpperCase() 把字符串转换为大写:
通过 toLowerCase() 把字符串转换为小写:
var text1 = "Hello World!"; // 字符串
var text2 = text1.toUpperCase(); // HELLO WORLD!
var text3 = text1.toLowerCase(); // hello world!
字符串 concat() 方法
concat() 连接两个或多个字符串:
var text1 = "Hello";
var text2 = "World!";
var text3 = "toJS";
var text4 = text1.concat(" ",text2," ", text3);//Hello World! toJS
concat() 方法可用于代替加运算符。下面两行是等效的:
var text = "Hello" + " " + "World!";
var text = "Hello".concat(" ","World!");
所有字符串方法都会返回新字符串。它们不会修改原始字符串。
正式地说:字符串是不可变的:字符串不能更改,只能替换。
String.trim()
trim() 方法删除字符串两端的空白符:
var str = " Hello World! ";
alert(str.trim());//Hello World!
警告:Internet Explorer 8 或更低版本不支持 trim() 方法。
如需支持 IE 8,您可搭配正则表达式使用 replace() 方法代替:
例子:
var str = " Hello World! ";
alert(str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''));
还可以使用上面的 replace 方案把 trim 函数添加到 JavaScript String.prototype:
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
var str = " Hello World! ";
alert(str.trim());
提取字符串字符
这是两个提取字符串字符的安全方法:
- charAt(position)
- charCodeAt(position)
charAt() 方法返回字符串中指定下标(位置)的字符串:
charCodeAt() 方法返回字符串中指定索引的字符 unicode 编码:
var str = "HELLO WORLD";
str.charAt(0); //返回 H
str.charCodeAt(0);// 返回 72
你也可以使用属性访问,
var str = "HELLO WORLD";
str[0];//返回 H
使用属性访问有点不太靠谱:
- 不适用 Internet Explorer 7 或更早的版本
- 它让字符串看起来像是数组(其实并不是)
- 如果找不到字符,
[ ]返回undefined,而charAt()返回空字符串。 - 它是只读的。
str[0] = "A"不会产生错误(但也不会工作!)
var str = "HELLO WORLD";
str[0] = "A"; // 不产生错误,但不会工作
str[0]; // 返回 H
把字符串转换为数组
可以通过 split() 将字符串转换为数组:
var txt = "a,b,c,d,e"; // 字符串
txt.split(","); // 用逗号分隔
txt.split(" "); // 用空格分隔
txt.split("|"); // 用竖线分隔
如果分隔符是 "",被返回的数组将是间隔单个字符的数组:
var txt = "Hello"; // 字符串
var arr = txt.split(""); // 分隔为字符 [H, e, l, l, o]
字符串模板
Back-Tics 语法
模板字面量使用反引号 (``) 而不是引号 ("") 来定义字符串:
let text = `Hello World!`;
Mac电脑上反引号输出,英文输入法下 option + 数字1左边的按钮。
字符串内的引号
通过使用模板字面量,您可以在字符串中同时使用单引号和双引号:
let text = `He's often called "Johnny"`;
模板字面量允许多行字符串:
let text =
`The quick
brown fox
jumps over
the lazy dog`;
插值
${...}
JavaScript 数字
整数(不使用指数或科学计数法)会被精确到 15 位。
var x = 999999999999999; // x 将是 999999999999999
var y = 9999999999999999; // y 将是 1000000000000000
小数的最大数是 17 位,但是浮点的算数并不总是 100% 精准:
var x = 0.2 + 0.1; // x 将是 0.30000000000000004
使用乘除法有助于解决上面的问题:
var x = (0.2 * 10 + 0.1 * 10) / 10; // x 将是 0.3
数字+字符串容易出错的地方
var x = 10;
var y = 20;
var z = "The result is: " + x + y;//The result is: 1020
var x = 10;
var y = 20;
var z = "30";
var result = x + y + z;//3030
在所有数字运算中,JavaScript 会尝试将字符串转换为数字:
var x = "100";
var y = "10";
var z = x / y; // z 将是 10
var x = "100";
var y = "10";
var z = x * y; // z 将是 1000
var x = "100";
var y = "10";
var z = x - y; // z 将是 90
但是该例不会如上例般运行:
var x = "100";
var y = "10";
var z = x + y; // z 不会是 110(而是 10010)
NaN - 非数值
NaN 属于 JavaScript 保留词,指示某个数不是合法数。
尝试用一个非数字字符串进行除法会得到 NaN(Not a Number):
var x = 100 / "Apple"; // x 将是 NaN(Not a Number)
您可使用全局 JavaScript 函数 isNaN() 来确定某个值是否是数:
var x = 100 / "Apple";
isNaN(x); // 返回 true,因为 x 不是数
要小心 NaN。假如您在数学运算中使用了 NaN,则结果也将是 NaN:
var x = NaN;
var y = 5;
var z = x + y; // z 将是 NaN
也可相加
var x = NaN;
var y = "5";
var z = x + y; // z 将是 NaN5
NaN 是数,typeof NaN 返回 number:
typeof NaN; // 返回 "number"
Infinity
Infinity (或 -Infinity)是 JavaScript 在计算数时超出最大可能数范围时返回的值。
var myNumber = 2;
while (myNumber != Infinity) { // 执行直到 Infinity
myNumber = myNumber * myNumber;
}
除以 0(零)也会生成 Infinity:
var x = 2 / 0; // x 将是 Infinity
var y = -2 / 0; // y 将是 -Infinity
类型是 number
typeof Infinity; // 返回 "number"
十六进制
JavaScript 会把前缀为 0x 的数值常量解释为十六进制。
var x = 0xFF; // x 将是 255。
绝不要用前导零写数字(比如 07)。
一些 JavaScript 版本会把带有前导零的数解释为八进制。
默认地,Javascript 把数显示为十进制小数。
但是您能够使用 toString() 方法把数输出为十六进制、八进制或二进制。
var myNumber = 128;
myNumber.toString(16); // 返回 80
myNumber.toString(8); // 返回 200
myNumber.toString(2); // 返回 10000000
JavaScript 数字方法
toString() 方法
toString() 以字符串返回数值。
var x = 123;
x.toString(); // 从变量 x 返回 123
(123).toString(); // 从文本 123 返回 123
(100 + 23).toString(); // 从表达式 100 + 23 返回 123
toFixed() 方法
toFixed() 返回字符串值,它包含了指定位数小数的数字:
var x = 9.656;
x.toFixed(0); // 返回 10
x.toFixed(2); // 返回 9.66
x.toFixed(4); // 返回 9.6560
x.toFixed(6); // 返回 9.656000
toFixed(2) 非常适合处理金钱。(也不一定,四舍五入不严谨。)
toPrecision() 方法
toPrecision() 返回字符串值,它包含了指定长度的数字:(包含了小数点前面)
var x = 9.656;
x.toPrecision(); // 返回 9.656
x.toPrecision(2); // 返回 9.7
x.toPrecision(4); // 返回 9.656
x.toPrecision(6); // 返回 9.65600
valueOf() 方法
valueOf() 以数值返回数值:
var x = 123;
x.valueOf(); // 从变量 x 返回 123
(123).valueOf(); // 从文本 123 返回 123
(100 + 23).valueOf(); // 从表达式 100 + 23 返回 123
在 JavaScript 中,数字可以是原始值(typeof = number)或对象(typeof = object)。
在 JavaScript 内部使用 `valueOf()` 方法可将 Number 对象转换为原始值。
没有理由在代码中使用它。
所有 JavaScript 数据类型都有 `valueOf()` 和 `toString()` 方法。
把变量转换为数值
这三种 JavaScript 方法可用于将变量转换为数字:
| 方法 | 描述 |
|---|---|
| Number() | 返回数字,由其参数转换而来。 |
| parseFloat() | 解析其参数并返回浮点数。 |
| parseInt() | 解析其参数并返回整数。 |
这些方法并非数字方法,而是全局 JavaScript 方法。
Number() 方法
如果无法转换数字,则返回 NaN。
x = true;
Number(x); // 返回 1
x = false;
Number(x); // 返回 0
x = new Date();
Number(x); // 返回 1404568027739
x = "10"
Number(x); // 返回 10
x = "10 20"
Number(x); // 返回 NaN
Number(Date()),是直接把时间转成了时间戳。非常方便
parseInt() 方法
parseInt() 解析一段字符串并返回数值。允许空格。只返回首个数字:
如果无法转换为数值,则返回 NaN (Not a Number)。
parseInt("10"); // 返回 10
parseInt("10.33"); // 返回 10
parseInt("10 20 30"); // 返回 10
parseInt("10 years"); // 返回 10
parseInt("years 10"); // 返回 NaN
parseFloat() 方法
parseFloat() 解析一段字符串并返回数值。允许空格。只返回首个数字:
如果无法转换为数值,则返回 NaN (Not a Number)。
parseFloat("10"); // 返回 10
parseFloat("10.33"); // 返回 10.33
parseFloat("10 20 30"); // 返回 10
parseFloat("10 years"); // 返回 10
parseFloat("years 10"); // 返回 NaN
数值属性
| 属性 | 描述 |
|---|---|
| MAX_VALUE | 返回 JavaScript 中可能的最大数。 |
| MIN_VALUE | 返回 JavaScript 中可能的最小数。 |
| NEGATIVE_INFINITY | 表示负的无穷大(溢出返回)。 |
| NaN | 表示非数字值("Not-a-Number")。 |
| POSITIVE_INFINITY | 表示无穷大(溢出返回)。 |
JavaScript 数组
创建数组,获取数组内元素数量,对数组进行排序
var cars = ["Saab", "Volvo", "BMW"];
//不推荐这种创建方式,效率较差
var cars = new Array("Saab", "Volvo", "BMW");
cars.length;//获取数组内的数据数量
cars.sort();//对数组进行排序
遍历数组元素
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>";
}
也可以使用 Array.foreach() 函数:
var fruits, text;
fruits = ["Banana", "Orange", "Apple", "Mango"];
text = "<ul>";
fruits.forEach(myFunction);
text += "</ul>";
function myFunction(value) {
text += "<li>" + value + "</li>";
}
添加数组元素
向数组添加新元素的最佳方法是使用 push() 方法:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Lemon");
也可以使用 length 属性向数组添加新元素:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[fruits.length] = "Lemon";
如果超范围添加元素,下面的例子会输出。 Banana Orange Apple Mango undefined undefined Lemon
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[6] = "Lemon";// 向 fruits 添加一个新元素 (Lemon)
还可以这样,
var person = [];
person[0] = "Bill";
person[1] = "Gates";
person[2] = 62;
var x = person.length; // person.length 返回 3
var y = person[0]; // person[0] 返回 "Bill"
在iOS,Flutter,安卓中,数组越界是会指针异常的。这样看来JS这个特性还是有一定优点的。
判断某个对象是不是数组
ECMAScript 5 定义了新方法 Array.isArray():
Array.isArray(fruits); // 返回 true
此方案的问题在于 ECMAScript 5 不支持老的浏览器。
function isArray(x) {
return x.constructor.toString().indexOf("Array") > -1;
}
还可以这样判断
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits instanceof Array // 返回 true
JavaScript 数组方法
toString()
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.toString(); // Banana,Orange,Apple,Mango
join()
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.join(" * ");//Banana * Orange * Apple * Mango
pop()&push()
删除添加数据
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var x = fruits.pop(); //数组中删除了 Mango x = Mango
var y = fruits.push("Mango");//又把他添加进去了 y = Mango
可以这样添加元素
var fruits = ["Banana", "Orange", "Apple", "Mango"];
//向 fruits 添加新元素 "Lemon"
fruits.unshift("Lemon"); //结果 Lemon,Banana,Orange,Apple,Mango
也可以这样删除元素:shift
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.shift();
shift 删除后 [Orange,Apple,Mango]
也可以这样删除:delete
var fruits = ["Banana", "Orange", "Apple", "Mango"];
delete fruits[0];
*** 使用 delete 会在数组留下未定义的空洞。请使用 pop() 或 shift() 取而代之。
拼接数组 splice()
var fruits1 = ["Banana", "Orange", "Apple", "Mango"];
fruits1.splice(2, 0, "Lemon", "Kiwi");
第一个参数(2)定义了应添加新元素的位置(拼接)。
第二个参数(0)定义应删除多少元素。
其余参数(“Lemon”,“Kiwi”)定义要添加的新元素。
splice() 方法返回一个包含已删除项的数组:
使用 splice() 来删除元素
通过聪明的参数设定,您能够使用 splice() 在数组中不留“空洞”的情况下移除元素:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(0, 1);
合并(连接)数组 concat()
concat() 方法通过合并(连接)现有数组来创建一个新数组:
var myGirls = ["Cecilie", "Lone"];
var myBoys = ["Emil", "Tobias", "Linus"];
var myChildren = myGirls.concat(myBoys); // 连接 myGirls 和 myBoys
concat() 方法不会更改现有数组。它总是返回一个新数组。
concat() 方法可以使用任意数量的数组参数:
var arr1 = ["Cecilie", "Lone"];
var arr2 = ["Emil", "Tobias", "Linus"];
var arr3 = ["Robin", "Morgan"];
var myChildren = arr1.concat(arr2, arr3); // 将arr1、arr2 与 arr3 连接在一起
类似于 Sting中的使用。
裁剪数组
slice() 方法用数组的某个片段切出新数组。
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1); //[Orange,Lemon,Apple,Mango]
slice() 可接受两个参数,比如 (1, 3)。
该方法会从开始参数选取元素,直到结束参数(不包括)为止。
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1, 3); //["Orange", "Lemon"]
如果结束参数被省略,比如第一个例子,则 slice() 会切出数组的剩余部分。
数组排序
sort()
反转数组
reverse()
数字排序
升序。
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b});
降序
ar points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return b - a});
查找最高(或最低)的数组值
先升序排序,再去数组的首和尾就是最大最小。 获取通过
Math.max.apply(null, points)
Math.min.apply(null, points)
排序对象数组 根据对象某个属性进行排序。
var cars = [
{type:"Volvo", year:2016},
{type:"Saab", year:2001},
{type:"BMW", year:2010}];
cars.sort(function(a, b){return a.year - b.year});
比较字符串属性会稍复杂: 这里是转换了大小写。
cars.sort(function(a, b){
var x = a.type.toLowerCase();
var y = b.type.toLowerCase();
if (x < y) {return -1;}
if (x > y) {return 1;}
return 0;
});
Array.forEach()
forEach() 方法为每个数组元素调用一次函数(回调函数)。
var txt = "";
var numbers = [45, 4, 9, 16, 25];
numbers.forEach(myFunction);
function myFunction(value, index, array) {
txt = txt + value + "<br>";
}
注释:该函数接受 3 个参数:
- 项目值
- 项目索引
- 数组本身
上面的例子只用了 value 参数。这个例子可以重新写为:
var txt = "";
var numbers = [45, 4, 9, 16, 25];
numbers.forEach(myFunction);
function myFunction(value) {
txt = txt + value + "<br>";
}
所有浏览器都支持 Array.forEach(),除了 Internet Explorer 8 或更早的版本:
Array.map()
map() 方法通过对每个数组元素执行函数来创建新数组。
map() 方法不会对没有值的数组元素执行函数。
map() 方法不会更改原始数组。
这个例子将每个数组值乘以2:
var numbers1 = [45, 4, 9, 16, 25];
//numbers2:[90,8,18,32,50]
var numbers2 = numbers1.map(function (value){
return value * 2;
})
所有浏览器都支持 Array.map(),除了 Internet Explorer 8 或更早的版本:
Array.filter()
filter() 方法创建一个包含通过测试的数组元素的新数组。
var numbers1 = [45, 4, 9, 16, 25];
//numbers3:[4,9,16,25]
var numbers3 = numbers1.filter(function (value){
return value < 30
})
所有浏览器都支持 Array.filter(),除了 Internet Explorer 8 或更早的版本:
Array.reduce()
reduce() 方法在每个数组元素上运行函数,以生成(减少它)单个值。
reduce() 方法在数组中从左到右工作。另请参阅 reduceRight()。
reduce() 方法不会减少原始数组。
这个例子确定数组中所有数字的总和:
var numbers1 = [1, 2, 3, 4, 5];
//redNum:15
var redNum = numbers1.reduce(function (previousValue, currentValue){
return previousValue + currentValue;
})
reduce() 方法能够接受一个初始值:
var numbers1 = [1, 2, 3, 4, 5];
//redNum:115
var redNum = numbers1.reduce(
function (previousValue, currentValue){
return previousValue + currentValue;
},
100)
Array.reduceRight()
使用方法和和reduce()一致,不同的是计算方向。
- reduce():从左向右
- Array.reduceRight():从右向左
所有浏览器都支持 Array.reduce() & Array.reduceRight(),除了 Internet Explorer 8 或更早的版本:
Array.every()
every() 方法检查所有数组值是否通过测试。
var numbers = [45, 4, 9, 16, 25];
var allOver18 = numbers.every(myFunction);//false
function myFunction(value, index, array) {
return value > 18;
}
或者去掉不需要的参数
var numbers = [45, 4, 9, 16, 25];
var allOver18 = numbers.every(myFunction);
function myFunction(value) {
return value > 18;
}
所有浏览器都支持 Array.every(),除了 Internet Explorer 8 或更早的版本:
Array.some()
some() 方法检查某些数组值是否通过了测试。
var numbers = [45, 4, 9, 16, 25];
var someOver18 = numbers.some(myFunction);//true
function myFunction(value, index, array) {
return value > 18;
}
或者去掉不需要的参数
var numbers = [45, 4, 9, 16, 25];
var someOver18 = numbers.some(myFunction);//true
function myFunction(value) {
return value > 18;
}
所有浏览器都支持 Array.some(),除了 Internet Explorer 8 或更早的版本:
Array.indexOf()
indexOf() 方法在数组中搜索元素值并返回其位置。
注释:第一个项目的位置是 0,第二个项目的位置是 1,以此类推。
var fruits = ["Apple", "Orange", "Apple", "Mango"];
var a = fruits.indexOf("Orange");//1
array.indexOf(item, start)
| item | 必需。要检索的项目。 |
|---|---|
| start | 可选。从哪里开始搜索。负值将从结尾开始的给定位置开始,并搜索到结尾。 |
如果item多次出现,则返回第一次出现的位置。
Array.lastIndexOf()
使用方法和indexOf()一样,不同的点是搜索方向。
- indexOf():从左向右
- lastIndexOf():从右向左
所有浏览器都支持 Array.indexOf() & lastIndexOf(),除了 Internet Explorer 8 或更早的版本:
Array.find()
find() 方法返回通过测试函数的第一个数组元素的值。
这个例子查找(返回)大于 18 的第一个元素的值:
var numbers = [4, 9, 16, 25, 29];
var first = numbers.find(myFunction);//25
function myFunction(value, index, array) {
return value > 18;
}
老旧的浏览器不支持 Array.find()。下面列出了完全支持此方法的首个浏览器版本:
| Chrome | IEdge | Firefox | Safari | Opera |
|---|---|---|---|---|
| 45 | 12 | 25 | 8 | 32 |
Array.findIndex()
findIndex() 方法返回通过测试函数的第一个数组元素的索引。
这个例子查找大于 18 的第一个元素的索引:
var numbers = [4, 9, 16, 25, 29];
var first = numbers.findIndex(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
老旧的浏览器不支持 Array.findIndex()。下面列出了完全支持此方法的首个浏览器版本:
| Chrome | IEdge | Firefox | Safari | Opera |
|---|---|---|---|---|
| 45 | 12 | 25 | 8 | 32 |
数组 Const
数组不是常量
关键字 const 有一定误导性。
*它不定义常量数组。它定义的是对数组的常量引用。*
因此,我们仍然可以更改常量数组的元素。
元素可以重新赋值
// 您可以创建常量数组:
const cars = ["Saab", "Volvo", "BMW"];
// 您可以更改元素:
cars[0] = "Toyota";
// 您可以添加元素:
cars.push("Audi");
必须在声明时赋值,下面这种声明方式是不可行的。
const cars;
cars = ["Saab", "Volvo", "BMW"];
const 块作用域
用 const 声明的数组具有块作用域。,类似于let
const cars = ["Saab", "Volvo", "BMW"];
// 此处 cars[0] 为 "Saab"
{
const cars = ["Toyota", "Volvo", "BMW"];
// 此处 cars[0] 为 "Toyota"
}
// 此处 cars[0] 为 "Saab"
重新声明数组
不允许在同一作用域或同一块中将数组重新声明或重新赋值给 const:
var cars = ["Volvo", "BMW"]; // 允许
const cars = ["Volvo", "BMW"]; // 不允许
{
var cars = ["Volvo", "BMW"]; // 允许
const cars = ["Volvo", "BMW"]; // 不允许
}
不允许在同一作用域或同一块中重新声明或重新赋值现有的 const 数组:
const cars = ["Volvo", "BMW"]; // 允许
const cars = ["Volvo", "BMW"]; // 不允许
var cars = ["Volvo", "BMW"]; // 不允许
cars = ["Volvo", "BMW"]; // 不允许
{
const cars = ["Volvo", "BMW"]; // 允许
const cars = ["Volvo", "BMW"]; // 不允许
var cars = ["Volvo", "BMW"]; // 不允许
cars = ["Volvo", "BMW"]; // 不允许
}
允许在另一个作用域或另一个块中使用 const 重新声明数组:
const cars = ["Volvo", "BMW"]; // 允许
{
const cars = ["Volvo", "BMW"]; // 允许
}
{
const cars = ["Volvo", "BMW"]; // 允许
}
浏览器支持
Internet Explorer 10 或更早的版本不支持 const 关键字。
| Chrome | IE | Firefox | Safari | Opera |
|---|---|---|---|---|
| Chrome 49 | IE 11 / Edge | Firefox 36 | Safari 10 | Opera 36 |
| 2016 年 3 月 | 2013 年 10 月 | 2015 年 2 月 | 2016 年 9 月 | 2016 年 3 月 |