1, cookie的创建、读取和删除
在JS中,可以使用Document
对象的cookie
属性操作cookie
。 JS 可以读取、创建、修改和删除当前网页的cookie
创建 cookie
JS可以使用document.cookie
属性创建cookie
document.cookie = 'username = Jerry; expires = Mon, 26 Aug 2019 12:00:00 UTC; path=/'
// JS可以使用document.cookie属性创建cookie
// 还可以添加有效日期(UTC 时间)。默认情况下,在浏览器关闭时会删除 cookie:
// 通过 path 参数,可以告诉浏览器 cookie 属于什么路径。默认情况下,cookie 属于当前页
读取cookie
通过 JS,可以这样读取 cookie:
var x = document.cookie
document.cookie会在一条字符串中返回所有 cookie,比如:
cookie1=value; cookie2
改变 cookie
通过使用 JS,咱们可以像创建 cookie
一样改变它:
document.cookie = "username=Steve Jobs; expires=Sun, 31 Dec 2017 12:00:00 UTC; path=/";
这样旧 cookie
会被覆盖
删除 cookie
删除 cookie
非常简单,不必指定 cookie
值:直接把 expires
参数设置为过去的日期即可:
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/"
2, 解构赋值交换变量的值
之前的方法
let x = 1;
let y = 2;
let temp = x;
x = y;
y = temp;
console.log(x, y) // 2 1
现在的方法
let x = 1;
let y = 2;
let z = 3;
[x, y, z] = [z, y, x]
console.log(x, y, z) // 3 2 1
3,vuex的使用
vuex是什么
是一个专门为vue.js开发的状态管理模式 + 库
,采用集中式存储管理应用的所有组件的状态,以相应的规则保证状态以一种可预测的方式发生变化。
vuex 具体用法
1,安装
npm install vuex --save | yarn add vuex
在 main.js 引入
import store from './store'
new Vue({
el: '#App',
store,
...
})
2,添加文件
3,每个文件具体配置
- 1, modules里添加js文件,命名随意
示例:
假设里面创建了一个 form.js 和 user.js 两个文件
// form.js
const state = {
count: 0
}
const mutations = {
SET_STATE: (state, data) => {
state.count++
}
}
const actions = {}
export default {
state,
mutations,
actions
}
// user.js
const state = {
name: 'Jerry',
age: 18
}
const mutations = {
SET_NAME: (state, data) => {
state.name = data
},
SET_AGE: (state, data) => {
state.age = data
}
}
const actions = {}
export default {
state,
mutations,
actions
}
- 2, getter.js
所有使用的状态都需要在这里列出来
const getters = {
count: state => state.form.count,
name: state => state.user.name,
age: state => state.user.age
};
export default getters
- 3, index.js
modules中创建的文件在index.js中引入一下
import Vue from 'vue';
import Vuex from 'vuex';
import form from './modules/form'
import user from './modules/user'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
form,
user
},
getters
})
export default store
-
4,使用
使用方法很简单,只需要在具体的.vue文件中引入相应的状态即可
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['count', 'name', 'age'])
}
如果有遇到Object(...) is not a function,
查看报错所在位置在仓库的index.js,错误地点代码为:
const store = new Vuex.Store({
modules: {
form,
user
},
getters
})
vuex版本问题,我这里的vuex是4.0.2,版本过高, 将vuex版本降低为3.6.2即可解决。
如果改变状态也很简单,不需要额外引入,直接调用方法即可:
this.$store.commit('SET_STATE');
this.$store.commit('SET_NAME', '小王');
this.$store.commit('SET_AGE', 100);
mutations 和 actions 的区别:
mutations 用于变更 store 中的数据
actions用于处理异步任务,但是actions中还是要通过触发mutations的方式间接的变更数据
Actions 中不能直接需要state中的数据,必须通过 context.commit()触发某个 mutations 才行。
1, commit,例如:this.$store.commit('SET_STATE') // mutations中的方法
2,dispatch,例如:this.$store.dispatch('set_state'). // actions中的方法
两者区别:
Commit 提交执行 mutations 中的方法,mutations 是修改数据的,必须是同步的
dispatch 是提交执行 actions 中的方法,actions提交的是mutations,可以是异步操作,actions不可以修改store中的数据,需要commit mutations中的方法进行数据修改。
当我们的操作行为含有异步操作,比如向后台发送请求获取数据,就需要使用actions的dispatch完成了。
4,面向对象编程
Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class
(类)
在ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字定义类。class 的本质是 function。它可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法
1, 生成实例对象的原始模式
假定我们把猫看成一个对象,它有"名字"和"颜色"两个属性
let cat = {
name: '',
color: ''
}
现在,我们需要根据这个原型对象的规格,生成两个实例对象
let cat1 = {}
cat1.name = '咪咪'
cat1.color = '白色'
let cat2 = {}
cat2.name = '乐乐'
cat2.color = '黄色'
以上就是最简单的封装了,把两个属性封装在一个对象里面。但是,这样的写法有两个缺点:
- 1,如果多生成几个实例,写起来非常麻烦
- 2,实例与原型之间,没有办法看出他们之间的关系
2,原始模式的改进
我们可以写一个函数,解决代码重复的问题
function Cat(name, color) {
return {
name: name,
color: color
}
}
然后生成实例对象,就等于是在调用函数:
let cat1 = Cat('咪咪', '白色')
let cat2 = Cat('乐乐', '黄色')
这种方法的问题依然是,cat1
和cat2
之间没有内在的联系,不能反映出它们是同一个原型对象的实例
3,构造函数模式
为了解决从原型对象生成实例的问题,Javascript提供了一个构造函数(Constructor)模式
所谓"构造函数",其实就是一个普通函数,但是内部使用了this 变量,对构造函数使用new
运算符,就能生成实例,并且this
变量会绑定在实例对象上。
比如,猫的原型对象现在可以这样写:
function Cat (name, color) {
this.name = name;
this.color = color
}
我们现在就可以生成实例对象了:
let cat1 = new Cat('咪咪', '白色')
let cat2 = new Cat('乐乐', '黄色')
这时cat1
和cat2
会自动含有一个constructor
属性,指向它们的构造函数
cat1.constructor === Cat // true
cat2.constructor === Cat // true
Javascript还提供了一个instanceof
运算符,验证原型对象与实例对象之间的关系
cat1 instanceof Cat // true
cat2 instanceof Cat // true
cat2 instanceof Object // true
// instanceof 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上 - MDN
构造函数模式的问题
构造函数方法很好用,但是存在一个浪费内存的问题
我们现在为Cat
对象添加一个不变的属性type
(种类),再添加一个方法eat
(吃)。那么,原型对象Cat
就变成了下面这样:
function Cat(name, color) {
this.name = name;
this.color = color;
this.type = '宠物'
this.eat = function () {
console.log('猫罐头')
}
}
还是采用同样的方法,生成实例:
let cat1 = new Cat('咪咪', '白色')
let cat2 = new Cat('乐乐', '黄色')
console.log(cat1.type) // 宠物
console.log(cat2.eat()) // 猫罐头
表面上好像没什么问题,但是实际上这样做,有一个很大的弊端。那就是对于每一个实例对象,type
属性和eat()
方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存。这样既不环保,也缺乏效率。
cat1.eat === cat2.eat // false
能不能让type
属性和eat()
方法在内存中只生成一次,然后所有实例都指向那个内存地址呢?回答是可以的
4,prototype 模式
Javascript规定,每一个构造函数都有一个prototype
属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承
这意味着,我们可以把那些不变的属性和方法,直接定义在prototype
对象上
function Cat(name, color) {
this.name = name;
this.color = color;
}
Cat.prototype.type = '宠物'
Cat.prototype.eat = function () {
console.log('猫罐头')
}
然后,生成实例:
let cat1 = new Cat('咪咪', '白色')
let cat2 = new Cat('乐乐', '黄色')
console.log(cat1.type) // 宠物
console.log(cat1.eat()) // 猫罐头
这时所有实例的type
属性和eat()
方法,其实都是同一个内存地址,指向prototype
对象,因此就提高了运行效率
cat1.eat === cat2.eat // true
Prototype模式的验证方法
为了配合prototype
属性,Javascript定义了一些辅助方法,帮助我们使用它
1, isPrototypeOf()
这个方法用来判断,某个proptotype
对象和某个实例之间的关系
Cat.prototype.isPrototypeOf(cat1) // true
2, hasOwnProperty()
每个实例对象都有一个hasOwnProperty()
方法,用来判断某一个属性到底是本身属性,还是继承自prototype
对象的属性
cat1.hasOwnProperty("name") // true
cat1.hasOwnProperty("type") // false
3,in
in
运算符可以用来判断,某个实例是否含有某个属性,不管是不是本身属性
'name' in cat1 // true
'type' in cat1 // true
in
运算符还可以用来遍历某个对象的所有属性
for (let i in cat1) {
console.log("cat1["+i+"]="+cat1[i])
}
// cat1[name]=咪咪
// cat1[color]=白色
// cat1[type]=宠物
// cat1[eat]=function () {
console.log('猫罐头')
}