//变量
let i ="xxxx"
i =1
i =2
//函数
xxx =function (a,b) {
// if (typeof a == "string" && typeof b == "string") {
return a + b
// }
}
function aaa(a,b) {
if (typeof a =="number" &&typeof b =="number") {
return a + b
}
if (typeof a =="string" &&typeof b =="string") {
return a
}
}
alert(xxx(22,222))
alert(aaa("xxx","222"))
//常量
const height =222
const HEIGHT_LEFT =223
alert(height)
alert(HEIGHT_LEFT)
//数据类型
// 弱类型
let message ="11111"
message =123
alert(message)
//Number 类型,代表整数和浮点数
// Infinity -Infinity 无穷大 NAN计算错误
alert(1/0)
alert(Infinity)
// NAN 会传递, 会被传播到结果 例外 NAN ** 0 1
let bigInt =1212121121212122221212n
//String 类型
let str ="hello"
let str2 ='xxxx'
let phrase =`xxx${str}`
alert(phrase)
// number 用于任何类型的数字:整数或浮点数,在 ±(253-1) 范围内的整数。
// bigint 用于任意长度的整数。
// string 用于字符串:一个字符串可以包含 0 个或多个字符,所以没有单独的单字符类型。
// boolean 用于 true 和 false。
// null 用于未知的值 —— 只有一个 null 值的独立类型。
// undefined 用于未定义的值 —— 只有一个 undefined 值的独立类型。
// symbol 用于唯一的标识符。
// object 用于更复杂的数据结构。
// 我们可以通过 typeof 运算符查看存储在变量中的数据类型。
//
// 通常用作 typeof x,但 typeof(x) 也可行。
// 以字符串的形式返回类型名称,例如 "string"。
// typeof null 会返回 "object" —— 这是 JavaScript 编程语言的一个错误,实际上它并不是一个 object。
//交互
// 与用户交互的 3 个浏览器的特定函数:
//
// alert
// 显示信息。
// prompt
// 显示信息要求用户输入文本。点击确定返回文本,点击取消或按下 Esc 键返回 null。
// confirm
// 显示信息等待用户点击确定或取消。点击确定返回 true,点击取消或按下 Esc 键返回 false。
// 这些方法都是模态的:它们暂停脚本的执行,并且不允许用户与该页面的其余部分进行交互,直到窗口被解除。
//
// 上述所有方法共有两个限制:
//
// 模态窗口的确切位置由浏览器决定。通常在页面中心。
// 窗口的确切外观也取决于浏览器。我们不能修改它。
// 这就是简单的代价。还有其他一些方法可以显示更漂亮的窗口,并与用户进行更丰富的交互,但如果“花里胡哨”不是非常重要,那使用本节讲的这些方法也挺好。
//类型转换
// 字符串转换
let value =true
alert(value)
alert(typeof value)
value =toString(value)
alert(value)
alert(typeof value)
//数字类型转换
alert("6" /"2")//string 类型的值被自动转换成 number 类型后进行计算 在算术函数和表达式中,会自动进行 number 类型转换。
let numStr ="100"
numStr =Number(numStr)
alert(typeof numStr)
numStr ="hjashjashj"
numStr =Number(numStr)
alert(typeof numStr)// 输出NAN
// Number 类型转换规则:
// 值 变成……
// undefined NaN
// null 0
// true 和 false 1 and 0
// string 去掉首尾空格后的纯数字字符串中含有的数字。如果剩余字符串为空,则转换结果为 0。否则,将会从剩余字符串中“读取”数字。当类型转换出现 error 时返回 NaN。
// 请注意 null 和 undefined 在这有点不同:null 变成数字 0,undefined 变成 NaN。
alert(Boolean("1"))
alert(Boolean(0))
alert(Boolean("hah"))// true
alert(Boolean(""))//false
// 请注意:包含 0 的字符串 "0" 是 true
// 一些编程语言(比如 PHP)视 "0" 为 false。但在 JavaScript 中,非空的字符串总是 true。
// 总结
// 有三种常用的类型转换:转换为 string 类型、转换为 number 类型和转换为 boolean 类型。
//
// 字符串转换 —— 转换发生在输出内容的时候,也可以通过 String(value) 进行显式转换。原始类型值的 string 类型转换通常是很明显的。
//
// 数字型转换 —— 转换发生在进行算术操作时,也可以通过 Number(value) 进行显式转换。
//
// 数字型转换遵循以下规则:
//
// 值 变成……
// undefined NaN
// null 0
// true / false 1 / 0
// string “按原样读取”字符串,两端的空白会被忽略。空字符串变成 0。转换出错则输出 NaN。
// 布尔型转换 —— 转换发生在进行逻辑操作时,也可以通过 Boolean(value) 进行显式转换。
//
// 布尔型转换遵循以下规则:
//
// 值 变成……
// 0, null, undefined, NaN, "" false
// 其他值 true
// 上述的大多数规则都容易理解和记忆。人们通常会犯错误的值得注意的例子有以下几个:
//
// 对 undefined 进行数字型转换时,输出结果为 NaN,而非 0。
// 对 "0" 和只有空格的字符串(比如:" ")进行布尔型转换时,输出结果为 true。
//数学运算符
// 支持以下数学运算:
// 加法 +,
alert(3 +2)// 5
// 减法 -,
alert(3 -2)// 1
// 乘法 *,
alert(1 *2)// 2
// 除法 /,
alert(4 /2)// 2
// 取余 %,
alert(5 %2)// 1
// 求幂 **.
alert(2 **2)// 2² = 4
alert(2 **3)// 2³ = 8
alert(2 **4)// 2⁴ = 16
alert(4 ** (1/2) ); // 2(1/2 次方与平方根相同)
alert(8 ** (1/3) ); // 2(1/3 次方与立方根相同)
// 用二元运算符 + 连接字符串
let strMath ="hah" +"hhh" // "hahhhh"
alert(strMath)
alert(2 +2 +'1')// 41
alert('1' +2 +2)// 122
alert(6 -'2')// 4
alert('6' /'2')// 4
// 数字转化,一元运算符 +
// 加号 + 有两种形式。一种是上面我们刚刚讨论的二元运算符,还有一种是一元运算符。
// 一元运算符加号,或者说,加号 + 应用于单个值,对数字没有任何作用。但是如果运算元不是数字,加号 + 则会将其转化为数字。
let mathX =1
alert(+mathX)// 1
let mathY = -1
alert(mathY)// -1
// 转化非数字
alert(+true)// 1
alert(+"")// 0
// 它的效果和 Number(...) 相同,但是更加简短。
let mathApples ="2"
let mathOranges ="3"
alert(mathApples +mathOranges)// 23
alert(+mathApples + +mathOranges)// 5
// 运算符优先级
// 如果一个表达式拥有超过一个运算符,执行的顺序则由 优先级 决定。换句话说,所有的运算符中都隐含着优先级顺序。
// 从小学开始,我们就知道在表达式 1 + 2 * 2 中,乘法先于加法计算。这就是一个优先级问题。乘法比加法拥有 更高的优先级。
// 圆括号拥有最高优先级,所以如果我们对现有的运算顺序不满意,我们可以使用圆括号来修改运算顺序,就像这样:(1 + 2) * 2。
// 在 JavaScript 中有众多运算符。每个运算符都有对应的优先级数字。数字越大,越先执行。如果优先级相同,则按照由左至右的顺序执行。
// 这是一个摘抄自 Mozilla 的 优先级表(你没有必要把这全记住,但要记住一元运算符优先级高于二元运算符):
// 优先级 名称 符号
// … … …
// 15 一元加号 +
// 15 一元负号 -
// 14 求幂 **
// 13 乘号 *
// 13 除号 /
// 12 加号 +
// 12 减号 -
// … … …
// 2 赋值符 =
// … … …
// 我们可以看到,“一元加号运算符”的优先级是 15,高于“二元加号运算符”的优先级 12。这也是为什么表达式 "+apples + +oranges" 中的一元加号先生效,然后才是二元加法。
// 赋值运算符
// let a = 1;
// let b = 2;
// let c = 3 - (a = b + 1);// 不过,请不要写这样的代码。这样的技巧绝对不会使代码变得更清晰或可读。
// alert( a ); // 3
// alert( c ); // 0
// 原地修改
// let n = 2;
// n = n + 5;
// n = n * 2;
// let n = 2;
// n += 5; // 现在 n = 7(等同于 n = n + 5)
// n *= 2; // 现在 n = 14(等同于 n = n * 2)
// alert( n ); // 14
// 所有算术和位运算符都有简短的“修改并赋值”运算符:/= 和 -= 等。
// 这类运算符的优先级与普通赋值运算符的优先级相同,所以它们在大多数其他运算之后执行:
// let n = 2;
// n *= 3 + 5;
// alert( n ); // 16 (右边部分先被计算,等同于 n *= 8)
// 自增/自减
// let counter = 2;
// counter++; // 和 counter = counter + 1 效果一样,但是更简洁
// alert( counter ); // 3
// let counter = 2;
// counter--; // 和 counter = counter - 1 效果一样,但是更简洁
// alert( counter ); // 1
// 自增/自减只能应用于变量。试一下,将其应用于数值(比如 5++)则会报错。
// 运算符 ++ 和 -- 可以置于变量前,也可以置于变量后。
// 当运算符置于变量后,被称为“后置形式”:counter++。
// 当运算符置于变量前,被称为“前置形式”:++counter。
// 两者都做同一件事:将变量 counter 与 1 相加。
// 那么它们有区别吗?有,但只有当我们使用 ++/-- 的返回值时才能看到区别。
// 详细点说。我们知道,所有的运算符都有返回值。自增/自减也不例外。前置形式返回一个新的值,但后置返回原来的值(做加法/减法之前的值)。
// 为了直观看到区别,看下面的例子:
// let counter = 1;
// let a = ++counter; // (*)
// alert(a); // 2
// (*) 所在的行是前置形式 ++counter,对 counter 做自增运算,返回的是新的值 2。因此 alert 显示的是 2。
// 下面让我们看看后置形式:
// let counter = 1;
// let a = counter++; // (*) 将 ++counter 改为 counter++
// alert(a); // 1
// (*) 所在的行是后置形式 counter++,它同样对 counter 做加法,但是返回的是 旧值(做加法之前的值)。因此 alert 显示的是 1。
// 总结:
// 如果自增/自减的值不会被使用,那么两者形式没有区别:
// let counter = 0;
// counter++;
// ++counter;
// alert( counter ); // 2,以上两行作用相同
// 如果我们想要对变量进行自增操作,并且 需要立刻使用自增后的值,那么我们需要使用前置形式:
// let counter = 0;
// alert( ++counter ); // 1
// 如果我们想要将一个数加一,但是我们想使用其自增之前的值,那么我们需要使用后置形式:
// let counter = 0;
// alert( counter++ ); // 0
// 自增/自减和其它运算符的对比
// ++/-- 运算符同样可以在表达式内部使用。它们的优先级比绝大部分的算数运算符要高。
// 举个例子:
// let counter = 1;
// alert( 2 * ++counter ); // 4
// 与下方例子对比:
// let counter = 1;
// alert( 2 * counter++ ); // 2,因为 counter++ 返回的是“旧值”
// 尽管从技术层面上来说可行,但是这样的写法会降低代码的可阅读性。在一行上做多个操作 —— 这样并不好。
// 当阅读代码时,快速的视觉“纵向”扫描会很容易漏掉 counter++,这样的自增操作并不明显。
// 我们建议用“一行一个行为”的模式:
// let counter = 1;
// alert( 2 * counter );
// counter++;
// 位运算符
// 位运算符把运算元当做 32 位整数,并在它们的二进制表现形式上操作。
// 这些运算符不是 JavaScript 特有的。大部分的编程语言都支持这些运算符。
// 下面是位运算符:
// 按位与 ( & )
// 按位或 ( | )
// 按位异或 ( ^ )
// 按位非 ( ~ )
// 左移 ( << )
// 右移 ( >> )
// 无符号右移 ( >>> )
// 这些运算符很少被使用,一般是我们需要在最低级别(位)上操作数字时才使用。我们不会很快用到这些运算符,例如密码学,它们很有用。当你需要了解它们的时候,可以阅读 MDN 上的 位操作符 章节。
// 逗号运算符
// 逗号运算符 , 是最少见最不常使用的运算符之一。有时候它会被用来写更简短的代码,因此为了能够理解代码,我们需要了解它。
// 逗号运算符能让我们处理多个语句,使用 , 将它们分开。每个语句都运行了,但是只有最后的语句的结果会被返回。
// 举个例子:
// let a = (1 + 2, 3 + 4);
// alert( a ); // 7(3 + 4 的结果)
// 这里,第一个语句 1 + 2 运行了,但是它的结果被丢弃了。随后计算 3 + 4,并且该计算结果被返回。
// 逗号运算符的优先级非常低
// 请注意逗号运算符的优先级非常低,比 = 还要低,因此上面你的例子中圆括号非常重要。
// 如果没有圆括号:a = 1 + 2, 3 + 4 会先执行 +,将数值相加得到 a = 3, 7,然后赋值运算符 = 执行 a = 3,然后逗号之后的数值 7 不会再执行,它被忽略掉了。相当于 (a = 1 + 2), 3 + 4。
// 为什么我们需要这样一个运算符,它只返回最后一个值呢?
// 有时候,人们会使用它把几个行为放在一行上来进行复杂的运算。
// 举个例子:
// // 一行上有三个运算符
// for (a = 1, b = 3, c = a * b; a < 10; a++) {
// ...
// }
// 这样的技巧在许多 JavaScript 框架中都有使用,这也是为什么我们提到它。但是通常它并不能提升代码的可读性,使用它之前,我们要想清楚。
// 1 10 1 2 6 9px $45 2 nan -95 -14 1 nan -2
// 有字符串的加法 "" + 1,首先会将数字 1 转换为一个字符串:"" + 1 = "1",然后我们得到 "1" + 0,再次应用同样的规则得到最终的结果。
// 减法 -(像大多数数学运算一样)只能用于数字,它会使空字符串 "" 转换为 0。
// 带字符串的加法会将数字 5 加到字符串之后。
// 减法始终将字符串转换为数字,因此它会使 " -9 " 转换为数字 -9(忽略了字符串首尾的空格)。
// null 经过数字转换之后会变为 0。
// undefined 经过数字转换之后会变为 NaN。
// 字符串转换为数字时,会忽略字符串的首尾处的空格字符。在这里,整个字符串由空格字符组成,包括 \t、\n 以及它们之间的“常规”空格。因此,类似于空字符串,所以会变为 0。
// let a = prompt("First number?", 1);//它的运行结果不正确。下面例子中的输出是 12(对于默认的 prompt 的值)。
// let b = prompt("Second number?", 2);// 为什么会这样?修正它。结果应该是 3。
// alert(+a + +b); // 3
网友评论