第三章:语言基础

第三章:语言基础

3.1 语法

3.1.4 严格模式

"use strict";
function doSomething() {
    "use strict";
    // do something
}

3.3 变量

3.3.1 var 关键字

  • 不初始化的情况下,变量值为 undefined
var a;
console.log(a); // output: undefined
a = 1;
console.log(a); // output: 1
  1. var 声明作用域
    1.1 使用 var 定义的变量会成为其所在函数的局部变量
    1.2 省略 var 会创建全局变量

1.1 代码示例:

function test() {
    var char = 'a';
}
test(); // 调用时创建变量并赋值,调用后销毁
console.log(char);  // output:char is not defined

1.2 代码示例

function test() {
    // var char = 'a';
    char = 'a';
}
test();
console.log(char);  // output:a
  1. var 声明提升
function test() {
    console.log(char);
    var char = 'a';
}
test(); // output: undefined

上面的代码等价于:

function test() {
    var char;
    console.log(char);
    char = 'a';
}
test(); // output: undefined

3.3.2 let 声明

  • let 声明的范围是块作用域
if (true) {
    let name = 'jiy';
    console.log(name); // output: jiy
}
console.log(name); // output:name is not defined
  • var 声明的范围是函数作用域
if (true) {
    var name = 'jiy';
    console.log(name); // output: jiy
}
console.log(name); // output: jiy
  1. 暂时性死区

    • let 没有变量提升
    • 在 let 声明前的执行瞬间被称为暂时性死区
  2. 全局声明

    • 与 var 不同,let 在全局作用域中声明的变量不会成为 window对象的属性
  3. for 循环中的 let 声明

    • 使用 let 声明迭代变量时,后台会为每个迭代循环声明一个新的迭代变量。每个 setTimeout 引用的都是不同的变量实例
for (var i = 0; i < 5; i++) {
    setTimeout(() => {
        console.log(i);
    }, 0);
}
// output: 5 5 5 5 5

for (let i = 0; i < 5; i++) {
    setTimeout(() => {
        console.log(i);
    }, 0);
}
// output: 0 1 2 3 4

3.3.3 const 声明

  • const 声明的限制只适用于它指向的变量的引用
const person = {};
person.name = 'Jiy';    // ok

3.4 数据类型

  • ES6 有六种简单数据类型:
    • Undefined
    • Null
    • Boolean
    • Number
    • String
    • Symbol(ES6新增)
  • 还有一种复杂数据类型:
    • Object

3.4.1 typeof 操作符

  • 返回值
    • “boolean”
    • “string”
    • “number”
    • “object”:值为对象或null
    • “function”
    • “symbol”

3.4.2 Undefined 类型

let test1;
// let test2;
console.log(typeof test1);  // output: undefined
console.log(typeof test2);  // output: undefined

if (test1) {
    // 不会执行
}

if (!test1) {
    // 会执行
}

if (test2) {
    // 报错
}

3.4.3 Null 类型

  • null 值表示一个空对象指针
  • 注意:
console.log(undefined == null); // output: true

3.4.4 Boolean 类型

数据类型转换为 true 的值转换为 false 的值
Booleantruefalse
String非空字符串“”
Number非零数值(包括无穷值)0,NaN
Object任意对象null
UndefinedN/A(不存在)undefined
console.log(Boolean("")); // output: false

3.4.5 Number 类型

  • 注意:
    • 八进制字面量在严格模式下会导致引擎抛出语法错误
    • 正零和负零在所有情况下都被认为是等同的
  1. 浮点值
  2. 值的范围
    • 精确度最高可达 17 位小数
      • 可表示最小值 Number.MIN_VALUE
      • 可表示最大值 Number.MAX_VALUE
      • 超出范围会被转换成 Infinity
    • 2.2.0会被当成 2处理
    • 0.1 + 0.2 == 0.300 000 000 000 000 04
let result = Number.MAX_VALUE + Number.MIN_VALUE;
console.log(isFinite(result)); // output: false
  1. NaN:Not A Number
    • 表示本来要返回数值的操作失败了
console.log(0 / 0);         // output: NaN
console.log(-5 / 0);        // output: -Infinity
console.log(NaN == NaN);    // output: false
console.log(isNaN(true));   // output:false ( true -> 1 )
  1. 数值转换
Number()
    Number(true) == 1
    Number(null) == 0
    Number(undefined) == NaN
parseInt()

parseFloat()

3.4.6 String 类型

  1. 字符字面量

    • 转义序列只算一个字符的长度
  2. 字符串的特点

    • 字符串不可变,修改时会重新创建
  3. 转换为字符串

    • toString()
      • true 调用该方法返回 ‘true’
      • null 和 undefined 没有该方法
    • String()
      • null 和 undefined 分别返回自身的字符串
  4. 模板字面量

  5. 字符串插值

  6. 标签函数:必须使用模板字面量` `

let a = 6;
let b = 9;

function simpleTest(strings, ...expressions) {
    console.log(strings)
    return strings[0] + expressions.map((e, i) => `${e}${strings[i + 1]}`).join('');
}

