Blogger Information
Blog 5
fans 0
comment 0
visits 2394
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
JavaScript基础语法(二)(运算符、流程控制、函数)
幽幽小帆
Original
479 people have browsed it

1、运算符

(1)赋值运算符

一个 赋值运算符(assignment operator) 将它右边操作数的****赋给它左边的操作数。最简单的赋值运算符是等于(=),它将右边的操作数值赋给左边的操作数。那么 x = y 就是将 y 的值赋给 x。

  1. =
  2. +=
  3. -=
  4. *=
  5. /=

(2)算术运算符

算术运算符使用数值(字面量或者变量)作为操作数并返回一个数值。标准的算术运算符就是加减乘除(+ - * /)。

当操作数是浮点数时,这些运算符表现得跟它们在大多数编程语言中一样(特殊要注意的是,除零会产生Infinity)。

除了标准的算术运算符(+, - ,* /),JavaScript还提供了下表中的算术运算符。

  • %:求余,返回相除之后的余数。
  • ++:自增
  • --:自减
  • -:返回操作数的负值
  • +:如果操作数在之前不是number,试图将其转换为number
  • **:指数运算符
    • 2 ** 3 returns 8
    • 10 ** -1 returns 0.1

(2)逻辑运算符

逻辑运算符常用于布尔(逻辑)值之间; 当操作数都是布尔值时,返回值也是布尔值。 不过实际上&&和||返回的是一个特定的操作数的值,所以当它用于非布尔值的时候,返回值就可能是非布尔值。

  1. &&
  2. ||
  3. !

短路求值:

作为逻辑表达式进行求值是从左到右,它们是为可能的“短路”的出现而使用以下规则进行测试:

  • false && anything // 被短路求值为false
  • true || anything // 被短路求值为true

逻辑的规则,保证这些评估是总是正确的。请注意,上述表达式的anything部分不会被求值,所以这样做不会产生任何副作用。

(3)比较运算符

  1. = // 赋值运算符
  2. == // 等于(类型不一样,值一样,也会判断true
  3. === // 绝对等于(类型一样,值一样)
  • 这是js的一个缺陷,坚持不要使用 == 比较
  • NaN 和任何值都不相等,包括自身,只能通过 isNaN(NaN) 来判断这个数是否是NaN
  • 浮点数问题:

null 和 undefined

  • null 空
  • undefined 未定义

(4)字符串运算符

除了比较操作符,它可以在字符串值中使用,连接操作符(+)连接两个字符串值相连接,返回另一个字符串,它是两个操作数串的结合。

  1. var myString = "alpha";
  2. myString += "bet"; // 返回 "alphabet"

(5)逗号运算符

逗号操作符(,)对两个操作数进行求值并返回最终操作数的值。它常常用在 for 循环中,在每次循环时对多个变量进行更新。

例如

  • 假如 a 是一个二维数组,每个维度各有10个元素,以下代码利用逗号操作符来同时改变两个变量的值。
  • 这段代码的功能是打印出该二维数组的对角线元素的值:
  1. var x = [0,1,2,3,4,5,6,7,8,9]
  2. var a = [x, x, x, x, x];
  3. for (var i = 0, j = 9; i <= j; i++, j--)
  4. console.log('a[' + i + '][' + j + ']= ' + a[i][j]);
  5. 结果:
  6. a[0][9]= 9
  7. a[1][8]= 8
  8. a[2][7]= 7
  9. a[3][6]= 6
  10. a[4][5]= 5

(6)一元操作符

  • delete
    • delete操作符,删除一个对象的属性或者一个数组中某一个键值
    • 如果 delete 操作成功,属性或者元素会变成 undefined。
    • 删除数组中的元素时,数组的长度是不变的,例如删除a[3], a[4],a[4]和a[3] 仍然存在变成了undefined。
  • typeof
    • typeof 操作符返回一个表示 operand 类型的字符串值。operand 可为字符串、变量、关键词或对象,其类型将被返回。
  • void
    • void运算符表明一个运算没有返回值。
    • 如下创建了一个超链接文本,当用户单击该文本时,不会有任何效果。
  1. <a href="javascript:void(0)">Click here to do nothing</a>

(7)关系操作符

  • in
    • in操作符,如果所指定的属性确实存在于所指定的对象中,则会返回true
  1. // Arrays
  2. var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
  3. 0 in trees; // returns true
  4. 3 in trees; // returns true
  5. 6 in trees; // returns false
  6. "bay" in trees; // returns false (you must specify the index number,
  7. // not the value at that index)
  8. "length" in trees; // returns true (length is an Array property)
  9. // Predefined objects
  10. "PI" in Math; // returns true
  11. var myString = new String("coral");
  12. "length" in myString; // returns true
  13. // Custom objects
  14. var mycar = {make: "Honda", model: "Accord", year: 1998};
  15. "make" in mycar; // returns true
  16. "model" in mycar; // returns true
  • instanceof
    • 如果所判别的对象确实是所指定的类型,则返回true
    • 当你需要确认一个对象在运行时的类型时,可使用instanceof

