JavaScript速记:掌握核心语法

最近我对鸿蒙开发产生了浓厚的兴趣,周末翻阅了廖雪峰老师的JS教程。本文是总结笔记,方便查阅这些语法。

基本语法

// Number, 不区分整数和浮点数
console.log(12.00 === 12)  // true

// 求余
console.log(10.5 % 3)  // 1.5

console.log(Number.MAX_SAFE_INTEGER === (2 ** 53 - 1))   // true

console.log(false == 0)   // true, 会自动转换数据类型
console.log(false === 0)  // false, 不转换数据类型,不一致时直接返回false

console.log(Number.NaN === Number.NaN)   // false
console.log(Number.POSITIVE_INFINITY === Number.POSITIVE_INFINITY) // true

console.log(1 / 3 === (1 - 2 / 3))  // false, 浮点数转换不精确

console.log(BigInt(2 ** 53))  // 9007199254740992n, 不能和Number一起运算

// 数组
console.log([1, 2, 3.14, 'Hello', null, true])

// null表示空值, undefined表示值未定义

// 对象: 属性名: 属性值 无序集合
const obj = {
    name: 'Tom',
    age: 18,
    gender: 'male',
    hobby: ['football', 'basketball'],
    address: {
        city: 'Beijing',
        street: 'Dongcheng'
    }
};
console.log(obj.name)  // Tom

// 动态语言,允许修改变量类型
let a = 1
a = 'Hello'
console.log(a)  // Hello

'use strict'   // 强制使用var声明变量,否则会报错,避免声明全局变量

console.log(`这是一个
多行
字符串`)

// 模板字符串
let name = 'Tom'
let age = 18
console.log(`My name is ${name}, I am ${age} years old.`)

// 数组
let arr = [1, 2, 3.14, 'Hello', null, true]
arr.length = 4    // 直接导致数组发生变化
console.log(arr) // [ 1, 2, 3.14, 'Hello' ]
arr.length = 6
console.log(arr) // [ 1, 2, 3.14, 'Hello', <2 empty items> ]
arr[6] = "x"
console.log(arr) // [ 1, 2, 3.14, 'Hello', <2 empty items>, 'x' ]
console.log(arr.slice(1, 3)) // [ 2, 3.14 ], 切片
console.log(arr.push(3))  // 返回长度8, 末尾添加
console.log(arr.pop())    // 3
// unshift()头部添加, shift()头部删除
// sort() 和 reverse()
arr.splice(0, 2, "I", "am")  // 删除、添加
console.log(arr)  // [ 'I', 'am', 3.14, 'Hello', <2 empty items>, 'x' ]
// concat() 和 join() 方法
// 多维数组

let xiaoming = {
    name: 'xiaoming',
    age: 18,
    gender: 'male',
    hobby: ['football', 'basketball'],
    address: {
        city: 'Beijing',
        street: 'Dongcheng'
    }
};

delete xiaoming.address
console.log('address' in xiaoming)  // false
xiaoming.address = 'Beijing'
console.log(xiaoming.hasOwnProperty('toString'))  // false
console.log(xiaoming.hasOwnProperty("address"))   // true

// 条件判断、循环, 和Java一致

// 字典
let map = new Map([["gender", "male"], ["hobby", "football"]])
map.set('name', 'xiaoming')
map.set('age', '18')
/**
 * Map(4) {
 *   'gender' => 'male',
 *   'hobby' => 'football',
 *   'name' => 'xiaoming',
 *   'age' => 18
 * }
 */
console.log(map)
for (let [key, value] of map) {
    console.log(key, value)
}

// 集合
let set = new Set([1, 2, 3, 3, '3'])
console.log(set) // Set(4) { 1, 2, 3, '3' }

// iterable
arr = [1, 2, 3]
for (let i in arr) {
    console.log(arr[i])
}
for (let x of arr) {
    console.log(x)
}
// element: 指向当前元素的值
// index: 指向当前索引
// array: 指向Array对象本身
// 可参见函数定义
arr.forEach((element, index, arr) => {
    console.log(element, index)
})

set = new Set(['A', 'B', 'C'])
set.forEach((element, sameElement, set) => {
    console.log(element, sameElement)
})
map = new Map([[1, 'x'], [2, 'y'], [3, 'z']])
map.forEach(function (value, key, map) {
    console.log(key, value)
})

函数

function abs(x) {
    if (arguments.length !== 1) {
        throw new Error("abs() takes exactly one argument")
    }
    if (typeof x !== "number") {
        throw new TypeError("abs() argument must be a number")
    }
    if (x >= 0) {
        return x
    } else {
        return -x
    }
}

console.log(abs(NaN))  // NaN
console.log(abs(10))

// console.log(abs('123'))  // throws

function add(x, y, ...rest) {
    // rest接收剩余参数,返回数组
}