const result = simpleTest`${a}+${b}=${a + b}`;
console.log(result) // output: 6+9=15
  1. 原始字符串
console.log(String.raw`\u00A9`);    // output: \u00A9
                                    // 也可以通过标签函数第一个参数的 raw 属性获取

3.4.7 Symbol 类型

  • 符号是原始值,符号实例唯一且不可变
  • 用途:确保对象属性使用唯一标识符,不会发生属性冲突
  1. 基本用法
let a1 = Symbol();
let a2 = Symbol();

let b1 = Symbol('test');
let b2 = Symbol('test');

let c = {b1:2};
c[b1] = 1;
c[b2] = 3;

console.log(a1 == a2);  // output: false
console.log(b1 == b2);  // output: false
console.log(b1);        // output: Symbol(test)
console.log(c);         // output: { b1: 2, [Symbol(test)]: 1, [Symbol(test)]: 3 }



let test1 = new Symbol();    // 报错
let test2 = Symbol();
let test3 = Object(test2);  // √
  1. 使用全局符号注册表
    • Symbol.for()
    • Symbol.keyFor(): string | undefined
let globalSymbol = Symbol.for('test');  // 创建新符号,添加到注册表
let other = Symbol.for('test');         // 重用已有符号
let other2 = Symbol('test');

console.log(globalSymbol == other);         // output: true
console.log(globalSymbol == other2);        // output: false

console.log(Symbol.keyFor(globalSymbol));   // output: test
console.log(Symbol.keyFor(other2));         // output: undefined
  1. 使用符号作为属性
    • 可以使用字符串或数值作为属性的地方,都可以使用符号
let s1 = Symbol('test1'),
    s2 = Symbol('test2'),
    s3 = Symbol('test3'),
    s4 = Symbol('test4');

let obj = {
    s0: 'p0',
    [s1]: "p1"
};
console.log(Object.getOwnPropertySymbols(obj));             // output: [ Symbol(test1) ]

Object.defineProperty(obj, s2, { value: 'p2' });
console.log(Object.getOwnPropertySymbols(obj));             // output: [ Symbol(test1), Symbol(test2) ]

Object.defineProperties(obj, {
    [s3]: { value: 'p3' },
    [s4]: { value: 'p4' }
});
console.log(Object.getOwnPropertySymbols(obj));             // output: [ Symbol(test1), Symbol(test2), Symbol(test3), Symbol(test4) ]
// console.log(Object.getOwnPropertyDescriptors(obj));      // 返回包含常规和符号属性描述符的对象
console.log(Reflect.ownKeys(obj));                          // output: [ 's0', Symbol(test1), Symbol(test2), Symbol(test3), Symbol(test4) ]
  1. 常用内置符号
    • @@iterator== Symbol.iterator
    • 通过重新定义内置符号可以改变原生结构的行为

3.4.8 Object 类型

3.5 操作符

3.5.2 位操作符

  • p59(第四版 中文)
  • ES 用64位存储数值,位操作时先转换成32位,之后把结果转换到64位
  • 有符号整数使用32位的前31位表示整数值,第三十二位表示符号(0为正,1为负)
  • 负数:
1. 确定绝对值的二进制表示
2. 取反码
3. 结果加1

以 -18 为例:
1. 18的二进制表示为:
    0000 0000 0000 0000 0000 0000 0001 0010
2. 反码为:
    1111 1111 1111 1111 1111 1111 1110 1101
3. 结果加1即为最终结果:
    1111 1111 1111 1111 1111 1111 1110 1110

let num = -18;
console.log(num.toString(2));   // output: "-10010"
  • NaNInfinity在位处理中被当成 0 处理
  1. 按位非 ~
    • 返回数值的反码
    • 最终效果是对数值取反并减一
  2. 按位与 &
    • 将两个数的每一位对齐
    • 只有两个位都是 1 时返回1,任意一位是 0 时返回0
25   = 0000 0000 0000 0000 0000 0000 0001 1001
 3   = 0000 0000 0000 0000 0000 0000 0000 0011
------------------------------------------------
AND  = 0000 0000 0000 0000 0000 0000 0000 0001
  1. 按位或 |
    • 只有两个位都是 0 时返回0,任意一位是 1 时返回1
  2. 按位异或 ^
    • 两位都是 1 或 0 时,返回 0
  3. 左移 <<
    • 按照指定的位数将数值的所有位向左移动,用 0 补全、
    • 保留符号位
  4. 有符号右移 >>
    • 是左移的逆运算
    • 空位用符号位的值补全
  5. 无符号右移 >>>
    • 正数的结果与 >> 相同
    • 负数用 0 补全空位,结果为正数

3.5.3 布尔操作符

  1. !
console.log(!{});           // false

console.log(!"");           // true
console.log(!"abc");        // false

console.log(!0);            // true
console.log(!9);            // false
console.log(!Infinity);     // false