(7)运算符优先级

运算符的优先级,用于确定一个表达式的计算顺序。在你不能确定优先级时,可以通过使用括号显式声明运算符的优先级

Operator type Individual operators
member . []
call / create instance () new
negation/increment ! ~ - + ++ -- typeof void delete
multiply/divide * / %
addition/subtraction + -
bitwise shift << >> >>>
relational < <= > >= in instanceof
equality == != === !==
bitwise-and &
bitwise-xor ^
bitwise-or ` `
logical-and &&
logical-or ` `
conditional ?:
assignment `= += -= *= /= %= <<= >>= >>>= &= ^= =`
comma ,

更为详细的版本:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table

2、流程控制

(1)if else

  1. let age = 3;
  2. if (age >= 18){
  3. console.log("成年人");
  4. }else if (age >= 12){
  5. console.log("青少年");
  6. }else{
  7. console.log("儿童");
  8. }

(2)switch

  1. <script>
  2. let err = 0;
  3. switch(err){
  4. case 0:
  5. console.log('请求错误');
  6. break;
  7. case 1:
  8. console.log("请求超时");
  9. break;
  10. case 2:
  11. console.log("请求成功");
  12. break;
  13. default:
  14. console.log("未知错误");
  15. break;
  16. }
  17. </script>
  1. <script>
  2. let age = 0;
  3. switch(true){
  4. case age >=18 && age < 65:
  5. console.log('青壮年');
  6. break;
  7. case age >= 12 && age < 18:
  8. console.log("青少年");
  9. break;
  10. case age >=3 && age < 12:
  11. console.log("儿童");
  12. break;
  13. case age < 3:
  14. console.log("婴幼儿");
  15. break;
  16. default:
  17. console.log("退休了");
  18. break;
  19. }
  20. </script>

(3)三元表达式

Boolean(条件)? A : B

  1. // 如果Boolean(gender)则输出女,否则输出男。
  2. Boolean(gender)? '女': '男';

(3)for循环

循环三条件:

  1. 初始条件:数组索引的引用(i= 0)
  2. 循环条件:为真则执行循环体(i < arr.length)
  3. 更新条件:必须要有,否则进入死循环(i++)

①、for循环

  1. for(let i=0; i< 100; i++){
  2. console.log(i)
  3. }
  4. let age = [12, 3, 45, 24, 53, 32, 56, 45, 67];

②、while循环

  1. var num = 0;
  2. while(num <= 100){
  3. console.log(num);
  4. num++;
  5. }
  6. do{
  7. console.log(num);
  8. num++;
  9. }while(num < 100)

③、for of 循环

ES6语法糖,类似python

  1. let age = [12, 3, 45, 24, 53, 32, 56, 45, 67];
  2. for (let num of age){
  3. console.log(num);
  4. }

④、for in 循环

对象遍历用 for…in

  1. let age = [12, 3, 45, 24, 53, 32, 56, 45, 67];
  2. for (let num in age){
  3. console.log(num); // num 是age的索引
  4. console.log(age[num]); // 输出值
  5. }
  1. let obj = {
  2. id:1,
  3. username: 'xiaoniu',
  4. 'max salary': 123456,
  5. };
  6. for (var key in obj){
  7. console.log(key); // key obj
  8. console.log(obj[key]); // 输出值
  9. }

3、函数

对于重复的计算过程,可以考虑函数进行封装,实现“代码复用”。

(1)函数的声明和调用

这部分基础语法(一)中已有。

(2)匿名函数

匿名函数有两种:

  • 第一种:函数是一次性的,称为立即调用函数, IIFE
    • 将声明与调用二合一
  1. (function(a,b){
  2. console.log(a+b);
  3. })(10,50);
  • 第二种:函数不是一次性的,可以使用函数表达式
    • 将匿名函数当成值赋给一个变量
    • 调用方式:通过变量
  1. let getUserName = function(username){
  2. return "Hello" + username;
  3. }
  4. console.log(getUserName('小牛同学'));
  • 第三种:箭头函数
    • 用于简化匿名函数
  1. // 命名函数
  2. function sum(a, b){
  3. return a + b
  4. }
  5. // 匿名函数
  6. let add1 = function(a, b){
  7. return a + b
  8. }
  9. // 箭头函数
  10. let add2 = (a, b)=>{
  11. console.log(a + b)
  12. }

