闭包:
-
hd被调用了,会开辟一个环境然后开始运行,但是运行完了之后,这个环境就会被清除掉,运算产生的数据也不会被保留,相当于你打游戏又重新开了一把。如果不加return的话,这个过程就相当于打游戏,调用函数这个相当于重新开游戏
function hd() {
let n =1;
function sum() {
console.log(++n);
};
sum();
}
hd();
function hd() {
let n =1;
return function sum() {
console.log(++n);
};
sum();
}
hd();
加个return之后,那么你的sum()被外部引用了之后,这个变量n的位置也会被保留,原来n=1,后来n以n=2的数据被保留,这就是return的作用。
ES6对象字面量增强写法:
1.创建新的对象的时候:
const obj = new Object()
2.{}这个花括号就叫做字面量
const obj = {}
const obj = {
name: 'why',
age: '18',
run: function () {
console.log('在奔跑')
}
}
3.属性的增强写法
const name = 'why',
const age = 18,
const height = 1.88
es5写法
const obj = {
name:name
age:age
height:height
}
es6写法
const obj = {
name
age
height
}
4.函数的增强写法
es5写法:
const obj = {
run: function () {},
eat: function () {}
}
es6写法:
const obj = {
run() {},
eat() {}
}
ES6之扩展运算符…(三个点)
对象中的扩展运算符(…)用于取出参数对象中的所有可遍历属性,拷贝到当前对象中
let bar = { a:1,b:2 }
let barz = { ...bar }
(这个时候barz = { a:1,b:2 })
如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性
let bar = { a:1,b:2 }
let barz = { ...bar,...{a:2,b:4} }
(这个时候barz = { a:2,b:4 })
这里有点需要注意的是扩展运算符对对象实例的拷贝属于一种浅拷贝。肯定有人要问什么是浅拷贝?我们知道javascript中有两种数据类型,分别是基础数据类型和引用数据类型。
基础数据类型是按值访问的,常见的基础数据类型有Number、String、Boolean、Null、Undefined,这类变量的拷贝的时候会完整的复制一份;
引用数据类型比如Array,在拷贝的时候拷贝的是对象的引用,当原对象发生变化的时候,拷贝对象也跟着变化
基础数据类型:
let obj1 = { a: 1, b: 2};
let obj2 = { ...obj1, b: '2-edited'};
console.log(obj1); // {a: 1, b: 2}
console.log(obj2); // {a: 1, b: "2-edited"}
引用数据类型:
let obj1 = { a: 1, b: 2, c: {nickName: 'd'}};
let obj2 = { ...obj1};
obj2.c.nickName = 'd-edited';
console.log(obj1); // {a: 1, b: 2, c: {nickName: 'd-edited'}}
console.log(obj2); // {a: 1, b: 2, c: {nickName: 'd-edited'}}
实例代码:
list是一个空的数组
res.data.data.results是请求回来的数组
如果this.list.push(res.data.data.results),这样写请求回来的数组就都成了list的元素:list=【[ ], [ ], [ ]】
this.list.push(...res.data.data.results)
扩展运算符针对数组的功能:
(1)可以直接展开数组
(2)链接数组
(3)应用于函数传参
let arr1 = [1,3,5,6]
let arr2 = [2,4,6,8]
// 展开数组
console.log(...arr1)
// 链接数组
let arr3 = [...arr1,...arr2]
console.log(arr3)
// 应用于函数传参
let arr4 = [1,2,56]
function sum(a,b) {
return a+b
}
console.log(sum(...arr4))
函数防抖和节流第三方包:
用法:防抖函数debounce将需要防抖的函数都给包起来
(1)安装
npm i lodash
如果安装报错的话,重新进行一次npm run serve就可以了
(2)引用
全部引进来
_这个是随便起的名字,叫abc或者cde都可以
这种方式会将lodash中的所有函数都会调进来
import _ from 'lodash'
// 有个防抖的函数
// debounce就是防抖函数,_.debounce就可以使用
// 这个的原理是你调用了一次函数之后,在时间间隔1秒内再调用的话通过不了
const fn = _.debounce(function () {
console.log('hello')
}, 1000)
fn()
部分引进来,只引进自己需要的
具体用法:
import { debounce } from 'lodash'
watch: {
searchText: {
// 当数据发生变化的时候就会触发handler,immediate表示会立即出发
handler: debounce(function () {
console.log('hello')
searchSuggestion({ q: this.searchText }).then(res => {
console.log(res)
this.suggestions = res.data.data.options
})
}, 1000),
immediate: true
}
}
高阶函数与函数科里化的代码演示:
函数科里化:通过函数调用继续返回函数的方式,实现多次接受参数
<script type="text/babel">
class Demo extends React.Component {
state = {
username:'',
password:''
}
saveFormData = (dataType) => {
return (event) => {
this.setState({[dataType]: event.target.value})
}
}
render () {
return (
<div>
<form>
<span>用户名:</span>
<input onChange={this.saveFormData('username')} type="text" label="123"/>
<span>密码:</span>
<input onChange={this.saveFormData('password')} type="password" label="123"/>
<button>登录</button>
<button>登录</button>
</form>
</div>
)
}
}
ReactDOM.render(<Demo />,document.getElementById('test'))
</script>
以下代码实现了函数的多次调用:
<script type="text/babel">
class Demo extends React.Component {
state = {
username:'',
password:''
}
saveFormData = (dataType,value) => {
this.setState({[dataType]:value})
}
render () {
return (
<div>
<form>
<span>用户名:</span>
<input onChange={(event)=>{this.saveFormData('username',event.target.value)}} type="text" label="123"/>
<span>密码:</span>
<button>登录</button>
<button>登录</button>
</form>
</div>
)
}
}
ReactDOM.render(<Demo />,document.getElementById('test'))
</script>
this的指向问题:
此时的this指向的是这个实例化对象
class person {
constructor (name, age) {
this.name = name
this.age = age
}
speak () {
console.log(this)
}
}
p2.speak()
此时的this指向的是全局window
speak () {
console.log(this)
}
speak()
此时的this指向的是undefined
因为创建类的时候,类的内部会开启局部严格模式,局部严格模式导致类中方法的this指向有规定,
而 const x = p1.speak x() 这样的写法相当于是直接调用,此时是带有局部严格模式的,所以指向是undefined
class person {
constructor (name, age) {
this.name = name
this.age = age
}
speak () {
console.log(this)
}
}
const x = p1.speak
x()
箭头函数的简写知识:
(1)
const a = () => 1
console.log(a())这个输出的1
const a = () => return 1
(2)以下代码想返回一个对象
但是如下的写法那个大括号相当于箭头函数的大括号,这样写是不可以的
const a = () => {data:1}
正确写法:写一个小括号将这个对象给包起来
const a = () => ({data:1})
正则表达式:
作用:用于匹配字符串中字符组合的模式,在JavaScript中,正则表达式也是对象
功能:
(1)验证表单
(2)过滤页面内容中的一些敏感词
(3)或者从字符串中提取我们想要的特定部分
测试正则表达式test
用于检测字符串是否符合该规则,该对象会返回true或者false,其参数是测试字符串
格式:regexObj.test(str)
regexObj----------是写的正则表达式,str----------使我们要测试的文本
boo输出的是true
var ag = /123/;
console.log(ag)
var boo = ag.test(123)
console.log(boo)
正则表达式中不需要加引号,写上abc,就是要验证这个字符串,千万不要加
var rg = /123/表示的是只要有1234返回的就是true,顺序不可以变,如果是1324返回的就是false
var rg = /123/
console.log(rg.test('123'))
console.log(rg.test('1234'))
正则表达式特殊字符
(1)边界符
----------表示以谁开始,如果中括号里面有,表示取反的意思
$----------表示以谁结束
[]----------表示有一系列字符串可以选择,只要匹配其中一个就可以了
//精确匹配,必须和123一模一样
var rg = /^123$/
console.log(rg.test('123'))
(2)量词符
*----------重复0次或者更多次
±--------重复1次或者更多次
?----------重复零次或者一次
{n}----------重复n次
{n,}----------重复n次或者更多次
{n-m}----------重复n次到m次