# 模板字符串

const date = new Date()
console.log(`现在是北京时间: ${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}`);
function getFullYear(){
  return date.getFullYear()
}
function getMonth(){
  return date.getMonth() + 1
}
function getDate(){
  return date.getDate()
}
console.log(`现在是北京时间: ${getFullYear()}${getMonth()}${getDate()}`);

# 标签模板字符串

function foo(name) {
  console.log(`my name is saber`);
}
const name = 'saber'
foo`` // 调用函数
function foo(name, age) {
  console.log('name', name, 'age', age); // name [ 'saber 16' ] age undefined
  console.log(`name: ${name} age: ${age}`); // name: saber 16 age: undefined
}
const name = 'saber'
const age = 16
foo`saber 16`  // 参数都被放到一个数组里面
function foo(name, age) {
  console.log('name', name, 'age', age); // name [ 'saber ', ' heixiuxiu~~ ' ] age 16
  console.log(`name: ${name} age: ${age}`); // name: saber , heixiuxiu~~  age: 16
}
const name = 'saber'
const age = 16
foo`saber ${age} heixiuxiu~~ `  // ${} 通过这种方式切断数组

# 函数默认参数

function foo(name = 'saber', age = 16) {
 console.log(`name: ${name} age: ${age}`); // name: saber age: 16
}
foo()

# 对象参数和默认值以及解构

function foo({name, age } = {name: 'saber', age: 16}) {
 console.log(`name: ${name} age: ${age}`); // name: saber age: 16
}
foo()

# 传对象其中之一参数并赋默认值和解构

function foo({name, age = 16} = {}) {
 console.log(`name: ${name} age: ${age}`); // name: saber age: 16
}
foo({name: 'saber'})

# 有默认值的形参最好放在最后

function sum(x, y, z = 30) {
  return x + y + z
}
console.log(sum(10, 20))

# 默认值的形参放在前面解决方法

function sum(z = 30, x, y) {
  return x + y + z
}
console.log(sum(undefined ,10, 20)) // 60 这种是可行的
console.log(sum(0 ,10, 20)) // 30 不可行
console.log(sum(null ,10, 20)) // 30 不可行

# 有默认值函数 length 属性 对默认值前面的参数属性 length 才有效

function sum(w, x, y = 30, z) {
  return w + x + y + z
}
console.log(sum.length) // 2

# 函数剩余参数

function sum(x, ...args) {
  console.log(x, args) // 1 [ 2, 3, 4 ]
  console.log(x, ...args) // 1 2 3 4
}
sum(1, 2, 3, 4)
  • ES6 中引用了 rest parameter,可以将不定数量的参数放入到一个数组中:
    • 如果最后一个参数是 ... 为前缀的,那么它会将剩余的参数放到该参数中,并且作为一个数组;

剩余参数和 arguments 有什么区别呢?

  • 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参;
  • arguments 对象不是一个真正的数组,而 rest 参数是一个真正的数组,可以进行数组的所有操作;
  • arguments 是早期的 ECMAScript 中为了方便去获取所有的参数提供的一个数据结构,而 rest 参数是 ES6 中提供并且希望以此来替代 arguments 的;
  • 剩余参数必须放到最后一个位置,否则会报错

# 箭头函数

  • 箭头函数是没有显式原型的,所以不能作为构造函数,使用 new 来创建对象;
const foo = () => {
  // console.log(arguments) // arguments is not defined
}
foo(1,2,3)
console.log(foo.prototype) // undefined

# 展开语法

const friends = ['薇尔莉特', '樱岛麻衣', '小鸟游六花']
const saber = 'saber'
const lain = {
  name: 'lain',
  friends: ['saber']
}
// 1. 函数调用
function foo(f1, f2, f3,) {
  console.log(f1, f2, f3);
}
foo.apply(null, friends) // 薇尔莉特 樱岛麻衣 小鸟游六花
foo(...friends) // 薇尔莉特 樱岛麻衣 小鸟游六花
console.log(...saber) // s a b e r
// 2. 构造数组
const newFriends = [saber, ...friends]
console.log(newFriends) // ['saber', ' 薇尔莉特 ', ' 樱岛麻衣 ', ' 小鸟游六花 ']
// 3. 构建对象时
const newLain = { ...lain, age: 16 }
console.log(newLain) // { name: 'lain', friends: [ 'saber' ], age: 16 }

# 展开语法 -> 浅拷贝

const lain = {
  name: 'lain',
  friends: ['saber']
}
const newLain = {
  ...lain,
  age: 16
}
newLain.friends.push('小鸟游六花')
console.log(lain) // {name: 'lain', friends: [ 'saber', ' 小鸟游六花 '] }

# 数值表示

const n1 = 100 // 十进制 
const n2 = 0b100 // 二进制 binary
const n3 = 0o100 // 八进制 octonary
const n4 = 0x100 // 十六进制 hexadecimal
console.log(n1, n2, n3, n4) // 100 4 64 256

# 连接符

const n5 = 10_000_000
console.log(n5) // 10000000
const n6 = 10_0.50
console.log(n6) // 100.5

# Symbol

  • ES2019 (ES10) 中,Symbol 还有一个描述符 (description)
const s1 = Symbol('s1')
const s2 = Symbol('s2')
console.log(s1 === s2) // false
console.log(s1.description) // s1
  • Symbol 值作为 key
// 1. 在定义对象字面量时使用
const lain = Symbol('lain')
const saber = Symbol('saber')
const characters = {
  [lain]: 'lain'
}
console.log(characters) // {Symbol(lain): 'lain'}
// 2. 新增属性
characters[saber] = 'saber'
console.log(characters) // {Symbol(lain): 'lain', Symbol(saber): 'saber'}
// 3.Object.defineProprtty 方式
const Neko = Symbol('Neko')
Object.defineProperty(characters, Neko, {
  enumerable: true,
  configurable: true,
  writable: true,
  value: 'Neko'
})
console.log(characters) // {Symbol(lain): 'lain', Symbol(saber): 'saber', Symbol(Neko): 'Neko'}
// 4. 获取 key
console.log(characters[lain], characters[saber], characters[Neko]) // lain saber Neko
// 5. 使用 Symbol 作为 key 的属性名,在遍历 / Object.keys 等中是获取不到这些 Symbol 值
console.log(Object.keys(characters)) // []
console.log(Object.getOwnPropertyNames(characters)) // []
// 6. 通过 Object.getOwnPropertySymbols 可以获取到 Symbol 值
const skeys = Object.getOwnPropertySymbols(characters)
console.log(skeys) // [Symbol(lain), Symbol(saber), Symbol(Neko)]
// 7. 遍历 Symbol 
for (const skey of skeys) {
  console.log(skey) // Symbol(lain)  Symbol(saber)  ymbol(Neko)
  console.log(characters[skey]) // lain saber Neko
}
// 8.Symbol 函数名
const foo = Symbol('foo')
characters[foo] = function () {
  console.log('foo')
}
characters[foo]() // foo
  • Symbol.for(key)
// 使传入的 Symbol 值一样  Symbol.for
const s1 = Symbol.for('Hello World')
const s2 = Symbol.for('Hello World')
console.log(s1 === s2) // true
// 获取 key  Symbol.keyFo
const key = Symbol.keyFor(s1)
console.log(key) // Hello World
// 将上面的 key 继续传入,这样也是一样的
const s3 = Symbol.for(key)
console.log(s3 === s1)
Update on Views times

Give me a cup of [coffee]~( ̄▽ ̄)~*

Nico Niconi WeChat Pay

WeChat Pay

Nico Niconi Alipay

Alipay