转化方法:

  • 去掉function
  • 在参数列表与大括号之间使用 =>
  1. // 如果函数体只有一条语句,**大括号**可以不写
  2. <script>
  3. let sum = (a, b)=>a+b;
  4. let res = sum(23, 342);
  5. console.log(res); // 结果为:365
  6. </script>
  7. <script>
  8. let sum = (a, b)=>console.log(a+b);
  9. sum(23, 342); // 结果为:365
  10. </script>
  11. // 如果参数只有一个,那么**参数的括号**也可以不写
  12. add = a => a+5;
  13. console.log(add(34, 42));
  14. // 但是没有参数时,括号必须写
  15. add = ()=>15+3;
  16. console.log(add());

补充

  • 胖箭头:=>
  • 瘦箭头:→

(3)函数传参

①、参数不足时,可以设置默认参数

参数不足时,可以设置默认参数

  1. function sum1(num1, num2){
  2. let total = 0;
  3. total = num1 + num2;
  4. console.log("total =", total);
  5. }
  6. sum1(12, 34);
  7. sum1(23); // 输出: NaN,原因是由于参数不足。
  8. //对于参数不足可以设置一个默认参数
  9. function sum2(num1, num2=0){
  10. let total = 0;
  11. total = num1 + num2;
  12. console.log("total =", total);
  13. }
  14. sum2(23);
  • function: 函数声明的关键字
  • sum1:函数名称
  • (num1, num2): 参数列表
  • (12, 34):调用参数,实际参数(实参),与上面参数列表中的参数一一对应。

③、参数过多时,可以使用rest语法

对于传入函数参数过多的情况,可以使用 rest语法 来解决,这种方式叫做归内参数/剩余参数/不定参数,将多余参数压到一个数组参数中

  1. function sum3(...args){
  2. console.log(args); // 输出:[23, 34, 545, 7, 23]
  3. }
  4. sum3(23,34,545,7,23);

①、将 … 用在函数的形参中,就是rest,归并操作,把多余的参数压到一个数组中。

  1. <script>
  2. let f = (a,b,...c)=>console.log(a,b,c);
  3. f(1,2,3,4,5,6); // 输出: 1 2 [3, 4, 5, 6]
  4. </script>

②、将 … 用在函数的调用参数中,就是扩展/展开,spread。

  1. let f = (a,b,...c)=>console.log(a,b,c);
  2. f(1,2,3,4,5,6);
  3. const arr = [12,45,67,76,34]
  4. f(...arr)

(4)函数的返回值

函数只能有一个返回值,默认单值返回。

如果需要返回多个值呢?

  • 可以使用数组或者对象
  1. <script>
  2. let fn = () => [1,2,3]
  3. let res = fn();
  4. console.log(res);
  5. fn = () =>({
  6. id:2,
  7. name:'admin',
  8. age:'23',
  9. });
  10. console.log(fn());
  11. </script>

(5)作用域

作用域分为:全局作用域、函数作用域,还有块作用域(块作用域不常用)。

  1. // 块作用域
  2. {
  3. let a = 1;
  4. console.log(a);
  5. }
  6. console.log(a);

①、函数作用域

函数作用域,即为在函数里边的变量。

②、全局作用域

全局作用域,即在函数外边的变量。

注:

函数里可以调用函数外的变量,但是函数外不能调用函数内的变量。

如果两个不同的函数各自申明了同一个变量,那么该变量只在各自的函数体内起作用。换句话说,不同函数内部的同名变量互相独立,互不影响:

这说明JavaScript的函数在查找变量时从自身函数定义开始,从“内”向“外”查找。如果内部函数定义了与外部函数重名的变量,则内部函数的变量将“屏蔽”外部函数的变量

  1. function foo() {
  2. var x = 1;
  3. function bar() {
  4. var x = 'A';
  5. console.log('x in bar() = ' + x);
  6. }
  7. console.log('x in foo() = ' + x); // 1
  8. bar(); // 'A'
  9. console.log('x in foo() = ' + x); // 1
  10. }
  11. foo();
  12. // 输出:
  13. x in foo() = 1
  14. x in bar() = A
  15. x in foo() = 1

作用域链:作用域链用于查询变量。作用域链的内容是:查询变量的时候,先从函数内部查询,如果有就直接访问,如果没有则向上一个作用域查询,一级一级向上,直到全局作用域。

作用域链的特点:

  • 单向的。
  • 由外向内传递可以,但是由内向外禁止。

