Js学习笔记

在 JavaScript 中,有三种包含字符串的方式。

  1. 双引号:"Hello".
  2. 单引号:'Hello'.
  3. 反引号:`Hello`.

双引号和单引号都是“简单”引用,在 JavaScript 中两者几乎没有什么差别。

反引号是 功能扩展 引号。它们允许我们通过将变量和表达式包装在 ${…} 中,来将它们嵌入到字符串中。例如:

let name = "John";

// 嵌入一个变量
alert( `Hello, ${name}!` ); // Hello, John!

// 嵌入一个表达式
alert( `the result is ${1 + 2}` ); // the result is 3

${…} 内的表达式会被计算,计算结果会成为字符串的一部分。可以在 ${…} 内放置任何东西:诸如名为 name 的变量,或者诸如 1 + 2 的算数表达式,或者其他一些更复杂的。

需要注意的是,这仅仅在反引号内有效,其他引号不允许这种嵌入。

  1. typeof null 的结果是 "object"。这是官方承认的 typeof 的行为上的错误,这个问题来自于 JavaScript 语言的早期,并为了兼容性而保留了下来。null 绝对不是一个 objectnull 有自己的类型,它是一个特殊值。
  2. typeof alert 的结果是 "function",因为 alert 在 JavaScript 语言中是一个函数。我们会在下一章学习函数,那时我们会了解到,在 JavaScript 语言中没有一个特别的 “function” 类型。函数隶属于 object 类型。但是 typeof 会对函数区分对待,并返回 "function"。这也是来自于 JavaScript 语言早期的问题。从技术上讲,这种行为是不正确的,但在实际编程中却非常方便。

我们也可以使用 Number(value) 显式地将这个 value 转换为 number 类型。

number 类型转换规则:

变成……
undefinedNaN
null0
true 和 false1 and 0
string去掉首尾空格后的纯数字字符串中含有的数字。如果剩余字符串为空,则转换结果为 0。否则,将会从剩余字符串中“读取”数字。当类型转换出现 error 时返回 NaN

alert( Number("   123   ") ); // 123
alert( Number("123z") );      // NaN(从字符串“读取”数字,读到 "z" 时出现错误)
alert( Number(true) );        // 1
alert( Number(false) );       // 0

请注意 null 和 undefined 在这有点不同:null 变成数字 0undefined 变成 NaN

用"+"也可以实现Number()的效果:

alert( +"   123   " ); // 123
alert( +"123z" );      // NaN(从字符串“读取”数字,读到 "z" 时出现错误)
alert( +true );        // 1
alert( +false );       // 0

明显使用“+”更简洁。

我们经常会有将字符串转化为数字的需求。比如,如果我们正在从 HTML 表单中取值,通常得到的都是字符串。如果我们想对它们求和,该怎么办?

二元运算符加号会把它们合并成字符串:

let apples = "2";
let oranges = "3";

alert( apples + oranges ); // "23",二元运算符加号合并字符串

如果我们想把它们当做数字对待,我们需要转化它们,然后再求和:

let apples = "2";
let oranges = "3";

// 在二元运算符加号起作用之前,所有的值都被转化为了数字
alert( +apples + +oranges ); // 5

// 更长的写法
// alert( Number(apples) + Number(oranges) ); // 5

一元运算符优先级高于二元运算符,这里apples和oranges前的两个加号作为一元运算符处理,优先级比中间的加号要高(中间的加号做两个数的求和,为二元运算符)。所以这里会先把两个字符串转换为数字再做加法运算。

幂运算:2 ** 4 表示2的4次方 4 ** (1/2)表示4的1/2次方即4的开方

布尔转换(可以使用Boolean(),它在做 if 判断是会发生):

  • 数字 0、空字符串 ""nullundefined 和 NaN 都会被转换成 false。因为它们被称为“假值(falsy)”值。注意任何非空字符串都会转成true,例如“0” (字符0),“ ”(字符空格)等。
  • 其他值被转换为 true,所以它们被称为“真值(truthy)”。

如果是值的比较,请参考下面内容

值的比较

数字比较略,

在比较字符串的大小时,JavaScript 会使用“字典(dictionary)”或“词典(lexicographical)”顺序进行判定。

换言之,字符串是按字符(母)逐个进行比较的。并且比较的是Unicode 编码顺序。

不同类型的比较:

当对不同类型的值进行比较时,JavaScript 会首先将其转化为数字(number)再判定大小。

注意:在转换时 null 转换成 0 ,undefined 转换成 NaN,NaN与任何数字比较都是返回false。null和undefined在做==判断时不发生转换,且null == undefined返回true,与其他任何值相比都返回false。另外 null === undefined 返回false。

alert( null > 0 );  // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true

alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)

5 > 4 → true
"apple" > "pineapple" → false
"2" > "12" → true
undefined == null → true
undefined === null → false
null == "\n0\n" → false
null === +"\n0\n" → false

关于if

可以用三目运算代替if...else,例如:

let message;

if (login == 'Employee') {
  message = 'Hello';
} else if (login == 'Director') {
  message = 'Greetings';
} else if (login == '') {
  message = 'No login';
} else {
  message = '';
}

可以写成:

let message = (login == 'Employee') ? 'Hello' :
  (login == 'Director') ? 'Greetings' :
  (login == '') ? 'No login' :
  '';

虽然if....else更长但是可读性强,可以自己取舍。

 逻辑运算符

|| (或)

除了基本用法,我们可以利用或运算来提取第一个真值

result = value1 || value2 || value3;

