函数与对象的语法糖🍬

384 阅读5分钟

1.函数默认参数

ES5

    function sum(a, b) {
        return a + b
    }
    sum(1)

那么会产生什么结果呢?

1.png
b为 undefined, return 的结果为 NaN
那如何处理呢?

    function sum(a, b) {
        a =  (a || 0)
        b = (b || 0//前者为真则其值,若为假则取后者 
        return a + b
    }
    sum(1)

ES6

    function sum(a=0, b=0) { // 如果 a/b 传的是 undefined 那么值默认为 0
        return a + b
    }
    sum(1)

与python的区别

在JS中,默认参数的数组每次都会有新的 2.png
在python中,它的默认参数的数组是共用的

>>> def fn(item, array=[])
...     array.append(item)
...     return array
...
>>> fn(1) // [1]
>>> fn(2) // [1, 2]

2.剩余参数

什么叫剩余参数

以下代码是已知参数的
function sum(a, b, c, d, e, f){ //
    return a+b+c+d+e+f
}
sum(1,2,3,4,5,6)

如果我不知道传的参数有多少个呢?

探索...

3.png

4.png

...numbers (这个就叫做剩余参数)
语法: ... + 变量
这个 变量 它是 数组 \

伪数组变真数组的三种方法

function sum(message){
  // 伪数组变真数组
  let args = Array.prototype.slice.call(arguments) // 方法1 ES5
  let args = Array.from(arguments) // 方法2 ES6
  let args = [...arguments] // 方法3 
  let numbers = arguments.slice(1)
  result = numbers.reduce((p, v) => p+v, 0)
  return message + result
}
sum('结果是:', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

5.png

那么就可写成以下写法

function sum(message,...numbers){
  result = numbers.reduce((p, v) => p+v, 0)
  return message + result
}
sum('结果是:', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

3.展开操作

let array1 = [1,2,3,4,5,6]
//要求 array2 是 array1 的后三项
let [1,2,3,...array2] = array1

6.png\

旧的方法添加数组

8.png

ES6的方法

7.png

4.解构赋值

研究的问题: 交换 a 和 b 的关系

a = 1
b = 2

请问如何把 a b 的值交换过来???

语法一(旧的方法)

9.png

语法二(新的方法)

[a, b] = [b, a]

语法三

var [a, b, ...rest] = [10, 20, 30, 40, 50]

语法四

var hhh = {name: 'hhh', age: 18, gender: 'Male'}
// ES5的写法
var name = hhh.naem
var age = hhh.age
var grnder = hhh.gender
// ES6的语法糖
var {name, age, gender} = hhh // 解构赋值,从hhh里取 name age gender,然后这三个东西分别声明一个变量

语法五

var [a=5, b=7] = [1]

上面的代码是如何演变的呢?

var [a, b] = [1, 2]
// 如果没有 2 呢?
var [a, b] = [1]
// b 是不是就 undefined
// 那如何给 b 一个默认值?
var [a, b=7] = [1] // 如果没有 b,那么 b=7.7为默认值
var [a=5, b=7] = [1] // 5 7 分别为 a b 的默认值,这个的结果为 [a=1, b=7]

语法六

var f = function(){
    return [1, 2, 3]
}
var [a, , b] = f()  // a=1 b=3


var hhh = {
    name1: 'Pink', age: 18, gender: 'Male'
}
var {name1:xm} = hhh // 我取的是 name1 ,但是我把 name1 重命名成 xm
console.log(xm) // Pink


var hhh = {
    name1: 'Pink', age: 18, gender: 'Male', girlfriend: {
        name2: 'YouYou', age: 18, gender: 'Female'
    }
}
// 下面的 hhh 是被解构的对象
var {child: {name2: xm='Nana'}} = hhh // name2重明名为姓名,Nana为默认值,如果没有姓名就取它
console.log(xm) // YouYou

对象浅拷贝

var objA = {name: 'a'}
// 如何拷贝呢?
var objB = Object.assign({}, objA) // 将 objA 的属性一个一个的浅拷贝过来


var objA = {
    name: {
        x: 'a'
    } 
}
var objB = Object.assign({}, objA) 
objB.name.x = 'b'
console.log(objA.name.x) // b 这就是浅拷贝,大家共用对象 

简单的方法进行浅拷贝

var objA = {
    name: {
        x: 'a'
    } 
}
var objB = [...objA] // 把objA的所有属性拷贝过来

对象合并

let objA = {
    p1: 1,
    p2: 2
}
let objC = {
    p1: 1111.
    p3: 3
}
let objB = Object.assign({}, objA, objC) // 旧的写法
let objB = {...objA, ...objC} // 新的写法
console.log(objB) // {p1: 1111, p2: 2, p3: 3}

能用 ... 就用,不能用的话就用 assign ,最后实在不行就 遍历
更多的例子: MDN

function drawES2015Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {})
{
  console.log(size, cords, radius);
  // do some chart drawing
}

function drawES2015Chart(a = {}){} // 把取的第一个参数命名为 a ,如果 a 不存在我就给一个空对象

function drawES2015Chart({size, cords, radius} = {}){} // 解构一下

function drawES2015Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {}{} // 解构赋值

function drawES2015Chart(options = {})
{
  let {size = 'big', cords = { x: 0, y: 0 }, radius = 25} = options
  console.log(size, cords, radius);
}

简单说说深拷贝

深拷贝:JSON.parse(JSOn.stringify(data))
如果这个对象满足以下条件就是深拷贝:

  1. 这个对象没有复杂的对象,没有日期对象、正则对象、没有函数、没有循环引用、没有所有普通对象之外的对象
  2. 这个对象它没有 undefined,因为JSON 不支持 undefined 能适用对象的深拷贝? 递归

5.属性加强

var x = 1
var y = 2
var obj = {
    "x" = x,
    "y" = y
}

var obj = {x, y}
var obj = {x:1, y:2}
var {x, y} = obj


var [x, y] = [1, 2]
var obj2 = {
    sayHi: function(name){},
    sayBye: function(name){}
}

var obj2 = {
    sayHi(name){},
    sayBye(name){}
}
var x = 1
var y = 2
var obj1 = {naem:1, age:2}
var obj2 = {
    x,
    y,
    z: 1,
    ...obj1,
    sayHi(name='hhh'){},
    sayBye(name='hhh'){},
    sayByeBye: function(){}
}
var key = 'x'
var value = 'y'

var obj = {}
obj[key] = value
// 最后结果  {"x": "y"} 

//ES6
var obj = {
    [key]: value
}

字符串

多行字符串 / 字符串里插变量

双引号和单引号一模一样,没有区别

var string = "hdfjakfhoq"
var string = 'fdaskldkqfhoq'
var text = 'hellow'

// 报错,ES5的字符串不支持换行
var string = "<div>
                <p>jasdjweka: __text__</p>
              </div>".replace('__text__', text)

// 如何解决? 用转译
var string = "<div>\
                <p>jasdjweka</p>\
              </div>" // 结果里面没有回车
var string = "<div>\  // 这里按space
                <p>jasdjweka</p>\ // 这里按space
              </div>" // 报错
// 以上写法最大的问题是如果你后面有空格,人眼是无法看出来的,它的语法是错误的,就可能找不到错误

var string = "<div>“ +
                ”<p>jasdjwe" + text + "ka</p>“ +
              ”</div>" // 这样是可以的
              
// ES6的语法糖
var string = `
   <div>
       <p>jasdjweka${ text        }</p> 
   </div>    
` // 反引号里面可以随便写,但是结果里包含4个 回车

函数接字符串

var name = 'hhh'
var res = 'key'

var string = `${name},你来帮我拿${res}`


var fn = function(){
   let strings = arguments[0]
   let var1 = arguments[1]
   let var2 = arguments[2]
   if(var1 === 'hhh'){
       return var1 + strings[1] + '水'
   }else{
       return var1 + strings[1] + '纸巾'
   }
}
fn`${name},你来帮我拿${res}`

10.png

11.png