(6)闭包

闭包的两个条件:

  1. 父子函数
  2. 自由变量
  1. <body>
  2. <script>
  3. function parent() {
  4. let a = 5;
  5. function f(b) {
  6. let c = 7;
  7. return a + b + c;
  8. }
  9. return f;
  10. }
  11. console.log(parent());
  12. const f1 = parent();
  13. console.log(f1);
  14. console.log(f1(3));
  15. </script>
  16. </body>

以下代码中 a 是子函数f 的自由变量。

  1. <body>
  2. <script>
  3. function parent1(a) {
  4. function f(b) {
  5. let c = 7;
  6. return a + b + c;
  7. }
  8. return f;
  9. }
  10. // 这时候,在外部调用 parent1() 会返回一个函数,此时闭包就产生了。
  11. console.log(parent1(4));
  12. // parent1() 调用结束,应该将空间和参数都释放的,但是由于父函数中第一个变量a 被它的一个子函数引用着,所有就不能销毁,这就会产生闭包。
  13. const f1 = parent1(4);
  14. console.log(f1);
  15. console.log(f1(3));
  16. </script>
  17. </body>

  1. // 如果:
  2. const f1 = parent1();
  3. console.log(f1(3)); // 结果为NaN,因为a缺少参数。

闭包的示例:

  1. let counter = (function(n){return function(){return n++}})(1);
  2. console.log(counter());
  3. console.log(counter());
  4. console.log(counter());


(7)对象字面量的简化

①、属性简化

  1. <script>
  2. let username = 'jack';
  3. let name = 'marry';
  4. let user1 = {
  5. username: 'tom',
  6. };
  7. console.log(user1.username); // 输出:tom
  8. let user2 = {
  9. username: name,
  10. };
  11. console.log(user2.username); // 输出:marry
  12. let user3 = {
  13. username: username,
  14. };
  15. console.log(user3.username); // 输出:jack
  16. // 简化熟悉
  17. let user4 = {
  18. username,
  19. };
  20. console.log(user4.username); // 输出:jack
  21. </script>

当满足以下两个条件的时候,可以简化属性:

  1. 作用域相同:对象属性与变量处于同一作用域下面。
  2. 名称相同:对象属性与变量同名。

②、方法简化

  1. <script>
  2. let username = 'jack';
  3. let user = {
  4. username,
  5. };
  6. console.log(user.username); // 输出:jack
  7. let user1 = {
  8. username,
  9. getName: function(){
  10. return 'Hello ' + this.username;
  11. },
  12. };
  13. console.log(user1.getName()) // 输出:Hello jack
  14. // 简化方法
  15. // 语法:省略 ": function"
  16. let user2 = {
  17. username,
  18. getName(){
  19. return 'Hello ' + this.username;
  20. },
  21. };
  22. console.log(user2.getName()) // 输出:Hello jack
  23. </script>

(8)模板字面量和模板函数

模板字面量:也叫”模板字符串”,是同义词,我觉得用”模板字面量”更直观,准确
模板函数:有的书也翻译与”标签函数”,因为它使用”模板字面量”做参数,称为”模板函数”更准确。

①、模板字符串

  1. <script>
  2. // 传统的输出字符串,使用双引号或者单引号
  3. console.log("Hello World!");
  4. // 如果要输出多行字符串,那么传统方法:
  5. console.log("html \n" + "css\n" + "js");
  6. // 输出表达式计算结果:
  7. let a = 10, b=20;
  8. console.log(a + "+" + b + "=" + (a, b))
  9. // 使用模板字符串
  10. // 模板字符串语法: 对变量或表达式可以使用 ${x} 来引用。
  11. let res = `${a} + ${b} = ${a + b}`
  12. console.log(res);
  13. // 模板表达式可以嵌套
  14. let gender = 0;
  15. let res1 = `${gender? `男:${name}`: `女`}`;
  16. console.log(res1);
  17. </script>

注:使用插值占位符: **${}** ,可以将变量或表达式插入到字符串中。

②、模板函数

使用模板字符串为参数的函数

例如:

  1. alert`Hello World!`
  1. <script>
  2. function calc(strs, ...args){
  3. console.log(strs);
  4. console.log(args);
  5. console.log(args[0] * args[1])
  6. }
  7. calc`数量: ${10}, 单价: ${50}`
  8. </script>

注:

  • 模板函数就是在“模板字面量”之前加一个标签/标识符,而这个标签就是一个函数名。
  • 模板函数的参数是有约定的,不能乱写,第一个是字面量数组,从第二个开始才是内部的占位符参数
Correcting teacher:PHPzPHPz

Correction status:qualified

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post