如果不存在真值,就返回该链的最后一个值

alert( 1 || 0 ); // 1(1 是真值)

alert( null || 1 ); // 1(1 是第一个真值)
alert( null || 0 || 1 ); // 1(第一个真值)

alert( undefined || null || 0 ); // 0(都是假值,返回最后一个值)

实际运用:

例如,我们有变量 firstNamelastName 和 nickName,都是可选的(即可以是 undefined,也可以是假值)。

我们用或运算 || 来选择有数据的那一个,并显示出来(如果没有设置,则用 "Anonymous"):

let firstName = "";
let lastName = "";
let nickName = "SuperCoder";

alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder

短路求值(Short-circuit evaluation)。

或运算符 || 的另一个用途是所谓的“短路求值”。

这指的是,|| 对其参数进行处理,直到达到第一个真值,然后立即返回该值,而无需处理其他参数。

如果操作数不仅仅是一个值,而是一个有副作用的表达式,例如变量赋值或函数调用,那么这一特性的重要性就变得显而易见了。

在下面这个例子中,只会打印第二条信息:

true || alert("not printed");
false || alert("printed");

在第一行中,或运算符 || 在遇到 true 时立即停止运算,所以 alert 没有运行。

有时,人们利用这个特性,只在左侧的条件为假时才执行命令。

下面这段代码会输出什么?

alert( alert(1) || 2 || alert(3) );

答案:首先是 1,然后是 2

对 alert 的调用没有返回值。或者说返回的是 undefined

  1. 第一个或运算 || 对它的左值 alert(1) 进行了计算。这就显示了第一条信息 1
  2. 函数 alert 返回了 undefined,所以或运算继续检查第二个操作数以寻找真值。
  3. 第二个操作数 2 是真值,所以执行就中断了。2 被返回,并且被外层的 alert 显示。

这里不会显示 3,因为运算没有抵达 alert(3)

&&(与)

基本用法略。

与运算寻找第一个假值

result = value1 && value2 && value3;

和或运算相反,这里返回的是第一个假值,如果没有假值,则返回最后一个值。

alert( 1 && 2 && null && 3 ); // null

alert( 1 && 2 && 3 ); // 3,最后一个值

与运算 && 的优先级比或运算 || 要高。

所以代码 a && b || c && d 跟 && 表达式加了括号完全一样:(a && b) || (c && d)

这段代码将会显示什么?

alert( alert(1) && alert(2) );

答案:1,然后 undefined。

调用 alert 返回了 undefined(它只展示消息,所以没有有意义的返回值)。

因此,&& 计算了它左边的操作数(显示 1),然后立即停止了,因为 undefined 是一个假值。&& 就是寻找假值然后返回它,所以运算结束。

!(非)

感叹符号 ! 表示布尔非运算符。

逻辑非运算符接受一个参数,并按如下运作:

  1. 将操作数转化为布尔类型:true/false
  2. 返回相反的值。

两个非运算 !! 有时候用来将某个值转化为布尔类型:

alert( !!"non-empty string" ); // true
alert( !!null ); // false

非运算符 ! 的优先级在所有逻辑运算符里面最高,所以它总是在 && 和 || 之前执行。

??(空值合并运算符)

空值合并运算符 ?? 提供了一种从列表中选择第一个“已定义的”值的简便方式。

它被用于为变量分配默认值:

// 当 height 的值为 null 或 undefined 时,将 height 的值设置为 100
height = height ?? 100;
  • ?? 运算符的优先级非常低,仅略高于 ? 和 =,因此在表达式中使用它时请考虑添加括号。

  • 如果没有明确添加括号,不能将其与 || 或 && 一起使用。

循环

我们可以利用continue来减少代码嵌套:

for (let i = 0; i < 10; i++) {

  if (i % 2) {
    alert( i );
  }

}

可以改写成:

for (let i = 0; i < 10; i++) {

  //如果为真,跳过循环体的剩余部分。
  if (i % 2 == 0) continue;

  alert(i); // 1,然后 3,5,7,9
}

函数

函数声明方式如下所示:

function name(parameters, delimited, by, comma) {
  /* code */
}
  • 作为参数传递给函数的值,会被复制到函数的局部变量。
  • 函数可以访问外部变量。但它只能从内到外起作用。函数外部的代码看不到函数内的局部变量。
  • 函数可以返回值。如果没有返回值,则其返回的结果是 undefined。如alter()
  • 函数的参数可以有默认值
    function showMessage(from, text = "no text given") {
      alert( from + ": " + text );
    }
    
    showMessage("Ann"); // Ann: no text given

    这里text在不给参数的情况下就会使用我们设置的默认值"no text given"

为了使代码简洁易懂,建议在函数中主要使用局部变量和参数,而不是外部变量。

与不获取参数但将修改外部变量作为副作用的函数相比,获取参数、使用参数并返回结果的函数更容易理解。

函数命名:

  • 函数名应该清楚地描述函数的功能。当我们在代码中看到一个函数调用时,一个好的函数名能够让我们马上知道这个函数的功能是什么,会返回什么。
  • 一个函数是一个行为,所以函数名通常是动词。
  • 目前有许多优秀的函数名前缀,如 create…show…get…check… 等等。使用它们来提示函数的作用吧。

不能在return和返回值之间加空行

对于 return 的长表达式,可能你会很想将其放在单独一行,如下所示:

return
 (some + long + expression + or + whatever * f(a) + f(b))

但这不行,因为 JavaScript 默认会在 return 之后加上分号。上面这段代码和下面这段代码运行流程相同:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值