一、定义变量
(1)let
let声明的变量只在let命令所在的代码块内有效。
(2)const
const声明一个只读的常量,一旦声明,常量的值就不能改变
(3)let/const和var的区别
-
①预解析
var会进行预解析let和const不会,必须在定义后使用变量
console.log( n1 );//undefined var n1 = 666; console.log( n2 ) // 报错 let n2 = 888; console.log( n3 ) // 报错 const n3 = 888; -
②重复变量名
var可以定义重复变量名,重复定义没有意义let和const不能定义重复变量名
var n = 6; var n; console.log( n ) let n1 = 7; // let n1 = 8; // 报错 const n2 = 7; // const n2 = 8; // 报错 -
③块级作用域
var是没有块级作用域,只会被私有作用域限制使用范围(函数内)let和const是可以被块级作用域显示使用范围,任何一个可以书写代码的{}就是块级作用域,由let/const定义变量的{}称为暂时性死区
if(true){ var n = 200; // 在大括号中 let/const声明的变量,会被大括号限制使用范围 let user = 'zs'; const age = 20; if(true){ console.log( user ) //'zs' console.log( age ) // 20 } } console.log( n ) // 200 // console.log( user ) // 报错 user is not defined // console.log( age ) // 报错 age is not defined
(4)let和const的区别
-
①定义时的赋值
let定义变量时,可以不赋值const定义变量时,必须赋值
let n; const m; // 报错 没有赋值 -
②值修改
let定义的变量值可以修改const定义的变量不可修改
let n = 6; n = 8; console.log( n ) // 8 const m = 8; // m = 9; // 报错 console.log( m ) const obj = {name:'zs'}; // obj 中存储的是对象的地址 obj.name = 'lisi'; // 并没有修改o中存储的地址 console.log( o ) // {name: "lisi"}
二、箭头函数
-
ES6中定义函数的一种方式,只能用来定义匿名函数表达式(匿名函数)
var fn = function(){}、var obj = { f:function(){} }、setInterval(function(){},1000)、事件源.on事件类型 = function(){}等
-
语法:
()=>{},()书写形参的位置,=>箭头函数的标志,{}函数的函数体// 函数表达式 let fn = function(){console.log( '666' )} fn(); // 箭头函数 let ff = ()=>{console.log( '888' )} ff() -
特点:
-
①可以省略小括号不写
- 当函数只有一个形参时,可以不写;如果没有形参或两个以上形参则必须写小括号
let ff = n => {console.log( n )} ff(666) // 666 // 不能省略的情况 let f = (n,m)=>{console.log( n,m )} f(10,20) // 10 20 -
②可以省略大括号不写
- 当函数内代码只有一句话(一个表达式)时,可以省略,并且会自动返回这一句的结果,自动把这句代码的结果当做函数的返回值
let ff = n => console.log(n); ff(100) // 100 let fn = n => {return n+100}; // let fn = n=> n+100; let res = fn(100); console.log( res ) // 200 -
③箭头函数没有
argumentslet fn = function () { console.log( arguments ) } fn(10,20,30) let fn = ()=> { console.log( arguments ) } // 报错 arguments is not defined fn(10,20,30) -
④没有
this- 官方:箭头函数内的
this就是上下文的this - 私人:箭头函数内的
this就是定义箭头函数外部作用域的this - 箭头函数内的
this和调用箭头函数的方式没有关系,和调用箭头函数的位置有关系
document.onclick = function () { console.log( this ) // this就是事件源 } console.log(this); // window document.onclick = () => { // 箭头函数定义在全局作用域中 // 则箭头函数内 的this指向全局作用域中的this window console.log(this) // window } document.onclick = function () { console.log(this) // this就是事件源 document let obj = { fn: function () { console.log(this) }, ff: () => { // 箭头函数定义在事件处理函数中 // this指向事件处理函数中的this 事件源 document console.log(this) } } obj.fn() // this指向调用fn方法的对象 obj.ff() // this指向事件处理函数中的this 事件源 document } - 官方:箭头函数内的
-
三、函数形参默认值
- 在函数定义的小括号中,直接给形参赋值,这个值就是函数内形参使用的默认值
- 注意: 箭头函数中如果形参使用了默认值,则不能省略小括号
let ff = function (n1=10,n2=20) {
console.log( n1,n2 )
}
// ff();// 形参使用默认值 n1为10 n为20
// ff(66);// 形参n1使用实参传递的66 形参n2使用默认值 n1为66 n2为20
ff(66,88);// 形参n1使用实参传递的66 形参n2使用实参传递的88 n1为66 n2为88
四、模板字符串
- 使用反括号包裹
`` - ①在模板字符串中可以换行书写
- ②在模板字符串中可以解析变量,
${变量},在${}中可以执行一些简单的代码
let str =
`<ul>
<li>${username}</li>
<li>${age+1}</li>
<li>${gender}</li>
</ul>
`;
console.log(str)
document.body.innerHTML = str;
五、对象简写
- ①如果对象的属性名和属性值的变量名一样,可以简写,将
属性名、冒号省略 - ②如果对象中属性对应的值只有一个匿名函数,可以简写,将
冒号、function省略
let username = '张三'
let userage = 18;
// 对象
let obj = {
// username: username,
username,
userage,
// fn:function(){console.log( 666 )},
fn(){console.log( 666 )}
}
console.log( obj )
obj.fn()
六、解构赋值
- 作用:快速的获取数据结构中的某一个值
(1)解构数组
- 语法:
解构 = 数组 - 数组解构使用
[],[]在赋值等号的左边叫解构,[]在赋值等号的右边叫数组
// let n1;
// let n2;
// let n3;
// let n4;
[n1, n2, n3, n4, n5] = ['a', 'b', 'c', 'd'];
console.log(n1, n2, n3, n4) // a b c d
console.log( n5 )// undefined
(2)解构对象
- 语法:
解构 = 对象 - 解构对象使用
{},{}在赋值等号的左边叫解构,{}在赋值等号的右边叫数组 - 在左边的
{}中 你需要书写解构的key(属性名)
let obj = { username: 'liam', age: 18 };
let { username, age } = obj// 等价于 let username = obj.username, age = obj.age
console.log(username, age) // liam 18
let { age:userage} = obj // 等价于 let userage = obj.age
console.log( userage ) // 18
let o = {
name: 'zs',
age: 20,
info: {
height: 180,
weight: 180,
addr: {
city: '北京'
}
}
}
let { name: username, age, info: { height, weight, addr: { city } } } = o;
console.log(username, age, height, weight, city); // zs 20 180 180 北京
七、运算符
(1)展开运算符...
- 可以展开数组和对象,展开的对象需要放在
{},展开的数组需要放在[]或方法函数实参位置
let arr = [1,2,3,4,5,'a','b','c'];
console.log(...arr ) // 1 2 3 4 5 "a" "b" "c"
(2)合并运算符...
...既可以展开数组,也可以合并多个数据,得到数组- 当
...用于函数形参位置时,就是一个合并运算符,可以把多个实参合并起来得到一个数组
// 合并数组使用
let arr1 = [1, 2, 3, 4];
let arr2 = [5, 6, 7, 8];
var newArr = [...arr1,...arr2]
console.log( newArr )// [1, 2, 3, 4, 5, 6, 7, 8]
// 合并对象使用
let o = { name: 'liam', age: 18 };
let obj = {
gender:'男',
...o
}
console.log( obj ) // name:'liam',age:18,gender:'男'
let fn = function (...arr) {
console.log( arr ) // [1, 2, 3, 4, 5, 6]
}
fn(1, 2, 3, 4, 5, 6);
// 合并运算符,可以适当的弥补箭头函数内没有argumenst的缺陷
let ff1 = (...ars) => {
console.log( ars ) // [1, 2, 32, 34, 4]
}
ff1(1, 2, 32, 34, 4)
let ff2 = (n1, n2, n3, ...ars) => {
console.log( n1,n2,n3 ) // 1 2 3
console.log(ars) // [4, 5, 6, 7]
}
ff2(1, 2, 3, 4, 5, 6, 7)
八、模块化开发
九、万能检测数据类型
- 语法:
Object.prototype.toString.call(你要检测的数据) - 返回值:
[object 数据类型]
console.log(Object.prototype.toString.call(1)) // [object N]
十、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.parse、JSON.stringify json.stringify是将 js 的对象或者数组转换成为 json 格式的字符串
(1)JSON.parse
-
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)obj就是我们 js 的对象arr就是我们 js 的数组
(2)JSON.stringify
-
JSON.stringify是将对象或者数组转换为 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) console.log(jsonObj) console.log(jsonArr)jsonObj就是 json 格式的对象字符串jsonArr就是 json 格式的数组字符串
十一、this 关键字
-
每一个函数内部都有一个关键字是
this -
可以让我们直接使用的
-
重点: 函数内部的 this 只和函数的调用方式有关系,和函数的定义方式没有关系
-
函数内部的 this 指向谁,取决于函数的调用方式
-
全局定义的函数直接调用,
this => windowfunction fn() { console.log(this) } fn() // 此时 this 指向 window -
对象内部的方法调用,
this => 调用者var obj = { fn: function () { console.log(this) } } obj.fn() // 此时 this 指向 obj -
定时器的处理函数,
this => windowsetTimeout(function () { console.log(this) }, 0) // 此时定时器处理函数里面的 this 指向 window -
事件处理函数,
this => 事件源div.onclick = function () { console.log(this) } // 当你点击 div 的时候,this 指向 div -
自调用函数,
this => window(function () { console.log(this) })() // 此时 this 指向 window
-
强行改变 this 指向的三个方法
- 刚才我们说过的都是函数的基本调用方式里面的 this 指向
- 我们还有三个可以忽略函数本身的 this 指向转而指向别的地方
- 这三个方法就是 call / apply / bind
- 是强行改变 this 指向的方法
call
-
call方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向 -
语法:
函数名.call(要改变的 this 指向,要给函数传递的参数1,要给函数传递的参数2, ...)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
-
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.call(obj, [1, 2])-
fn()的时候,函数内部的 this 指向 window -
fn.apply(obj, [1, 2])的时候,函数内部的 this 就指向了 obj 这个对象 -
使用 apply 方法的时候
- 会立即执行函数
- 第一个参数是你要改变的函数内部的 this 指向
- 第二个参数是一个 数组,数组里面的每一项依次是向函数传递的参数
-
bind
-
bind方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向 -
和 call / apply 有一些不一样,就是不会立即执行函数,而是返回一个已经改变了 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 指向 windownewFn(1, 2)的时候执行的是一个和 fn 一摸一样的函数,只不过里面的 this 指向改成了 obj