console.log(!null);         // true
console.log(!NaN);          // true
console.log(!undefined);    // true
  1. &&

    • 第一个操作数是对象,返回第二个操作数
    • 第二个操作数是对象,只有第一个求值为 true时返回该对象
    • 都是操作数,返回第二个操作数
    • 有一个操作数为 null | NaN | undefined,返回 null | NaN | undefined
    • 短路性
  2. ||

    • 第一个操作数是对象,返回第一个操作数
    • 第一个操作数是 false,返回第二个操作数
    • 都是操作数,返回第一个操作数
    • 有一个操作数为 null | NaN | undefined,返回 null | NaN | undefined
    • 短路性

3.5.4 乘性操作符

  1. 乘法操作符
    • Infinity * 0 = NaN
  2. 除法操作符
    • Infinity / Infinity = NaN
    • 0 / 0 = NaN
  3. 取模操作符
    • Infinity % 有限值 = NaN
    • 有限值 % 0 = NaN
    • Infinity % Infinity = NaN
    • 有限值 % 无限制 = 有限值
    • 0 % 非0 = 0

3.5.5 指数操作符 ** Math.pow()

3.5.6 加性操作符

  1. 加法操作符
    • 任一为 NaN,返回NaN
    • Infinity + Infinity = Infinity
    • Infinity + -Infinity = NaN
    • +0 + +0 = +0
    • +0 + -0 = +0
  2. 减法操作符
    • +0 - -0 = -0

3.5.7 关系操作符

  • 涉及 NaN时返回 false

3.5.8 相等操作符

  1. == / !=
    • undefined == null
    • undefinednull不进行类型转换
    • NaN出现时一律不相等
    • 都为对象时,两者指向同一对象时相等
class Test {}

const a = new Test();
const b = new Test();
console.log(a == b);    // output: false
  1. === / !==
    • undefined !== null

3.5.9 条件操作符(三元表达式)

3.5.10 赋值操作符

3.5.11 逗号操作符

let num = (1, 2, 3, 4, 5, 0);   // num = 0

3.6 语句

3.6.1 if 语句

3.6.2 do-while 语句

3.6.3 while 语句

3.6.4 for 语句

3.6.5 for-in 语句

  • 只迭代非符号键属性
  • 要迭代的变量是 nullundefined时,不会执行循环体

3.6.6 for-of 语句

  • 按照可迭代对象的 next()方法产生值的顺序进行迭代(详见第七章)
  • ES2018 新增了异步迭代 for-await-of,详见附录A

3.6.7 标签语句

  • 可通过 breakcontinue引用
start: for(const item of array){
    console.log(item);
}

3.6.8 break 和 continue 语句

let num = 0;

outermost:
for (let i = 0; i < 10; i++) {
    for (let j = 0; j < 10; j++) {
        if (i == 5 && j == 5) {
            break outermost;            // 标签让 break 同时也退出了外层循环
            // continue outermost;      // 标签会让外层循环继续执行,而不是内层
        }
        num++;
    }
}

console.log(num);                       // output: 55

3.6.9 with 语句

  • 将代码作用域设置为特定的对象
  • 严格模式不允许使用
  • 影响性能,难以调试,不推荐使用
let qs = location.search.substring(1);
let hostName = location.hostname;
let url = location.href;

    |
    V

with(location) {
    let qs = search.substring(1);
    let hostName = hostname;
    let url = href;
}

3.6.10 switch 语句

  • 条件值可以是变量或表达式
  • 不会进行类型转换
  • 特殊用法:
let num = 25;

switch (true) {
    case num < 0:
        console.log('num < 0');
        break;
    case num >= 0 && num <= 10:
        console.log('num between 0 and 10');
        break;
    case num > 10 && num <= 20:
        console.log('num between 10 and 20');
        break;
    default:
        console.log('num > 20');
}

3.7 函数

  • 详见第十章
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
循环结构是Python编程语言中非常重要的一部分。它允许我们重复执行一段代码,以达到更高效和简洁的编程。 在Python中,有两种常用的循环结构,分别是for循环和while循环。 for循环适用于已知循环次数的情况。它通过遍历一个可迭代对象(比如列表或字符串),依次取出其中的元素,并执行相应的代码块。例如,我们可以使用for循环来计算一个列表中所有元素的总和。代码如下: ```python numbers = [1, 2, 3, 4, 5] total = 0 for num in numbers: total += num print(total) # 输出:15 ``` while循环适用于未知循环次数的情况。它会根据一个条件判断的真假来决定是否继续循环执行代码块。当条件为真时,代码块会一直执行下去,直到条件为假时停止循环。例如,我们可以使用while循环来实现一个简单的倒数计时器。代码如下: ```python countdown = 10 while countdown > 0: print(countdown) countdown -= 1 print("倒计时结束!") ``` 上述代码会从10开始倒数,直到countdown变为0时,停止循环,并输出"倒计时结束!"。 无论是for循环还是while循环,我们在使用时都需要小心避免死循环的情况。如果循环条件一直为真,循环就会一直执行下去,导致程序无法正常结束。因此,在编写代码时,我们应该保证循环条件能够在一定条件下变为假,以防止出现死循环的情况。 循环结构在Python编程中具有重要作用,它可以帮助我们处理大量数据、重复任务和条件控制等问题,提高代码的灵活性和效率。熟练掌握循环结构的使用,对于编写高效的程序非常重要。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值