// 局部作用域实际上是函数内部的变量,函数内部可以访问外部函数的变量,但外部函数不能访问函数内部的变量
// 全局作用域是全局变量,默认绑定到window
// const和let都具有块级作用域,const声明常量

// 解构赋值
let [x, [y, z]] = ['hello', ['JavaScript', 'ES6']]

let person = {
    name: '小明',
    age: 20,
    gender: 'male',
    passport: 'G-12345678',
    school: 'No.4 middle school',
    address: {
        city: 'Beijing',
        street: 'No.1 Road',
        zipcode: '100001'
    }
}

let {name, gender: sex} = person
console.log(sex)  // 赋值给sex
let {address: {city, street}, address} = person
console.log(city, street)   // 用address属性的值解构
console.log(address)
let {single = true} = person
console.log(single)  // 解构默认值

// 方法内部的this, 指向当前调用对象
function getAge() {
    return new Date().getFullYear() - this.birth
}

let xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
}

console.log(xiaoming.age())
console.log(getAge.apply(xiaoming, []))  // 参数打包成Array
console.log(getAge.call(xiaoming))   // 参数按顺序传入

/*
let count = 0
let oldParseInt = parseInt

window.parseInt = function () {
    count += 1
    return oldParseInt.apply(null, arguments)
}

parseInt('10')
parseInt('20')
parseInt('30')
console.log('count = ' + count)  // 3
 */

// map - reduce
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(arr.map(Math.pow).reduce((x, y) => x + y))

console.log(arr.filter(x => x % 2 === 0))  // [ 2, 4, 6, 8, 10 ]

// 闭包, 内部函数引用了外部函数值,返回内部函数
function make_pow(n) {
    return (x) => Math.pow(x, n)
}

console.log(make_pow(3)(3))

// zero(f)(x) = x
let zero = (f) => {
    return (x) => x
}

// one(f)(x) = f(x)
let one = (f) => {
    return (x) => {
        f(x)
    }
}

// add(n, m)(f)(x) = m(f)(n(f)(x))
// two(f)(x) = one(f)(one(f)(x)) = one(f)(f(x)) = f(f(x))
let _add = (n, m) => {
    return (f) => {
        return (x) => {
            return m(f)(n(f)(x))
        }
    }
}

_add(_add(one, one), one)(() => {
    console.log("print")
})()

// 箭头函数内部的this是词法作用域,由上下文确定, 总是绑定到外层调用obj

// 标签函数: 函数调用转化为带标签的模板字符串
const email = "test@example.com"
const password = 'hello123'

let sql = (strings, ...exps) => {
    console.log(`SQL: ${strings.join('?')}`)
    console.log(`SQL parameters: ${JSON.stringify(exps)}`)
    return {
        name: '小明',
        age: 20
    }
}

// 自动分割strings和exps
const result = sql`select *
                   from users
                   where email = '${email}'
                     and password = '${password}'`
console.log(JSON.stringify(result))

// 生成器函数
function* fib(max) {
    let [n1, n2] = [0, 1]
    while (n1 < max) {
        yield n1;
        [n1, n2] = [n2, n1 + n2]
    }
}

for (let i of fib(100)) {
    console.log(i)
}

正则、JSON

// 正则表达式
const reg = {
    // 验证手机号
    phone: /^1[3-9]\d{9}$/,
    // 验证邮箱
    email: /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
    // 验证密码
    password: /^[a-zA-Z0-9_-]{6,16}$/,
    // 验证姓名
    name: /^[\u4e00-\u9fa5]{2,4}$/
}

console.log(reg.email.test("teset@example.com"))

// 分组
console.log(/^(\d{3})-(\d{3,4}-\d{4})$/.exec("010-1234-5678"))

// 非贪婪匹配
console.log(/^(?:\d{3}-){2}\d{4}$/.exec("010-1234-5678"))

// 全局搜索,可以多匹配几次
console.log(/a/g.exec("abc"))

let xiaoming = {
    name: '小明',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
    // 精细化控制JSON输出,不能是箭头函数
    toJSON: function () {
        return {
            'name': this.name,
            'age': this.age
        }
    }
}

console.log(JSON.stringify(xiaoming, (key, value) => {
    if (typeof value == 'string') {
        return value.toUpperCase()
    }
    return value
}, ' '))

Class

// 基于原型创建对象
function Student(name) {
    this.name = name
}

Student.prototype.hello = function () {
    console.log("Hello: " + this.name)
}

new Student("Joe").hello()

class Student {
    constructor(name) {
        this.name = name
    }

    hello() {
        console.log("Hello: " + this.name)
    }
}

class PrimaryStudent extends Student {
    constructor(name, grade) {
        super(name)
        this.grade = grade
    }

    doHomework() {
        console.log("Doing homework before exam.")
    }
}

new PrimaryStudent("Job").doHomework()
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值