引言
如果我们没有变量,我们就不得不写大量的代码去枚举和检查输入的名字,然后去显示它们,这样做显然是低效率和不可行的 。
一个变量,就是一个用于存放数值的容器。
变量不是数值本身,它们仅仅是一个用于存储数值的容器。你可以把变量想象成一个个用来装东西的纸箱子。
I 变量的声明
变量
是存储值的容器,在 JavaScript 中声明一个新变量的方法是使用关键字let
、const
和 var
,let 和 const 关键字允许你创建块作用域的变量。JavaScript 中可以定义重名变量,如果后面定义的变量没有初始化则会按照前面定义的输出 。
如果声明了一个变量却没有对其赋值,那么这个变量的类型就是 undefined。
1.1 let
代码语言:javascript复制//let 语句声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
let a;
let name = 'Simon';
let x,y,z=3;//只有最后一个变量z 被赋值了3
//给多个变量赋值
//Longhand
let a, b, c;
a = 5;
b = 8;
c = 12;
//Shorthand 简写
let [a, b, c] = [5, 8, 12];
// myLetVariable 在这里 *不能* 被引用
for (let myLetVariable = 0; myLetVariable < 5; myLetVariable ) {
// myLetVariable 只能在这里引用
}
// myLetVariable 在这里 *不能* 被引用
1.2 const
const 声明一个不可变的常量,这个常量在定义域内总是可见的。
代码语言:javascript复制const Pi = 3.14; // 设置 Pi 的值
1.3 var
var 变量名称
使用 var 声明的变量在它所声明的整个函数都是可见的。
var a;
var name = "simon";
// myVarVariable 在这里 *能* 被引用
for (var myVarVariable = 0; myVarVariable < 5; myVarVariable ) {
// myVarVariable 整个函数中都能被引用
}
// myVarVariable 在这里 *能* 被引用
//JavaScript 与其他语言的(如 Java)的重要区别是在 JavaScript 中语句块(blocks)是没有作用域的,只有函数有作用域。因此如果在一个复合语句中(如 if 控制结构中)使用 var 声明一个变量,那么它的作用域是整个函数(复合语句在函数中)。
//但是从 ECMAScript Edition 6 开始将有所不同的, let 和 const 关键字允许你创建块作用域的变量。
II 变量类型
可以为变量设置不同的数据类型,JavaScript 是一种“动态类型语言”, 这意味着不需要指定变量将包含什么数据类型,如果你声明一个变量并给它一个带引号的值,浏览器就会知道它是一个字符串:
代码语言:javascript复制let myString = 'Hello';
2.1 数据基本类型
- number (数字类型), 采用“遵循 IEEE 754 标准的双精度 64 位格式
("double-precision 64-bit format IEEE 754 values")
表示数字。在 JavaScript(除了BigInt)当中,并不存在整数/整型 (Integer)。可以使用内置函数parseInt()
将字符串转换为整型,该函数的第二个可选参数表示字符串所表示数字的基(进制):
parseInt("123", 10); // 123
parseInt("010", 10); // 10
parseInt("11", 2); // 3,把一个二进制数字字符串转换成整数值
//parseFloat() 只应用于解析十进制数字
//一元运算符 也可以把数字字符串转换成数值:
"42"; // 42
"010"; // 10
"0x10"; // 16
//parseInt() 和 parseFloat() 函数会尝试逐个解析字符串中的字符,直到遇上一个无法被解析成数字的字符,然后返回该字符前所有数字字符组成的数字。
//但是运算符 " "对字符串的转换方式与之不同, 只要字符串含有无法被解析成数字的字符,该字符串就将被转换成 NaN。
- boolean 布尔类型 ,分别是 true 和 false(两者都是关键字)。
//将变量转换成布尔类型
//1. false、0、空字符串("")、NaN、null 和 undefined 被转换为 false
//2. 除了以上情况,其他值被转换为 true。
//可以使用 Boolean() 函数进行显式转换:
Boolean(''); // false
Boolean(234); // true
//JavaScript 会在需要一个布尔变量时隐式完成这个转换操作,比如在 if 条件语句中。
- symbol (符号)(ES2015 新增)
ES2015 新增 从 Symbol() 返回的 symbol 值都是唯一的,能作为对象属性的标识符; https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol
2.2 Object (对象类型)
- Function (函数),特殊的对象,函数也可以被保存在变量中,并且像其他对象一样被传递。
- Array ( 数组)类型
- Date (日期)
var d = new Date();
//1) 获得当前年份 d.getYear()
//2) 获得年份的全称 d.getFullYear()
//3) 获得月份 d.getMonth()
//4) 获得日期 d.getDate()
//5) 获得星期 d.getDay()
//6) 获得时间 d.getHours()
//7) 获得分钟 d.getMinutes()
//8) 获得秒钟 d.getSeconds()
- Math 内置对象 Math(数学对象),用以处理更多的高级数学函数和常数。
Math.sin(3.5);
var circumference = 2 * Math.PI * r;
//1) ceil() 向上取整
//2) floor() 向下取整
//3) round() 四舍五入
- RegExp(正则表达式),特殊的对象。
- string (字符串类型),JavaScript 中的字符串是一串Unicode 字符序列。它们是一串 UTF-16 编码单元的序列,每一个编码单元由一个 16 位二进制数表示。每一个 Unicode 字符由一个或两个编码单元来表示。
var str = new String("abc");
//通过访问字符串的 length(编码单元的个数)属性,可以得到它的长度。
"hello".length; // 5
//字符串也有 methods(方法)能让你操作字符串和获取字符串的信息。
"hello".charAt(0); // "h" charAt(下标)
"hello, world".replace("world", "mars"); // "hello, mars"
"hello".toUpperCase(); // "HELLO"
// indexOf()
// substring()
// concat()
// split()
2.3 特殊类型
- undefined (未定义)类型, 一个未被赋值的变量就是 undefined 类型,
undefined
实际上是一个不允许修改的常量。 - null ( non-value)空类型 , 只有显示声明null才能使用
- NaN : (Not a Number 的缩写),如果给定的字符串不存在数值形式,函数会返回一个特殊的值 NaN。
parseInt("hello", 10); // NaN
"test"/123
//把 NaN 作为参数进行任何数学运算,结果也会是 NaN:
NaN 5; //NaN
//使用内置函数 isNaN() 来判断一个变量是否为 NaN:
isNaN(NaN); // true
- 内置的 Error(错误)类型
特殊值:Infinity
(正无穷)和 -Infinity
(负无穷)
//使用内置函数 isFinite() 来判断一个变量是否是一个有穷数, 如果类型为Infinity, -Infinity 或 NaN 则返回 false:
isFinite(1/0); // false
isFinite(Infinity); // false
isFinite(-Infinity); // false
isFinite(NaN); // false
isFinite(0); // true
III 详解对象类型
JavaScript 中的一切(除了核心类型,core object)都是对象,JavaScript 中的对象,可以简单理解成“名称 - 值”对(而不是键值对)。“名称”部分是一个 JavaScript 字符串,“值”部分可以是任何 JavaScript 的数据类型——包括对象。
3.1 Function
函数
用来封装可复用的功能,函数通常包括参数,参数中保存着一些必要的数据。它们位于括号内部,多个参数之间用逗号分开。document.querySelector 和 alert 是浏览器内置的函数,随时可用。
let myVariable = document.querySelector('h1');
alert('hello!');
定义和声明函数
代码语言:javascript复制 function 函数名称(参数列表){
函数体
}
//一个 JavaScript 函数可以包含 0 个或多个已命名的变量。
var fun = new Function("a","b"," return a b;");//return 语句返回一个值并结束函数
//JavaScript 允许你创建匿名函数
var fun = function (a,b){
return a b;
}
// 注意:Function 类型没有重载,并且 fun 和fun(1,2)结果完全不同;
匿名函数
: 因为它没有名字,匿名函数还有另一种我们称之为箭头函数
的写法,箭头函数使用() =>
代替 function ()
:
//匿名函数
document.querySelector('html').onclick = function() {
alert('别戳我,我怕疼。');
}
//箭头函数
document.querySelector('html').addEventListener('click', () => {
alert('别戳我,我怕疼。');
});
//Longhand
function add(num1, num2) {
return num1 num2;
}
//Shorthand
const add = (num1, num2) => num1 num2;
函数体中有一个名为 arguments 的内部对象,类似于数组的对象,包括了所有被传入的参数。
代码语言:javascript复制function avg() {//可以接收任意个数的参数
var sum = 0;
for (var i = 0, j = arguments.length; i < j; i ) {
sum = arguments[i];
}
return sum / arguments.length;
}
avg(2, 3, 4, 5); // 3.5
使用剩余参数...args
来替换 arguments 的使用,function avg(firstValue, ...args)
会把传入函数的第一个值存入 firstValue,其他的参数存入 args。
function avg(...args) {//所有被传入该函数的参数都被变量 args 所持有。
var sum = 0;
for (let value of args) {//将 for 循环替换为 for...of 循环来参数args
sum = value;
}
return sum / args.length;
}
avg(2, 3, 4, 5); // 3.5
JavaScript 允许你通过任意函数对象
的 apply()
方法来传递给它一个数组作为参数列表。
代码语言:javascript复制函数也是对象
apply(thisArg, argsArray)
//1. thisArg在 func 函数运行时使用的 this 值。请注意,this 可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
//2. 一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。从 ECMAScript 5 开始可以使用类数组对象。
//传给 apply() 的第二个参数是一个数组,它将被当作 avg() 的参数列表使用
avg.apply(null, [2, 3, 4, 5]); // 3.5
const numbers = [5, 6, 2, 3, 7];
const max = Math.max.apply(null, numbers);
JavaScript 允许以递归方式调用函数,递归在处理树形结构(比如浏览器 DOM)时非常有用。
代码语言:javascript复制var charsInBody = (function countChars(elm) {
if (elm.nodeType == 3) { // 文本节点
return elm.nodeValue.length;
}
var count = 0;
for (var i = 0, child; child = elm.childNodes[i]; i ) {
count = countChars(child);
}
return count;
})(document.body);//命名立即调用的函数表达式(IIFE——Immediately Invoked Function Expression)
3.2 Object
对象
是存储在单个分组中的相关功能的集合,在编程中,对象是现实生活中的模型的一种代码结构。
创建一个空对象
代码语言:javascript复制var obj = new Object();// js方式创建一个对象
var obj = {};//对象字面量(object literal)
JSON 格式创建一个对象
代码语言:javascript复制 var oo = {
name:"hello",
age:123,
getName:function(){
return oo.name;
}
}
alert(oo.getName());
js方式创建一个对象
代码语言:javascript复制 var obj = new Object();
obj.name = "hello";//对象的属性可以通过链式(chain)表示方法访问
// 括号表示法 (bracket notation)
obj['name'] = 'Simon';
obj.for = 'Simon'; // 语法错误,因为 for 是一个预留关键字。从 ECMAScript 5 开始,预留关键字可以作为对象的属性名
obj["for"] = 'Simon'; // 工作正常
obj.age = 123;
obj.getName = function (){
return obj.name;
}
alert(obj.name);
alert(obj.getName());
3.3 Array 数组
Java中的数组,固定长度,存储同一类型数据,连续内存空间。js中的数组可变长,存储数据不固定,存储空间不一定连续。
JavaScript 中的数组是一种特殊的对象,与普通对象类似以数字为属性名,但只能通过[] 来访问
。
var arr = new Array();
arr[0] = 123;
arr[1] = "hello";
arr[5] = "aaaa";
通过数组字面量(array literal)创建数组
代码语言:javascript复制var arr2 = [1,2,3,"hello",,,"aa",];
alert(arr2.length);// IE中长度为8,火狐7
使用数组解构赋值来交换两个变量
代码语言:javascript复制//为了交换两个变量,通常使用第三个变量。
let x = 'Hello', y = 55;
//Longhand
const temp = x;
x = y;
y = temp;
//Shorthand
[x, y] = [y, x];
Array.length
并不总是等于数组中元素的个数
var a = ["dog", "cat", "hen"];
a[100] = "fox";
a.length; // 101
a.push(item);//在数组后追加元素
ES2015 引入了更加简洁的for...of
循环,可以用它来遍历可迭代对象,例如数组:
for (const currentValue of a) {
// Do something with currentValue
}
//不推荐使用 for...in 循环历数组,因为它遍历的是数组的索引。如果直接向 Array.prototype 添加了新的属性,使用这样的循环这些属性也同样会被遍历。
for (var i in a) {
// 操作 a[i]
}
ECMAScript 5 增加了另一个遍历数组的方法,forEach()
:
["dog", "cat", "hen"].forEach(function(currentValue, index, array) {
// 操作 currentValue 或者 array[index]
});
数组的属性 :length, 获得数组长度。
数组的API:
方法名称 | 描述 |
---|---|
a.toString() | 返回一个包含数组中所有元素的字符串,每个元素通过逗号分隔。 |
a.toLocaleString() | 根据宿主环境的区域设置,返回一个包含数组中所有元素的字符串,每个元素通过逗号分隔。 |
a.concat(item1[, item2[, ...[, itemN]]]) | 返回一个数组,这个数组包含原先 a 和 item1、item2、……、itemN 中的所有元素。 var arr1 = arr.concat(arr2);//将两个数组进行拼接操作,返回的是拼接好的数组 |
a.join(sep) | 返回一个包含数组中所有元素的字符串,每个元素通过指定的 sep 分隔。 arr2.join("-"); |
a.pop() | 删除并返回数组中的最后一个元素。 |
a.push(item1, ..., itemN) | 将 item1、item2、……、itemN 追加至数组 a。 |
a.reverse() | 数组逆序(会更改原数组 a)。 |
a.shift() | 删除并返回数组中第一个元素。 |
a.slice(start, end) | 返回子数组,以 a[start] 开头,以 a[end] 前一个元素结尾。 |
a.sort([cmpfn]) | 依据可选的比较函数 cmpfn 进行排序,如果未指定比较函数,则按字符顺序比较进行简单排序,默认只能排序0-9 ;如果排序数字复杂,则必须对sort方法进行修改: arr.sort(function(a,b){return a-b;}); |
a.splice(start, delcount[, item1[, ...[, itemN]]]) | 从 start 开始,删除 delcount 个元素,然后插入所有的 item。splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。 |
a.unshift(item1[, item2[, ...[, itemN]]]) | 将 item 插入数组头部,返回数组新长度 |
const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// inserts at index 1
console.log(months);
// expected output: Array ["Jan", "Feb", "March", "April", "June"]
months.splice(4, 1, 'May');
// replaces 1 element at index 4
console.log(months);
// expected output: Array ["Jan", "Feb", "March", "April", "May"]
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
see also
JavaScript小技能:运算符:https://blog.csdn.net/z929118967/article/details/126104974
iOS小技能:链式编程在iOS开发中的应用https://blog.csdn.net/z929118967/article/details/75219317