JSON 字符串
- json 是一种特殊的字符串格式, 本质上还是一个字符串
var jsonObj = '{ "name": "Jack", "age": 18, "gender": "男" }'
var jsonArr = '[{ "name": "Jack", "age": 18, "gender": "男" }, { "name": "Jack", "age": 18, "gender": "男" }, { "name": "Jack", "age": 18, "gender": "男" }]'
- 对象内部的
key 和 value 都用双引号包裹的字符串(必须是双引号)
JSON 的两个方法
JSON.parse 将 json 格式的字符串转换为 js 的对象或者数组
var jsonObj = '{ "name": "Jack", "age": 18, "gender": "男" }'
var jsonArr = '[{ "name": "Jack", "age": 18, "gender": "男" }, { "name": "Jack", "age": 18, "gender": "男" }, { "name": "Jack", "age": 18, "gender": "男" }]'
var obj = JSON.parse(jsonObj)
var arr = JSON.parse(jsonArr)
console.log(obj)
console.log(arr)
JSON.stringify 是将 js 的对象或者数组 转换为 json 格式的字符串
var obj = {
name: 'Jack',
age: 18,
gender: '男'
}
var arr = [
{
name: 'Jack',
age: 18,
gender: '男'
},
{
name: 'Jack',
age: 18,
gender: '男'
},
{
name: 'Jack',
age: 18,
gender: '男'
}
]
var jsonObj = JSON.stringify(obj)
var jsonArr = JSON.stringify(arr)
this 关键字
- 每一个函数内部都有一个关键字是
this
- 重点: 函数内部的 this 之和函数的调用有关, 和函数的定义方式没有关系
- 函数内部的 this 指向谁, 取决于函数的调用方式
- 全局定义的函数直接调用:
this == window
function fn(){
console.log(this)
}
fn()
var obj = {
fn: function () {
console.log(this)
}
}
obj.fn()
setTimeout(function () {
console.log(this)
}, 0)
div.onclick = function () {
console.log(this)
}
(function(){
console.log(this)
})()
call; apply; bind
- 刚才说过的都是函数的基本调用方式里面的 this 指向
- 我们还有三个可以忽略函数本身 this 指向 转而指向别的地方
- 这三个方法就是 call / apply / bind
- 这三个方法是强行改变 this 指向的方法
call
- 该方法是附加在函数调用后面使用, 可以忽略函数本身的 this 指向
- 语法:
函数名.call(要改变的 this 指向, 要给函数传递的参数1, 要给函数传递的参数1, ...)
var obj = {name: 'Jack'}
function fn(a, b) {
console.log(this)
console.log(a)
console.log(b)
}
fn(1, 2)
fn.call(obj, 1, 2)
fn() 的时候, 函数内部的 this 指向 window
fn.call(obj, 1, 2) 的时候, 函数内部的 this 就指向了 obj 这个对象
- 使用 call 方法的时候
- 会立即执行函数
- 第一个参数是我们要改变函数内部的 this 指向
- 第二个参数开始, 依次是向函数传递的参数
apply
- 该方法是附加在函数调用后面使用, 可以忽略函数本身的 this 指向
- 语法:
函数名.apply(要改变的 this 指向, [要给函数传递的参数1, 要给函数传递的参数2, ...])
var obj = {name: 'Jack'}
function fn(a, b) {
console.log(this)
console.log(a)
console.log(b)
}
fn(1, 2)
fn.apply(obj, [1, 2])
fn() 的时候, 函数内部的 this 指向 window
fn.apply(obj, [1, 2]) 的时候, 函数内部的 this 就指向了 obj 这个对象
- 使用 apply 方法的时候
- 会立即执行函数
- 第一个参数是我们改变的函数内部的 this 指向
- 第二个参数是一个 数组, 数组里面的每一项依次是向函数传递的参数
bind
- 该方法是附加在函数调用后面使用, 可以忽略函数本身的 this 指向
- 和 call / apply 有一些不一样, 就是 bind 不会立即执行函数, 而是返回一个已经改变了 this 指向的函数
- 语法:
var newFn = 函数名.bind(要改变的 this 指向); newFn(传递参数)
var obj = {name: 'Jack'}
function fn(a, b) {
console.log(this)
console.log(a)
console.log(b)
}
fn(1, 2)
var newFn = fn.bind(obj)
newFn(1, 2)
- bind 调用的时候, 不会执行 fn 这个函数, 而是返回一个新的函数
- 这个新的函数就是一个改变了 this 指向以后的 fn 函数
fn(1, 2) 的时候 this 指向了 window
newFn(1, 2) 的时候执行的是一个和 fn 一模一样的函数, 只不过里面的 this 指向改成了 obj
ES6 新增内容
let 和 const 关键字
- 我们以前声明变量一直使用的是
var 关键字来声明变量的
- 在 ES6 的时候, 多了两个关键字
let 与 const, 也是用来声明变量的
- 语法:
let 变量名
- 和 var 有一些区别
let 和 const 不允许重复声明变量
var num = 100
var num = 200
let num = 100
let num = 200
const num = 100
const num = 200
let 和 const 声明的变量不会再预解析的时候解析(也就是没有变量提升)
console.log(num)
var num = 100
console.log(num)
let num = 100
console.log(num)
const num = 100
let 和 const 声明的变量会被所有代码块{} 限制作用范围
if (true) {
var num = 100
console.log(num)
}
console.log(num)
if (true) {
let num = 100
console.log(num)
}
console.log(num)
if (true) {
const num = 100
console.log(num)
}
console.log(num)
- let 和 const 的区别
- let 声明的变量的值可以改变, const 声明的变量值不可以改变
let num = 100
num = 200
console.log(num)
const num = 100
num = 200
- let 声明的时候可以不赋值, const 声明的时候必须赋值
let num
num = 100
console.log(num)
const num
箭头函数
- 箭头函数是 ES6 里面一个简写函数的语法方式
- 重点: 箭头函数只能简写函数表达式, 不能简写声明式函数
function fn() {}
const fun = function () {}
const obj = {
fn: function () {}
}
- 语法:
(函数的形参) => {函数体内要执行的代码}
const fn = function (a, b) {
console.log(a)
console.log(b)
}
const fn1 = (a, b) => {
console.log(a)
console.log(b)
}
const obj = {
fn: function (a, b) {
console.log(a)
console.log(b)
}
}
const obj1 = {
fn: (a, b) => {
console.log(a)
console.log(b)
}
}
箭头函数的特殊性
- 箭头函数内部没有 this, 箭头函数的 this 是上下文的 this
- 箭头函数内部没有
arguments 这个参数集合
- 函数的形参只有一个的时候可以不写
() 其余情况必须写
- 函数体只有一行代码的时候, 可以不写
{}, 并且会自动 return
函数传参的默认值
- 我们在定义函数的时候, 有的时候需要一个默认值出现
- 就是当我不传递参数的时候, 使用默认值, 传递参数了就使用传递参数的参数
function fn(a) {
a = a || 10
console.log(a)
}
fn()
fn(20)
- 在 ES6 中我们可以直接把默认值写在函数的形参位置
function fn(a = 10) {
console.log(a)
}
fn()
fn(20)
const fn = (a = 10) => {
console.log(a)
}
fn()
fn(20)
- 注意! 箭头函数如果你需要使用默认值的话, 那么一个参数的时候也需要写()
解构赋值
解构对象
const obj = {
name: 'Jack',
age: 18,
gender: '男'
}
let name = obj.name
let age = obj.age
let gender = obj.gender
const obj = {
name: 'Jack',
age: 18,
gender: '男'
}
let { name, age, gender } = obj
解构数组
const arr = ['Jack', 'Rose', 'Tom']
let a = arr[0]
let b = arr[1]
let c = arr[2]
const arr = ['Jack', 'Rose', 'Tom']
let [a, b, c] = arr
模板字符串
- ES5 中我们表示字符串的时候使用
'' 或者 ""
- 在 ES6 中, 我们还有一个东西可以表示字符串 `` (反引号)
let str = `hello world`
console.log(typeof(str))
- 反引号与之前的区别
- 反引号可以换行书写
let str = 'hello world'
let str = `
hello
world
`
- 反引号可以直接在字符串里拼接变量, 不过需要借助
${}
let num = 100
let str = 'hello' + num + 'world' + num
console.log(str)
let str2 = 'hellonumworldnum'
console.log(str2)
let num = 100
let str = `hello${num}world${num}`
console.log(str)